Module: BTC::Base58
Overview
Base58 is used for compact human-friendly representation of Bitcoin addresses and private keys. Typically Base58-encoded text also contains a checksum (so-called “Base58Check”). Addresses look like 19FGfswVqxNubJbh1NW8A4t51T9x9RDVWQ. Private keys look like 5KQntKuhYWSRXNqp2yhdXzjekYAR7US3MT1715Mbv5CyUKV6hVe.
Here is what Satoshi said about Base58: Why base-58 instead of standard base-64 encoding?
-
Don’t want 0OIl characters that look the same in some fonts and
could be used to create visually identical looking account numbers.
-
A string with non-alphanumeric characters is not as easily accepted as an account number.
-
E-mail usually won’t line-break if there’s no punctuation to break at.
-
Double-clicking selects the whole number as one word if it’s all alphanumeric.
Constant Summary collapse
- ALPHABET =
'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
Instance Method Summary collapse
-
#base58_from_data(data) ⇒ Object
Converts binary string into its Base58 representation.
- #base58check_from_data(data) ⇒ Object
-
#data_from_base58(string) ⇒ Object
Converts binary string into its Base58 representation.
- #data_from_base58check(string) ⇒ Object
Instance Method Details
#base58_from_data(data) ⇒ Object
Converts binary string into its Base58 representation. If string is empty returns an empty string. If string is nil raises ArgumentError
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/btc/base58.rb', line 25 def base58_from_data(data) raise ArgumentError, 'Data is missing' unless data leading_zeroes = 0 int = 0 base = 1 data.bytes.reverse_each do |byte| if byte == 0 leading_zeroes += 1 else leading_zeroes = 0 int += base * byte end base *= 256 end ('1' * leading_zeroes) + base58_from_int(int) end |
#base58check_from_data(data) ⇒ Object
63 64 65 66 |
# File 'lib/btc/base58.rb', line 63 def base58check_from_data(data) raise ArgumentError, 'Data is missing' unless data base58_from_data(data + BTC.hash256(data)[0, 4]) end |
#data_from_base58(string) ⇒ Object
Converts binary string into its Base58 representation. If string is empty returns an empty string. If string is nil raises ArgumentError.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/btc/base58.rb', line 45 def data_from_base58(string) raise ArgumentError, 'String is missing' unless string int = int_from_base58(string) bytes = [] while int > 0 remainder = int % 256 int /= 256 bytes.unshift(remainder) end data = BTC::Data.data_from_bytes(bytes) byte_for_1 = '1'.bytes.first BTC::Data.ensure_ascii_compatible_encoding(string).bytes.each do |byte| break if byte != byte_for_1 data = "\x00" + data end data end |
#data_from_base58check(string) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/btc/base58.rb', line 68 def data_from_base58check(string) data = data_from_base58(string) if data.bytesize < 4 raise FormatError, "Invalid Base58Check string: too short string #{string.inspect}" end payload_size = data.bytesize - 4 payload = data[0, payload_size] checksum = data[payload_size, 4] if checksum != BTC.hash256(payload)[0, 4] raise FormatError, "Invalid Base58Check string: checksum invalid in #{string.inspect}" end payload end |