Class: Base32::Crockford
- Inherits:
-
Object
- Object
- Base32::Crockford
- Defined in:
- lib/base32/crockford.rb
Overview
encode a value with the encoding defined by Douglas Crockford in <www.crockford.com/wrmg/base32.html>
this is not the same as the Base32 encoding defined in RFC 4648
The Base32 symbol set is a superset of the Base16 symbol set.
We chose a symbol set of 10 digits and 22 letters. We exclude 4 of the 26 letters: I L O U.
Excluded Letters
- I
-
Can be confused with 1
- L
-
Can be confused with 1
- O
-
Can be confused with 0
- U
-
Accidental obscenity
When decoding, upper and lower case letters are accepted, and i and l will be treated as 1 and o will be treated as 0. When encoding, only upper case letters are used.
If the bit-length of the number to be encoded is not a multiple of 5 bits, then zero-extend the number to make its bit-length a multiple of 5.
Hyphens (-) can be inserted into symbol strings. This can partition a string into manageable pieces, improving readability by helping to prevent confusion. Hyphens are ignored during decoding. An application may look for hyphens to assure symbol string correctness.
Constant Summary collapse
- VERSION =
"0.1.0"
- ENCODE_CHARS =
%w(0 1 2 3 4 5 6 7 8 9 A B C D E F G H J K M N P Q R S T V W X Y Z ?)
- DECODE_MAP =
ENCODE_CHARS.to_enum(:each_with_index).inject({}) do |h,(c,i)| h[c] = i; h end.merge({'I' => 1, 'L' => 1, 'O' => 0})
Class Method Summary collapse
- .clean(string) ⇒ Object
-
.decode(string) ⇒ Object
decode a string to an integer using Douglas Crockfords Base32 Encoding.
-
.decode!(string) ⇒ Object
same as decode, but raises ArgumentError when the string can’t be decoded.
-
.encode(number, opts = {}) ⇒ Object
encodes an integer into a string.
-
.normalize(string) ⇒ Object
return the canonical encoding of a string.
-
.valid?(string) ⇒ Boolean
returns false iff the string contains invalid characters and can’t be decoded.
Class Method Details
.clean(string) ⇒ Object
129 130 131 |
# File 'lib/base32/crockford.rb', line 129 def clean(string) string.gsub(/-/,'').upcase end |
.decode(string) ⇒ Object
decode a string to an integer using Douglas Crockfords Base32 Encoding
the string is converted to uppercase and hyphens are stripped before decoding
I,i,l,L decodes to 1
O,o decodes to 0
Base32::Crockford.decode("16J") # => 1234
Base32::Crockford.decode("OI") # => 1
Base32::Crockford.decode("3G923-0VQVS") # => 123456789012345
returns nil
if the string contains invalid characters and can’t be decoded
98 99 100 101 102 |
# File 'lib/base32/crockford.rb', line 98 def self.decode(string) clean(string).split(//).map { |char| DECODE_MAP[char] or return nil }.inject(0) { |result,val| (result << 5) + val } end |
.decode!(string) ⇒ Object
same as decode, but raises ArgumentError when the string can’t be decoded
106 107 108 |
# File 'lib/base32/crockford.rb', line 106 def self.decode!(string) decode(string) or raise ArgumentError end |
.encode(number, opts = {}) ⇒ Object
encodes an integer into a string
when split
is given a hyphen is inserted every <n> characters to improve readability
when length
is given, the resulting string is zero-padded to be exactly this number of characters long (hyphens are ignored)
Base32::Crockford.encode(1234) # => "16J"
Base32::Crockford.encode(123456789012345, :split=>5) # => "3G923-0VQVS"
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/base32/crockford.rb', line 64 def self.encode(number, opts = {}) # verify options raise ArgumentError unless (opts.keys - [:length, :split] == []) str = number.to_s(2).reverse.scan(/.{1,5}/).map do |bits| ENCODE_CHARS[bits.reverse.to_i(2)] end.reverse.join str = str.rjust(opts[:length], '0') if opts[:length] if opts[:split] str = str.reverse str = str.scan(/.{1,#{opts[:split]}}/).map { |x| x.reverse } str = str.reverse.join("-") end str end |
.normalize(string) ⇒ Object
return the canonical encoding of a string. converts it to uppercase and removes hyphens
replaces invalid characters with a question mark (‘?’)
115 116 117 118 119 |
# File 'lib/base32/crockford.rb', line 115 def self.normalize(string) clean(string).split(//).map { |char| ENCODE_CHARS[DECODE_MAP[char] || 32] }.join end |
.valid?(string) ⇒ Boolean
returns false iff the string contains invalid characters and can’t be decoded
124 125 126 |
# File 'lib/base32/crockford.rb', line 124 def self.valid?(string) !(normalize(string) =~ /\?/) end |