Base58

一種編碼方式

Base58是用於比特幣(Bitcoin)中使用的一種獨特的編碼方式,主要用於產生Bitcoin的錢包地址。相比Base64,Base58不使用數字"0",字母大寫"O",字母大寫"I",和字母小寫"l",以及"+"和"/"符號。

設計Base58主要的目的是:

  1. 避免混淆。在某些字體下,數字0和字母大寫O,以及字母大寫I和字母小寫l會非常相似。
  2. 不使用"+"和"/"的原因是非字母或數字的字符串作為帳號較難被接受。
  3. 沒有標點符號,通常不會被從中間分行。
  4. 大部分的軟件支持雙擊選擇整個字符串。

以下引用自其作者中本聰(Satoshi Nakamoto)在base58.h中的註釋:

//
// 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.
// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
//

編碼

一個Base58"字元"可以表示的位元數為Log258 5.858 bits。經過Base58編碼的數據為原始的數據長度的 倍,稍微多於Base64的1.33倍。

編碼符號表:

編碼 字符 編碼 字符   編碼 字符   編碼 字符
0 1 16 H 32 Z 48 q
1 2 17 J 33 a 49 r
2 3 18 K 34 b 50 s
3 4 19 L 35 c 51 t
4 5 20 M 36 d 52 u
5 6 21 N 37 e 53 v
6 7 22 P 38 f 54 w
7 8 23 Q 39 g 55 x
8 9 24 R 40 h 56 y
9 A 25 S 41 i 57 z
10 B 26 T 42 j
11 C 27 U 43 k
12 D 28 V 44 m
13 E 29 W 45 n
14 F 30 X 46 o
15 G 31 Y 47 p

由於256不能被58所整除,Base58無法像Base64那樣子轉換為8位元的二進位後依次取出6位元,就可以快速完成轉換;因此,Base58編碼演算法需要除法運算實現。如果被編碼的數據較長,則要用特殊的class來處理大數,在Bitcoin使用了OpenSSL中的BIGNUM:

    code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    x = convert_bytes_to_big_integer(hash_result);

    output_string = "";

    while(x > 0) 
    {
        (x, remainder) = divide(x, 58);
        output_string.append(code_string[remainder]);
    }

    repeat(number_of_leading_zero_bytes_in_hash)
    {
        output_string.append(code_string[0]);
    }
    
    output_string.reverse();

外部連結

參見