base64 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/base64.rb +315 -62
  3. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e354beb33c4cd44aec636c9fef7f2948971fca963a60c87efb96d02f5a1a0b84
4
- data.tar.gz: 6925a1c6847f48c78cc2ef572bceb84e2e0b88f08ad6cff08267c57d56fca9f6
3
+ metadata.gz: 67c1752cf74c25682849d866ca527d3a001d52712144ec2d1b10df96389202f0
4
+ data.tar.gz: 54196151956485052bcb6d58226490f4b30efa44fe75ace5d6e713b7a2154773
5
5
  SHA512:
6
- metadata.gz: 5b12ef4b892b908de5a44db9822565082911af176add02b565a6d34a5d2bc0997fba5caf3bbd2554337c95ce8b78a53373c60da8b2d61449f078d8948c053330
7
- data.tar.gz: 5dde38796eff1286680e7589a18862be76424c53fcfdea12e2964c7b290df738fb6c9830767dc9dc1370d989c30258564d0af0d6452bf8513780dfcf5cae8804
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
- str.unpack("m").first
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
- str.unpack("m0").first
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.2
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: 2024-10-16 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.4.19
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.