Class: Base58

Inherits:
Object
  • Object
show all
Defined in:
lib/shipengine/utils/base58.rb

Overview

rubocop:disable

Defined Under Namespace

Modules: Private

Constant Summary collapse

ALPHABETS =
{
  flickr: '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ', # This is the default
  bitcoin: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz', # Also used for IPFS
  ripple: 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'
}.freeze
BASE =

NOTE: If adding new alphabets of non-standard length, this should become a method.

ALPHABETS[:flickr].length

Class Method Summary collapse

Class Method Details

.base58_to_binary(base58_val, alphabet = :flickr) ⇒ Object

Converts a base58 string to an ASCII-8BIT (binary) encoded string. All leading zeroes in the base58 input are preserved and converted to “x00” in the output.

Raises:

  • (ArgumentError)


87
88
89
90
91
92
93
# File 'lib/shipengine/utils/base58.rb', line 87

def self.base58_to_binary(base58_val, alphabet = :flickr)
  raise ArgumentError, 'Invalid alphabet selection.' unless ALPHABETS.include?(alphabet)

  nzeroes = base58_val.chars.find_index { |c| c != ALPHABETS[alphabet][0] } || base58_val.length - 1
  prefix = nzeroes.negative? ? '' : '00' * nzeroes
  [prefix + Private.int_to_hex(base58_to_int(base58_val, alphabet))].pack('H*')
end

.base58_to_int(base58_val, alphabet = :flickr) ⇒ Object Also known as: decode

Converts a base58 string to a base10 integer.

Raises:

  • (ArgumentError)


41
42
43
44
45
46
47
48
49
50
51
# File 'lib/shipengine/utils/base58.rb', line 41

def self.base58_to_int(base58_val, alphabet = :flickr)
  raise ArgumentError, 'Invalid alphabet selection.' unless ALPHABETS.include?(alphabet)

  int_val = 0
  base58_val.reverse.chars.each_with_index do |char, index|
    raise ArgumentError, 'Value passed not a valid Base58 String.' if (char_index = ALPHABETS[alphabet].index(char)).nil?

    int_val += char_index * (BASE**index)
  end
  int_val
end

.binary_to_base58(binary_val, alphabet = :flickr, include_leading_zeroes = true) ⇒ Object

Converts a ASCII-8BIT (binary) encoded string to a base58 string.

Raises:

  • (ArgumentError)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/shipengine/utils/base58.rb', line 68

def self.binary_to_base58(binary_val, alphabet = :flickr, include_leading_zeroes = true)
  raise ArgumentError, 'Value passed is not a String.' unless binary_val.is_a?(String)
  raise ArgumentError, 'Value passed is not binary.' unless binary_val.encoding == Encoding::BINARY
  raise ArgumentError, 'Invalid alphabet selection.' unless ALPHABETS.include?(alphabet)
  return int_to_base58(0, alphabet) if binary_val.empty?

  if include_leading_zeroes
    nzeroes = binary_val.bytes.find_index { |b| b != 0 } || binary_val.length - 1
    prefix = ALPHABETS[alphabet][0] * nzeroes
  else
    prefix = ''
  end

  prefix + int_to_base58(binary_val.unpack1('H*').to_i(16), alphabet)
end

.int_to_base58(int_val, alphabet = :flickr) ⇒ Object Also known as: encode

Converts a base10 integer to a base58 string.

Raises:

  • (ArgumentError)


54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/shipengine/utils/base58.rb', line 54

def self.int_to_base58(int_val, alphabet = :flickr)
  raise ArgumentError, 'Value passed is not an Integer.' unless int_val.is_a?(Integer)
  raise ArgumentError, 'Invalid alphabet selection.' unless ALPHABETS.include?(alphabet)

  base58_val = ''
  while int_val >= BASE
    mod = int_val % BASE
    base58_val = ALPHABETS[alphabet][mod, 1] + base58_val
    int_val = (int_val - mod) / BASE
  end
  ALPHABETS[alphabet][int_val, 1] + base58_val
end