Base58
Encoding / Decoding¶ ↑
Encode / decode numbers, hex or binary strings (incl. leading zeros) with Bitcoin or Flickr base58 notation / alphabet
-
home :: github.com/rubycoco/blockchain
Base58
Alphabets¶ ↑
Bitcoin¶ ↑
The bitcoin notation / alphabet (123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
)
The order of it's 58 characters is numeric, uppercase-alpha, lowercase-alpha.
Why use base58 (and not “standard” base64)?
// - 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. // - Doubleclicking selects the whole number as one word if it's all alphanumeric.
(Source: base58.h
- Bitcoin Source Code Header Comments)
Bitcoin (Base58
) Notation¶ ↑
Num | Character | Num | Character | Num | Character | Num | Character |
---|---|---|---|---|---|---|---|
0 | **1** | 1 | **2** | 2 | **3** | 3 | **4** |
4 | **5** | 5 | **6** | 6 | **7** | 7 | **8** |
8 | **9** | 9 | **A** | 10 | **B** | 11 | **C** |
12 | **D** | 13 | **E** | 14 | **F** | 15 | **G** |
16 | **H** | 17 | **J** | 18 | **K** | 19 | **L** |
20 | **M** | 21 | **N** | 22 | **P** | 23 | **Q** |
24 | **R** | 25 | **S** | 26 | **T** | 27 | **U** |
28 | **V** | 29 | **W** | 30 | **X** | 31 | **Y** |
32 | **Z** | 33 | **a** | 34 | **b** | 35 | **c** |
36 | **d** | 37 | **e** | 38 | **f** | 39 | **g** |
40 | **h** | 41 | **i** | 42 | **j** | 43 | **k** |
44 | **m** | 45 | **n** | 46 | **o** | 47 | **p** |
48 | **q** | 49 | **r** | 50 | **s** | 51 | **t** |
52 | **u** | 53 | **v** | 54 | **w** | 55 | **x** |
56 | **y** | 57 | **z** |
Note: 0
(Zero), O
(Upper-O), I
(Upper-I), l
(Lower-L) - these four characters (digits/letters) are missing in the base 58 alphabets.
Usage
Encode / Decode Numbers
require 'base58-alphabets' Base58.encode_num( 100 ) #=> "2j" Base58.encode_num( 123456789 ) #=> "BukQL" Base58.decode_num( "2j") #=> 100 Base58.decode_num( "BukQL" ) #=> 123456789 # or Base58::Bitcoin.encode_num( 100 ) #=> "2j" Base58::Bitcoin.encode_num( 123456789 ) #=> "BukQL" Base58::Bitcoin.decode_num( "2j") #=> 100 Base58::Bitcoin.decode_num( "BukQL" ) #=> 123456789
Encode / Decode Hex Strings
Base58.encode_hex( "626262" ) #=> "a3gV" # Note: The `0x` or `0X` hex prefix is optional. Base58.encode_hex( "0x626262" ) #=> "a3gV" Base58.encode_hex( "0X626262" ) #=> "a3gV" Base58.encode_hex( "516b6fcd0f" ) #=> "ABnLTmg" Base58.decode_hex( "a3gV" ) #=> "626262" Base58.decode_hex( "ABnLTmg" ) #=> "516b6fcd0f" # or Base58::Bitcoin.encode_hex( "626262" ) #=> "a3gV" Base58::Bitcoin.encode_hex( "516b6fcd0f" ) #=> "ABnLTmg" Base58::Bitcoin.decode_hex( "a3gV" ) #=> "626262" Base58::Bitcoin.decode_hex( "ABnLTmg" ) #=> "516b6fcd0f"
What about leading zeros?
Yes, if you use a hex or binary string - the leading zero bytes will get encoded / decoded (converted from 00
to 1
and back):
Base58.encode_hex( "00000000000000000000" ) #=> "1111111111" Base58.encode_hex( "00000000000000000000123456789abcdef0" ) #=> "111111111143c9JGph3DZ" Base58.decode_hex( "1111111111" ) #=> "00000000000000000000" Base58.decode_hex( "111111111143c9JGph3DZ" ) #=> "00000000000000000000123456789abcdef0"
Encode / Decode Bin(ary) Strings
Base58.encode_bin( "\xCE\xE99\x86".b ) #=> "6Hknds" Base58.decode_bin( "6Hknds" ) #=> "\xCE\xE99\x86" # or Base58::Bitcoin.encode_bin( "\xCE\xE99\x86".b ) #=> "6Hknds" Base58::Bitcoin.decode_bin( "6Hknds" ) #=> "\xCE\xE99\x86"
Flickr¶ ↑
The flickr notation / alphabet (123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ
)
The order of it's 58 characters is numeric, lowercase-alpha, uppercase-alpha.
Encode / Decode Numbers
Base58.format = :flickr # switch to flickr alphabet (default is bitcoin) Base58.encode_num( 12345 ) #=> "4ER" Base58.decode_num( "4ER" ) #=> 12345 # or Base58::Flickr.encode_num( 12345 ) #=> "4ER" Base58::Flickr.decode_num( "4ER" ) #=> 12345
That's it.
What's Base 58?¶ ↑
The number of characters you are left with when you use all the characters in the alphanumeric alphabet, but remove all the easily mistakable characters like 0
, O
, l
and I
is… 58.
alphanumeric = 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
(62 characters)
base58 = 123456789ABCDEFGH JKLMN PQRSTUVWXYZabcdefghijk mnopqrstuvwxyz
(58 characters)
From the Wikipedia:
Similar to Base64, but modified to avoid both non-alphanumeric characters (
+
and/
) and letters which might look ambiguous when printed (0
- zero,I
- capital i,O
- capital o andl
- lower case L). Satoshi Nakamoto invented the base58 encoding scheme when creating bitcoin. Some messaging and social media systems line break on non-alphanumeric strings. This is avoided by not using URI reserved characters such as+
.(Source: Base58 @ Wikipedia)
Why use base58?
The more characters you have in your base, the less you will need to use to represent big numbers. The bigger your base, the shorter your “number”. Example:
base10( 9999 ) #=> 9999 - decimal base16( 9999 ) #=> 270f - hexadecimal base58( 9999 ) #=> 3yQ
Install¶ ↑
Just install the gem:
$ gem install base58-alphabets
License¶ ↑
The base58-alphabets
scripts are dedicated to the public domain. Use it as you please with no restrictions whatsoever.