Module: AdequateCryptoAddress::Utils::MoneroBase58
- Defined in:
- lib/adequate_crypto_address/utils/monero_base58.rb
Overview
Monero's Base58 encodes fixed 8-byte blocks into 11 characters (shorter trailing blocks use fewer characters). Reference: https://github.com/monero-project/monero/blob/master/src/common/base58.cpp
Constant Summary collapse
- ALPHABET =
'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'- FULL_BLOCK_SIZE =
8- FULL_ENCODED_BLOCK_SIZE =
11- ENCODED_BLOCK_SIZES =
Decoded byte count produced by an encoded block of each valid length.
[0, 2, 3, 5, 6, 7, 9, 10, 11].freeze
Class Method Summary collapse
- .decode(string) ⇒ Object
-
.decode_block(chars, size) ⇒ Object
Decodes one Base58 block into exactly
sizebig-endian bytes, rejecting unknown characters and values that overflow the target byte width. - .decode_tail(string, full_blocks, last_size, out) ⇒ Object
Class Method Details
.decode(string) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/adequate_crypto_address/utils/monero_base58.rb', line 17 def decode(string) return nil if string.nil? || string.empty? full_blocks = string.length / FULL_ENCODED_BLOCK_SIZE last_size = string.length % FULL_ENCODED_BLOCK_SIZE return nil unless ENCODED_BLOCK_SIZES.include?(last_size) out = [] full_blocks.times do |i| block = decode_block(string[i * FULL_ENCODED_BLOCK_SIZE, FULL_ENCODED_BLOCK_SIZE], FULL_BLOCK_SIZE) return nil unless block out.concat(block) end decode_tail(string, full_blocks, last_size, out) end |
.decode_block(chars, size) ⇒ Object
Decodes one Base58 block into exactly size big-endian bytes, rejecting
unknown characters and values that overflow the target byte width.
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/adequate_crypto_address/utils/monero_base58.rb', line 46 def decode_block(chars, size) num = 0 chars.each_char do |char| index = ALPHABET.index(char) return nil unless index num = (num * 58) + index end return nil if num >= (1 << (size * 8)) Array.new(size) { |i| (num >> (8 * (size - 1 - i))) & 0xff } end |
.decode_tail(string, full_blocks, last_size, out) ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'lib/adequate_crypto_address/utils/monero_base58.rb', line 34 def decode_tail(string, full_blocks, last_size, out) return out if last_size.zero? tail = string[full_blocks * FULL_ENCODED_BLOCK_SIZE, last_size] block = decode_block(tail, ENCODED_BLOCK_SIZES.index(last_size)) return nil unless block out.concat(block) end |