Module: Base45Lite

Defined in:
lib/base45_lite.rb

Overview

An implementation of draft-faltstrom-base45-10, see datatracker.ietf.org/doc/draft-faltstrom-base45/

Defined Under Namespace

Classes: Error, ForbiddenLengthError, InvalidCharacterError, OverflowError

Constant Summary collapse

MAX_UINT18 =
2**16 - 1
SQUARED_45 =
45**2
MAPPING =
[
  *'0'..'9',
  *'A'..'Z',
  ' ', '$', '%', '*', '+', '-', '.', '/', ':'
].map!.with_index { |x, i| [i, x] }.to_h.freeze
REVERSE_MAPPING =
MAPPING.invert.freeze

Class Method Summary collapse

Class Method Details

.decode(input) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/base45_lite.rb', line 56

def self.decode(input)
  input
    .chars.map! { |c| REVERSE_MAPPING[c] || raise(InvalidCharacterError) }
    .each_slice(3).map do |slice|
      c, d, e = slice
      raise ForbiddenLengthError if d.nil?

      sum = c + d * 45
      sum += e * SQUARED_45 if e
      raise OverflowError if sum > MAX_UINT18

      sum
    end
    .pack((input.length % 3).zero? ? 'n*' : "n#{input.length / 3}C")
end

.encode(input) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/base45_lite.rb', line 40

def self.encode(input)
  sequence = []
  input.unpack('n*').map! do |uint16|
    i, c = uint16.divmod(45)
    i, d = i.divmod(45)
    _, e = i.divmod(45)
    sequence.push(c, d, e)
  end
  if input.bytesize.odd?
    i, c = input.getbyte(-1).divmod(45)
    _, d = i.divmod(45)
    sequence.push(c, d)
  end
  sequence.map!{ |n| MAPPING[n] }.join
end