Module: Philiprehberger::BaseConvert::Base58
- Defined in:
- lib/philiprehberger/base_convert/base58.rb
Overview
Base58 encoding and decoding using the Bitcoin alphabet
Alphabet: 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
Constant Summary collapse
- ALPHABET =
'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'- BASE =
ALPHABET.length
- DECODE_MAP =
ALPHABET.each_char.with_index.to_h.freeze
Class Method Summary collapse
-
.decode(string) ⇒ String
Decode a Base58 string.
-
.decode_int(string) ⇒ Integer
Decode a Base58 string to an integer.
-
.encode(string) ⇒ String
Encode a string to Base58.
-
.encode_int(integer) ⇒ String
Encode a non-negative integer to Base58.
Class Method Details
.decode(string) ⇒ String
Decode a Base58 string
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/philiprehberger/base_convert/base58.rb', line 39 def self.decode(string) return '' if string.empty? leading_ones = string.each_char.take_while { |c| c == ALPHABET[0] }.length num = 0 string.each_char do |char| value = DECODE_MAP[char] raise Error, "invalid Base58 character: #{char}" if value.nil? num = (num * BASE) + value end result = [] while num.positive? num, byte = num.divmod(256) result << byte end ("\x00" * leading_ones) + result.reverse.pack('C*') end |
.decode_int(string) ⇒ Integer
Decode a Base58 string to an integer
86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/philiprehberger/base_convert/base58.rb', line 86 def self.decode_int(string) raise ArgumentError, 'input must be a non-empty string' if string.nil? || string.empty? num = 0 string.each_char do |char| value = DECODE_MAP[char] raise ArgumentError, "invalid Base58 character: #{char}" if value.nil? num = (num * BASE) + value end num end |
.encode(string) ⇒ String
Encode a string to Base58
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/philiprehberger/base_convert/base58.rb', line 17 def self.encode(string) return '' if string.empty? bytes = string.bytes leading_zeros = bytes.take_while(&:zero?).length num = bytes.inject(0) { |acc, byte| (acc << 8) | byte } result = [] while num.positive? num, remainder = num.divmod(BASE) result << ALPHABET[remainder] end (ALPHABET[0] * leading_zeros) + result.reverse.join end |
.encode_int(integer) ⇒ String
Encode a non-negative integer to Base58
66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/philiprehberger/base_convert/base58.rb', line 66 def self.encode_int(integer) raise ArgumentError, 'input must be a non-negative integer' unless integer.is_a?(Integer) && integer >= 0 return ALPHABET[0] if integer.zero? result = [] num = integer while num.positive? num, remainder = num.divmod(BASE) result << ALPHABET[remainder] end result.reverse.join end |