Base58
一種編碼方式
此條目需要補充更多來源。 (2014年1月26日) |
Base58是用於比特幣(Bitcoin)中使用的一種獨特的編碼方式,主要用於產生Bitcoin的錢包地址。相比Base64,Base58不使用數字"0",字母大寫"O",字母大寫"I",和字母小寫"l",以及"+"和"/"符號。
設計Base58主要的目的是:
- 避免混淆。在某些字體下,數字0和字母大寫O,以及字母大寫I和字母小寫l會非常相似。
- 不使用"+"和"/"的原因是非字母或數字的字符串作為帳號較難被接受。
- 沒有標點符號,通常不會被從中間分行。
- 大部分的軟件支持雙擊選擇整個字符串。
以下引用自其作者中本聰(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();