1 | #
|
---|
2 | # = base64.rb: methods for base64-encoding and -decoding stings
|
---|
3 | #
|
---|
4 | # Author:: Yukihiro Matsumoto
|
---|
5 | # Documentation:: Dave Thomas and Gavin Sinclair
|
---|
6 | #
|
---|
7 | # Until Ruby 1.8.1, these methods were defined at the top-level. Now
|
---|
8 | # they are in the Base64 module but included in the top-level, where
|
---|
9 | # their usage is deprecated.
|
---|
10 | #
|
---|
11 | # See Base64 for documentation.
|
---|
12 | #
|
---|
13 |
|
---|
14 | require "kconv"
|
---|
15 |
|
---|
16 |
|
---|
17 | # The Base64 module provides for the encoding (#encode64) and decoding
|
---|
18 | # (#decode64) of binary data using a Base64 representation.
|
---|
19 | #
|
---|
20 | # The following particular features are also provided:
|
---|
21 | # - encode into lines of a given length (#b64encode)
|
---|
22 | # - decode the special format specified in RFC2047 for the
|
---|
23 | # representation of email headers (decode_b)
|
---|
24 | #
|
---|
25 | # == Example
|
---|
26 | #
|
---|
27 | # A simple encoding and decoding.
|
---|
28 | #
|
---|
29 | # require "base64"
|
---|
30 | #
|
---|
31 | # enc = Base64.encode64('Send reinforcements')
|
---|
32 | # # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
|
---|
33 | # plain = Base64.decode64(enc)
|
---|
34 | # # -> "Send reinforcements"
|
---|
35 | #
|
---|
36 | # The purpose of using base64 to encode data is that it translates any
|
---|
37 | # binary data into purely printable characters. It is specified in
|
---|
38 | # RFC 2045 (http://www.faqs.org/rfcs/rfc2045.html).
|
---|
39 |
|
---|
40 | module Base64
|
---|
41 | module_function
|
---|
42 |
|
---|
43 | # Returns the Base64-decoded version of +str+.
|
---|
44 | #
|
---|
45 | # require 'base64'
|
---|
46 | # str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' +
|
---|
47 | # 'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' +
|
---|
48 | # 'ZSB0aHJlZQpBbmQgc28gb24uLi4K'
|
---|
49 | # puts Base64.decode64(str)
|
---|
50 | #
|
---|
51 | # <i>Generates:</i>
|
---|
52 | #
|
---|
53 | # This is line one
|
---|
54 | # This is line two
|
---|
55 | # This is line three
|
---|
56 | # And so on...
|
---|
57 |
|
---|
58 | def decode64(str)
|
---|
59 | str.unpack("m")[0]
|
---|
60 | end
|
---|
61 |
|
---|
62 |
|
---|
63 | # Decodes text formatted using a subset of RFC2047 (the one used for
|
---|
64 | # mime-encoding mail headers).
|
---|
65 | #
|
---|
66 | # Only supports an encoding type of 'b' (base 64), and only supports
|
---|
67 | # the character sets ISO-2022-JP and SHIFT_JIS (so the only two
|
---|
68 | # encoded word sequences recognized are <tt>=?ISO-2022-JP?B?...=</tt> and
|
---|
69 | # <tt>=?SHIFT_JIS?B?...=</tt>). Recognition of these sequences is case
|
---|
70 | # insensitive.
|
---|
71 |
|
---|
72 | def decode_b(str)
|
---|
73 | str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/i) {
|
---|
74 | decode64($1)
|
---|
75 | }
|
---|
76 | str = Kconv::toeuc(str)
|
---|
77 | str.gsub!(/=\?SHIFT_JIS\?B\?([!->@-~]+)\?=/i) {
|
---|
78 | decode64($1)
|
---|
79 | }
|
---|
80 | str = Kconv::toeuc(str)
|
---|
81 | str.gsub!(/\n/, ' ')
|
---|
82 | str.gsub!(/\0/, '')
|
---|
83 | str
|
---|
84 | end
|
---|
85 |
|
---|
86 | # Returns the Base64-encoded version of +str+.
|
---|
87 | #
|
---|
88 | # require 'base64'
|
---|
89 | # Base64.b64encode("Now is the time for all good coders\nto learn Ruby")
|
---|
90 | #
|
---|
91 | # <i>Generates:</i>
|
---|
92 | #
|
---|
93 | # Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g
|
---|
94 | # UnVieQ==
|
---|
95 |
|
---|
96 | def encode64(bin)
|
---|
97 | [bin].pack("m")
|
---|
98 | end
|
---|
99 |
|
---|
100 | # _Prints_ the Base64 encoded version of +bin+ (a +String+) in lines of
|
---|
101 | # +len+ (default 60) characters.
|
---|
102 | #
|
---|
103 | # require 'base64'
|
---|
104 | # data = "Now is the time for all good coders\nto learn Ruby"
|
---|
105 | # Base64.b64encode(data)
|
---|
106 | #
|
---|
107 | # <i>Generates:</i>
|
---|
108 | #
|
---|
109 | # Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g
|
---|
110 | # UnVieQ==
|
---|
111 |
|
---|
112 | def b64encode(bin, len = 60)
|
---|
113 | encode64(bin).scan(/.{1,#{len}}/o) do
|
---|
114 | print $&, "\n"
|
---|
115 | end
|
---|
116 | end
|
---|
117 |
|
---|
118 |
|
---|
119 | module Deprecated # :nodoc:
|
---|
120 | include Base64
|
---|
121 |
|
---|
122 | for m in Base64.private_instance_methods(false)
|
---|
123 | module_eval %{
|
---|
124 | def #{m}(*args)
|
---|
125 | warn("\#{caller(1)[0]}: #{m} is deprecated; use Base64.#{m} instead")
|
---|
126 | super
|
---|
127 | end
|
---|
128 | }
|
---|
129 | end
|
---|
130 | end
|
---|
131 | end
|
---|
132 |
|
---|
133 | include Base64::Deprecated
|
---|