base64 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/base64.rb +313 -60
  3. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cdb7f1229721d778c55acf3ba0d52d0cfd01af75b642879cad18c897324f2d3
4
- data.tar.gz: f14d863cab6d699c6ed29f7c463da7b6fe0566410dbc21bdfc5c6880b0cd5056
3
+ metadata.gz: 67c1752cf74c25682849d866ca527d3a001d52712144ec2d1b10df96389202f0
4
+ data.tar.gz: 54196151956485052bcb6d58226490f4b30efa44fe75ace5d6e713b7a2154773
5
5
  SHA512:
6
- metadata.gz: 2b38e41b62859eeb7d5ec7a2111c323e5dca272889f3a8d611fec3c8cc9cc2bfc932f243544d1f3edd745930cac9a340de0d7deb03c2e6f85b12b9a5be77f2f7
7
- data.tar.gz: 7ebc528a0e7256f18f5efb8d5e69cc1599c640d1393124d08c33ad643ba45764f003830c9820282b2487f162f2db9681f811142e45bd3f9537e437f3becb9ef1
6
+ metadata.gz: 66de0c5435992cc15ba818a9d92e914edd777f09c535af68410fffe1a6485556ad85ec822e62b4b469e2614202b7f5aa7621f419a7ce9740ccb7c1c7da2ff70e
7
+ data.tar.gz: b9ed3e456b9545f9e2aa8fba015730e9abe6345cfbebd013807314de9516df9e92896d31d081363f5b805f510617c8405785df7ddf8221d146b844c1208b6b3e
data/lib/base64.rb CHANGED
@@ -1,85 +1,330 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
- # = base64.rb: methods for base64-encoding and -decoding strings
3
+ # \Module \Base64 provides methods for:
4
4
  #
5
-
6
- # The Base64 module provides for the encoding (#encode64, #strict_encode64,
7
- # #urlsafe_encode64) and decoding (#decode64, #strict_decode64,
8
- # #urlsafe_decode64) of binary data using a Base64 representation.
5
+ # - Encoding a binary string (containing non-ASCII characters)
6
+ # as a string of printable ASCII characters.
7
+ # - Decoding such an encoded string.
9
8
  #
10
- # == Example
9
+ # \Base64 is commonly used in contexts where binary data
10
+ # is not allowed or supported:
11
11
  #
12
- # A simple encoding and decoding.
12
+ # - Images in HTML or CSS files, or in URLs.
13
+ # - Email attachments.
13
14
  #
14
- # require "base64"
15
+ # A \Base64-encoded string is about one-third larger that its source.
16
+ # See the {Wikipedia article}[https://en.wikipedia.org/wiki/Base64]
17
+ # for more information.
15
18
  #
16
- # enc = Base64.encode64('Send reinforcements')
17
- # # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
18
- # plain = Base64.decode64(enc)
19
- # # -> "Send reinforcements"
19
+ # This module provides three pairs of encode/decode methods.
20
+ # Your choices among these methods should depend on:
21
+ #
22
+ # - Which character set is to be used for encoding and decoding.
23
+ # - Whether "padding" is to be used.
24
+ # - Whether encoded strings are to contain newlines.
25
+ #
26
+ # Note: Examples on this page assume that the including program has executed:
27
+ #
28
+ # require 'base64'
29
+ #
30
+ # == Encoding Character Sets
31
+ #
32
+ # A \Base64-encoded string consists only of characters from a 64-character set:
33
+ #
34
+ # - <tt>('A'..'Z')</tt>.
35
+ # - <tt>('a'..'z')</tt>.
36
+ # - <tt>('0'..'9')</tt>.
37
+ # - <tt>=</tt>, the 'padding' character.
38
+ # - Either:
39
+ # - <tt>%w[+ /]</tt>:
40
+ # {RFC-2045-compliant}[https://datatracker.ietf.org/doc/html/rfc2045];
41
+ # _not_ safe for URLs.
42
+ # - <tt>%w[- _]</tt>:
43
+ # {RFC-4648-compliant}[https://datatracker.ietf.org/doc/html/rfc4648];
44
+ # safe for URLs.
45
+ #
46
+ # If you are working with \Base64-encoded strings that will come from
47
+ # or be put into URLs, you should choose this encoder-decoder pair
48
+ # of RFC-4648-compliant methods:
49
+ #
50
+ # - Base64.urlsafe_encode64 and Base64.urlsafe_decode64.
51
+ #
52
+ # Otherwise, you may choose any of the pairs in this module,
53
+ # including the pair above, or the RFC-2045-compliant pairs:
54
+ #
55
+ # - Base64.encode64 and Base64.decode64.
56
+ # - Base64.strict_encode64 and Base64.strict_decode64.
57
+ #
58
+ # == Padding
59
+ #
60
+ # \Base64-encoding changes a triplet of input bytes
61
+ # into a quartet of output characters.
62
+ #
63
+ # <b>Padding in Encode Methods</b>
64
+ #
65
+ # Padding -- extending an encoded string with zero, one, or two trailing
66
+ # <tt>=</tt> characters -- is performed by methods Base64.encode64,
67
+ # Base64.strict_encode64, and, by default, Base64.urlsafe_encode64:
68
+ #
69
+ # Base64.encode64('s') # => "cw==\n"
70
+ # Base64.strict_encode64('s') # => "cw=="
71
+ # Base64.urlsafe_encode64('s') # => "cw=="
72
+ # Base64.urlsafe_encode64('s', padding: false) # => "cw"
73
+ #
74
+ # When padding is performed, the encoded string is always of length <em>4n</em>,
75
+ # where +n+ is a non-negative integer:
76
+ #
77
+ # - Input bytes of length <em>3n</em> generate unpadded output characters
78
+ # of length <em>4n</em>:
79
+ #
80
+ # # n = 1: 3 bytes => 4 characters.
81
+ # Base64.strict_encode64('123') # => "MDEy"
82
+ # # n = 2: 6 bytes => 8 characters.
83
+ # Base64.strict_encode64('123456') # => "MDEyMzQ1"
84
+ #
85
+ # - Input bytes of length <em>3n+1</em> generate padded output characters
86
+ # of length <em>4(n+1)</em>, with two padding characters at the end:
87
+ #
88
+ # # n = 1: 4 bytes => 8 characters.
89
+ # Base64.strict_encode64('1234') # => "MDEyMw=="
90
+ # # n = 2: 7 bytes => 12 characters.
91
+ # Base64.strict_encode64('1234567') # => "MDEyMzQ1Ng=="
92
+ #
93
+ # - Input bytes of length <em>3n+2</em> generate padded output characters
94
+ # of length <em>4(n+1)</em>, with one padding character at the end:
95
+ #
96
+ # # n = 1: 5 bytes => 8 characters.
97
+ # Base64.strict_encode64('12345') # => "MDEyMzQ="
98
+ # # n = 2: 8 bytes => 12 characters.
99
+ # Base64.strict_encode64('12345678') # => "MDEyMzQ1Njc="
100
+ #
101
+ # When padding is suppressed, for a positive integer <em>n</em>:
102
+ #
103
+ # - Input bytes of length <em>3n</em> generate unpadded output characters
104
+ # of length <em>4n</em>:
105
+ #
106
+ # # n = 1: 3 bytes => 4 characters.
107
+ # Base64.urlsafe_encode64('123', padding: false) # => "MDEy"
108
+ # # n = 2: 6 bytes => 8 characters.
109
+ # Base64.urlsafe_encode64('123456', padding: false) # => "MDEyMzQ1"
110
+ #
111
+ # - Input bytes of length <em>3n+1</em> generate unpadded output characters
112
+ # of length <em>4n+2</em>, with two padding characters at the end:
113
+ #
114
+ # # n = 1: 4 bytes => 6 characters.
115
+ # Base64.urlsafe_encode64('1234', padding: false) # => "MDEyMw"
116
+ # # n = 2: 7 bytes => 10 characters.
117
+ # Base64.urlsafe_encode64('1234567', padding: false) # => "MDEyMzQ1Ng"
118
+ #
119
+ # - Input bytes of length <em>3n+2</em> generate unpadded output characters
120
+ # of length <em>4n+3</em>, with one padding character at the end:
121
+ #
122
+ # # n = 1: 5 bytes => 7 characters.
123
+ # Base64.urlsafe_encode64('12345', padding: false) # => "MDEyMzQ"
124
+ # # m = 2: 8 bytes => 11 characters.
125
+ # Base64.urlsafe_encode64('12345678', padding: false) # => "MDEyMzQ1Njc"
126
+ #
127
+ # <b>Padding in Decode Methods</b>
128
+ #
129
+ # All of the \Base64 decode methods support (but do not require) padding.
130
+ #
131
+ # \Method Base64.decode64 does not check the size of the padding:
132
+ #
133
+ # Base64.decode64("MDEyMzQ1Njc") # => "01234567"
134
+ # Base64.decode64("MDEyMzQ1Njc=") # => "01234567"
135
+ # Base64.decode64("MDEyMzQ1Njc==") # => "01234567"
136
+ #
137
+ # \Method Base64.strict_decode64 strictly enforces padding size:
138
+ #
139
+ # Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError
140
+ # Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567"
141
+ # Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError
142
+ #
143
+ # \Method Base64.urlsafe_decode64 allows padding in +str+,
144
+ # which if present, must be correct:
145
+ # see {Padding}[Base64.html#module-Base64-label-Padding], above:
146
+ #
147
+ # Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567"
148
+ # Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567"
149
+ # Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError.
150
+ #
151
+ # == Newlines
152
+ #
153
+ # An encoded string returned by Base64.encode64 or Base64.urlsafe_encode64
154
+ # has an embedded newline character
155
+ # after each 60-character sequence, and, if non-empty, at the end:
156
+ #
157
+ # # No newline if empty.
158
+ # encoded = Base64.encode64("\x00" * 0)
159
+ # encoded.index("\n") # => nil
160
+ #
161
+ # # Newline at end of short output.
162
+ # encoded = Base64.encode64("\x00" * 1)
163
+ # encoded.size # => 4
164
+ # encoded.index("\n") # => 4
165
+ #
166
+ # # Newline at end of longer output.
167
+ # encoded = Base64.encode64("\x00" * 45)
168
+ # encoded.size # => 60
169
+ # encoded.index("\n") # => 60
170
+ #
171
+ # # Newlines embedded and at end of still longer output.
172
+ # encoded = Base64.encode64("\x00" * 46)
173
+ # encoded.size # => 65
174
+ # encoded.rindex("\n") # => 65
175
+ # encoded.split("\n").map {|s| s.size } # => [60, 4]
176
+ #
177
+ # The string to be encoded may itself contain newlines,
178
+ # which are encoded as \Base64:
179
+ #
180
+ # # Base64.encode64("\n\n\n") # => "CgoK\n"
181
+ # s = "This is line 1\nThis is line 2\n"
182
+ # Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
20
183
  #
21
- # The purpose of using base64 to encode data is that it translates any
22
- # binary data into purely printable characters.
23
-
24
184
  module Base64
185
+
186
+ VERSION = "0.2.0"
187
+
25
188
  module_function
26
189
 
27
- # Returns the Base64-encoded version of +bin+.
28
- # This method complies with RFC 2045.
29
- # Line feeds are added to every 60 encoded characters.
190
+ # Returns a string containing the RFC-2045-compliant \Base64-encoding of +bin+.
191
+ #
192
+ # Per RFC 2045, the returned string may contain the URL-unsafe characters
193
+ # <tt>+</tt> or <tt>/</tt>;
194
+ # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
195
+ #
196
+ # Base64.encode64("\xFB\xEF\xBE") # => "++++\n"
197
+ # Base64.encode64("\xFF\xFF\xFF") # => "////\n"
30
198
  #
31
- # require 'base64'
32
- # Base64.encode64("Now is the time for all good coders\nto learn Ruby")
199
+ # The returned string may include padding;
200
+ # see {Padding}[Base64.html#module-Base64-label-Padding] above.
33
201
  #
34
- # <i>Generates:</i>
202
+ # Base64.encode64('*') # => "Kg==\n"
203
+ #
204
+ # The returned string ends with a newline character, and if sufficiently long
205
+ # will have one or more embedded newline characters;
206
+ # see {Newlines}[Base64.html#module-Base64-label-Newlines] above:
207
+ #
208
+ # Base64.encode64('*') # => "Kg==\n"
209
+ # Base64.encode64('*' * 46)
210
+ # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq\nKg==\n"
211
+ #
212
+ # The string to be encoded may itself contain newlines,
213
+ # which will be encoded as ordinary \Base64:
214
+ #
215
+ # Base64.encode64("\n\n\n") # => "CgoK\n"
216
+ # s = "This is line 1\nThis is line 2\n"
217
+ # Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
35
218
  #
36
- # Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g
37
- # UnVieQ==
38
219
  def encode64(bin)
39
220
  [bin].pack("m")
40
221
  end
41
222
 
42
- # Returns the Base64-decoded version of +str+.
43
- # This method complies with RFC 2045.
44
- # Characters outside the base alphabet are ignored.
45
- #
46
- # require 'base64'
47
- # str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' +
48
- # 'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' +
49
- # 'ZSB0aHJlZQpBbmQgc28gb24uLi4K'
50
- # puts Base64.decode64(str)
51
- #
52
- # <i>Generates:</i>
53
- #
54
- # This is line one
55
- # This is line two
56
- # This is line three
57
- # And so on...
223
+ # Returns a string containing the decoding of an RFC-2045-compliant
224
+ # \Base64-encoded string +str+:
225
+ #
226
+ # s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
227
+ # Base64.decode64(s) # => "This is line 1\nThis is line 2\n"
228
+ #
229
+ # Non-\Base64 characters in +str+ are ignored;
230
+ # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
231
+ # these include newline characters and characters <tt>-</tt> and <tt>/</tt>:
232
+ #
233
+ # Base64.decode64("\x00\n-_") # => ""
234
+ #
235
+ # Padding in +str+ (even if incorrect) is ignored:
236
+ #
237
+ # Base64.decode64("MDEyMzQ1Njc") # => "01234567"
238
+ # Base64.decode64("MDEyMzQ1Njc=") # => "01234567"
239
+ # Base64.decode64("MDEyMzQ1Njc==") # => "01234567"
240
+ #
58
241
  def decode64(str)
59
242
  str.unpack1("m")
60
243
  end
61
244
 
62
- # Returns the Base64-encoded version of +bin+.
63
- # This method complies with RFC 4648.
64
- # No line feeds are added.
245
+ # Returns a string containing the RFC-2045-compliant \Base64-encoding of +bin+.
246
+ #
247
+ # Per RFC 2045, the returned string may contain the URL-unsafe characters
248
+ # <tt>+</tt> or <tt>/</tt>;
249
+ # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
250
+ #
251
+ # Base64.strict_encode64("\xFB\xEF\xBE") # => "++++\n"
252
+ # Base64.strict_encode64("\xFF\xFF\xFF") # => "////\n"
253
+ #
254
+ # The returned string may include padding;
255
+ # see {Padding}[Base64.html#module-Base64-label-Padding] above.
256
+ #
257
+ # Base64.strict_encode64('*') # => "Kg==\n"
258
+ #
259
+ # The returned string will have no newline characters, regardless of its length;
260
+ # see {Newlines}[Base64.html#module-Base64-label-Newlines] above:
261
+ #
262
+ # Base64.strict_encode64('*') # => "Kg=="
263
+ # Base64.strict_encode64('*' * 46)
264
+ # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg=="
265
+ #
266
+ # The string to be encoded may itself contain newlines,
267
+ # which will be encoded as ordinary \Base64:
268
+ #
269
+ # Base64.strict_encode64("\n\n\n") # => "CgoK"
270
+ # s = "This is line 1\nThis is line 2\n"
271
+ # Base64.strict_encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK"
272
+ #
65
273
  def strict_encode64(bin)
66
274
  [bin].pack("m0")
67
275
  end
68
276
 
69
- # Returns the Base64-decoded version of +str+.
70
- # This method complies with RFC 4648.
71
- # ArgumentError is raised if +str+ is incorrectly padded or contains
72
- # non-alphabet characters. Note that CR or LF are also rejected.
277
+ # Returns a string containing the decoding of an RFC-2045-compliant
278
+ # \Base64-encoded string +str+:
279
+ #
280
+ # s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK"
281
+ # Base64.strict_decode64(s) # => "This is line 1\nThis is line 2\n"
282
+ #
283
+ # Non-\Base64 characters in +str+ not allowed;
284
+ # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
285
+ # these include newline characters and characters <tt>-</tt> and <tt>/</tt>:
286
+ #
287
+ # Base64.strict_decode64("\n") # Raises ArgumentError
288
+ # Base64.strict_decode64('-') # Raises ArgumentError
289
+ # Base64.strict_decode64('_') # Raises ArgumentError
290
+ #
291
+ # Padding in +str+, if present, must be correct:
292
+ #
293
+ # Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError
294
+ # Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567"
295
+ # Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError
296
+ #
73
297
  def strict_decode64(str)
74
298
  str.unpack1("m0")
75
299
  end
76
300
 
77
- # Returns the Base64-encoded version of +bin+.
78
- # This method complies with ``Base 64 Encoding with URL and Filename Safe
79
- # Alphabet'' in RFC 4648.
80
- # The alphabet uses '-' instead of '+' and '_' instead of '/'.
81
- # Note that the result can still contain '='.
82
- # You can remove the padding by setting +padding+ as false.
301
+ # Returns the RFC-4648-compliant \Base64-encoding of +bin+.
302
+ #
303
+ # Per RFC 4648, the returned string will not contain the URL-unsafe characters
304
+ # <tt>+</tt> or <tt>/</tt>,
305
+ # but instead may contain the URL-safe characters
306
+ # <tt>-</tt> and <tt>_</tt>;
307
+ # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
308
+ #
309
+ # Base64.urlsafe_encode64("\xFB\xEF\xBE") # => "----"
310
+ # Base64.urlsafe_encode64("\xFF\xFF\xFF") # => "____"
311
+ #
312
+ # By default, the returned string may have padding;
313
+ # see {Padding}[Base64.html#module-Base64-label-Padding], above:
314
+ #
315
+ # Base64.urlsafe_encode64('*') # => "Kg=="
316
+ #
317
+ # Optionally, you can suppress padding:
318
+ #
319
+ # Base64.urlsafe_encode64('*', padding: false) # => "Kg"
320
+ #
321
+ # The returned string will have no newline characters, regardless of its length;
322
+ # see {Newlines}[Base64.html#module-Base64-label-Newlines] above:
323
+ #
324
+ # Base64.urlsafe_encode64('*') # => "Kg=="
325
+ # Base64.urlsafe_encode64('*' * 46)
326
+ # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg=="
327
+ #
83
328
  def urlsafe_encode64(bin, padding: true)
84
329
  str = strict_encode64(bin)
85
330
  str.chomp!("==") or str.chomp!("=") unless padding
@@ -87,14 +332,22 @@ module Base64
87
332
  str
88
333
  end
89
334
 
90
- # Returns the Base64-decoded version of +str+.
91
- # This method complies with ``Base 64 Encoding with URL and Filename Safe
92
- # Alphabet'' in RFC 4648.
93
- # The alphabet uses '-' instead of '+' and '_' instead of '/'.
94
- #
95
- # The padding character is optional.
96
- # This method accepts both correctly-padded and unpadded input.
97
- # Note that it still rejects incorrectly-padded input.
335
+ # Returns the decoding of an RFC-4648-compliant \Base64-encoded string +str+:
336
+ #
337
+ # +str+ may not contain non-Base64 characters;
338
+ # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
339
+ #
340
+ # Base64.urlsafe_decode64('+') # Raises ArgumentError.
341
+ # Base64.urlsafe_decode64('/') # Raises ArgumentError.
342
+ # Base64.urlsafe_decode64("\n") # Raises ArgumentError.
343
+ #
344
+ # Padding in +str+, if present, must be correct:
345
+ # see {Padding}[Base64.html#module-Base64-label-Padding], above:
346
+ #
347
+ # Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567"
348
+ # Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567"
349
+ # Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError.
350
+ #
98
351
  def urlsafe_decode64(str)
99
352
  # NOTE: RFC 4648 does say nothing about unpadded input, but says that
100
353
  # "the excess pad characters MAY also be ignored", so it is inferred that
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: base64
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yusuke Endoh
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-14 00:00:00.000000000 Z
11
+ date: 2023-11-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Support for encoding and decoding binary data using a Base64 representation.
14
14
  email:
@@ -35,14 +35,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
35
35
  requirements:
36
36
  - - ">="
37
37
  - !ruby/object:Gem::Version
38
- version: 2.3.0
38
+ version: '2.4'
39
39
  required_rubygems_version: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
43
  version: '0'
44
44
  requirements: []
45
- rubygems_version: 3.2.22
45
+ rubygems_version: 3.5.0.dev
46
46
  signing_key:
47
47
  specification_version: 4
48
48
  summary: Support for encoding and decoding binary data using a Base64 representation.