员外之前听过的编码格式要么是 Base32编码,要么是 Base64编码,今天发现还有个 Base58编码,着实让员外吃了一大惊,所以拉出来写写。还有就是员外写了这么多文章,从来没有飚过代码,这篇文章就先试着飙一些吧,看看大家反响,如果大家反映很强烈的话,以后就不再加入代码了。
Base编码
其实就是一种二进制转可视的字符串的算法,主要是用来把大的整数转换成字符串的形式,一是为了传播方便,比如网址、邮件文本、图片等就使用到了Base64编码;二是由于某些系统中只能使用ASCII字符,比如用Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法;三是base64特别适合在http,mime协议下快速传输数据。
Base58编码
Base58是用于Bitcoin中使用的一种独特的编码方式,主要用于产生Bitcoin的钱包地址。相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"l",以及"+"和"/"符号。
设计Base58主要的目的是:
- 避免混淆。在某些字体下,数字0和字母大写O,以及字母大写I和字母小写l会非常相似。这个想必每个人都遇到过,要么尝试多次最后终于成功了,要么就直接放弃了;
- 不使用"+"和"/"的原因是非字母或数字的字符串作为帐号较难被接受;
- 没有标点符号,通常不会被从中间分行;
- 大部分的软件支持双击选择整个字符串,如果中间有一些特殊符号,会打断选字。
来自维基百科
到这儿您应该发现了,其实Base58编码就是一种把整数通过编码改变成不容易输入错误的字符串,同时这组编码符号表中只有58个字符,所以就被称之为 Base58编码了。
Base58 的算法是通过输入一个[0,256)的值的流,然后输出一个[0,58) 的值的流。最后将每个值去查上面的编码表,就可以得到一个字符串,其实就是将256进制的值转换成58进制的值。这个字符串就是通过编码后的结果,这个过程就是 Base58编码的过程。
先小上一段代码,看不懂的直接略过即可:
# 将 input 256进制流转换为 output 58进制流
for carry in input:
for (outputPos, outputNum) in output.reverse():
carry += outputNum * 256
output[outputPos] = carry % 58
carry /= 58
# output 流处理完毕, carry依然有值, 则继续向 output 前部插入
while carry != 0 :
output.insertFront(carry%58)
carry /= 58
如果这个256进制的值前面有0的话,需要将前面的0直接转移到输出值的前面,因为0转换后依然是0。
Base58Check
除了上面这些之外,还不够,比特币还在 Base58 的基础上做了一些改良,主要解决了 Base58 在最后输出时没有校验机制的问题。如果在传播的过程中少了几位字符却没有被检验出来,那就会给持有比特币的用户带来巨大的损失,所以中本聪使用了 Base58Check 编码算法。