Module: Base32H

Extended by:
Base32H
Included in:
Base32H
Defined in:
lib/base32h.rb

Overview

This module provides Base32H encoding and decoding functions.

Constant Summary collapse

VERSION =
"0.1.0"

Instance Method Summary collapse

Instance Method Details

#decode(str) ⇒ Object

:category: Decoding Numeric

Decodes a Base32H number to its integer representation.



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/base32h.rb', line 112

def decode(str)
  res = str.to_s.chars.reverse.reduce({acc: 0, exp: 0}) do |state, char|
    digit = decode_digit(char)
    if digit.nil?
      state
    else
      {acc: state[:acc] + (digit * 32**state[:exp]),
       exp: state[:exp] + 1}
    end
  end
  res[:acc]
end

#decode_bin(str) ⇒ Object

:category: Decoding Binary

Decodes a Base32H binary into a string of packed unsigned bytes.



129
130
131
132
133
134
135
136
137
138
139
# File 'lib/base32h.rb', line 129

def decode_bin(str)
  data = str.chars.reject {|c| decode_digit(c).nil?}
  extra = data.length % 8
  data = (['0'] * (8 - extra)) + data if extra > 0
  out = []
  data.each_slice(8) do |s|
    chunk = u40_to_bytes decode(s.join '')
    out += chunk
  end
  out.pack('C*')
end

#decode_digit(d) ⇒ Object

:category: Decoding Digit

Decodes a single Base32H digit to its integer representation.



103
104
105
106
# File 'lib/base32h.rb', line 103

def decode_digit(d)
  d = d.to_s
  digits.find_index {|i| i.include? d}
end

#digitsObject

The complete list of Base32H digits, as an array of strings; the index of the array is the numeric value of the digit(s) in the string at that index. The first character in each string is the “canonical” digit (i.e. the one that Base32H-conformant encoders must emit for that value); all other characters (if present) are “aliases” (i.e. alternate forms of that digit that Base32H-conformant decoders must accept and correctly decode to that value).

For example, digits[27] returns ‘VvUu’, meaning that the “canonical” digit of value 27 is V, and that v, U, and u are all “aliases” of that canonical digit and decode to a value of 27.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/base32h.rb', line 22

def digits
  ['0Oo',
   '1Ii',
   '2',
   '3',
   '4',
   '5Ss',
   '6',
   '7',
   '8',
   '9',
   'Aa',
   'Bb',
   'Cc',
   'Dd',
   'Ee',
   'Ff',
   'Gg',
   'Hh',
   'Jj',
   'Kk',
   'Ll',
   'Mm',
   'Nn',
   'Pp',
   'Qq',
   'Rr',
   'Tt',
   'VvUu',
   'Ww',
   'Xx',
   'Yy',
   'Zz']
end

#encode(int) ⇒ Object

:category: Encoding Numeric

Encodes an integer to its Base32H representation.



72
73
74
75
76
77
78
79
80
81
# File 'lib/base32h.rb', line 72

def encode(int)
  rem = int.to_i.abs
  out = []
  return '0' if rem == 0
  while rem > 0 do
    out.unshift(encode_digit(rem % 32))
    rem /= 32
  end
  out.join ''
end

#encode_bin(bin) ⇒ Object

:category: Encoding Binary

Encodes a (binary) string to its Base32H representation.



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/base32h.rb', line 87

def encode_bin(bin)
  data = bin.unpack('C*')
  extra = data.length % 5
  data = ([0] * (5 - extra)) + data if extra > 0
  out = []
  data.each_slice(5) do |s|
    chunk = bytes_to_u40 s
    out.push encode(chunk).rjust(8, '0')
  end
  out.join ''
end

#encode_digit(d) ⇒ Object

:category: Encoding Digit

Encodes an integer between 0 and 31 (inclusive) to its Base32H representation.



62
63
64
65
66
# File 'lib/base32h.rb', line 62

def encode_digit(d)
  d = d.to_i
  return nil unless (0..31).include? d
  digits[d][0]
end