目录
1-3 base58 和 base58check 的python实现
一、编码算法
1-1 Base58
Base58是一种将非可视字符与可视化字符(ASCII)相互转化的编解码方法。
- 实现了数据的压缩、便于阅读,适用于抗自动监视的传输系统的底层编码机制
- 缺乏效验机制,无法检测出传输过程中字符串的遗漏,需要配合改进算法Base58Check使用。
Base58采用数字、大写字母、小写字母(去除歧义字符 0 (零), O (大写字母O), I (大写的字母i) and l (小写的字母L) ),总计58个字符作为编码的字母表。
编码步骤:
- 在 byte[] 数据前添加一个0x00,生成一个新的byte数组,并将新数组做倒序排序
- 把数组的数据转成10进制BigInteger数
- 把BigInteger数按字母表转换成58进制字符串
- 统计原 byte[] 数据中0x00的个数 count,在字符串前补 count 个字母表游标为零所对应的字符
from hashlib import sha256 __version__ = '1.0.3' # 58 character alphabet used alphabet = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' if bytes == str: # python2 iseq, bseq, buffer = ( lambda s: map(ord, s), lambda s: ''.join(map(chr, s)), lambda s: s, ) else: # python3 iseq, bseq, buffer = ( lambda s: s, bytes, lambda s: s.buffer, ) def scrub_input(v): if isinstance(v, str) and not isinstance(v, bytes): v = v.encode('ascii') return v def b58encode(v): '''Encode a string using Base58''' v = scrub_input(v) nPad = len(v) v = v.lstrip(b'\0') nPad -= len(v) p, acc = 1, 0 for c in iseq(reversed(v)): acc += p * c p = p << 8 result = b58encode_int(acc, default_one=False) return (alphabet[0:1] * nPad + result)
解码步骤:
- 倒序输入的字符串,将其按字母表转换成10进制 Biginteger 数
- 把 Biginteger 数转换成 byte[] 数据,并将 byte[] 数据倒序排序
- 统计原输入的字符串中字母表游标为零所对应的字符的个数 count
- 若 byte[] 数据的长度大于1,且 byte[0] 等于0,byte[1] 大于等于0x80,则从 byte[1] 开始截取,否则从 byte[0] 开始截取,得到结果。
def b58decode(v): '''Decode a Base58 encoded string''' v = v.rstrip() v = scrub_input(v) origlen = len(v) v = v.lstrip(alphabet[0:1]) newlen = len(v) acc = b58decode_int(v) result = [] while acc > 0: acc, mod = divmod(acc, 256) result.append(mod) return (b'\0' * (origlen - newlen) + bseq(reversed(result)))
Example:
字符串 byte[] AXaXZjZGA3qhQRTCsyG5uFKr9HeShgVhTF [0x17, 0xad, 0x5c, 0xac, 0x59, 0x6a, 0x1e, 0xf6, 0xc1, 0x8a, 0xc1, 0x74, 0x6d, 0xfd, 0x30, 0x4f, 0x93, 0x96, 0x43, 0x54, 0xb5, 0x78, 0xa5, 0x83, 0x22] 应用场景:为Base58Check编解码方法提供服务。
1-2 Base58Check
Base58Check是基于Base58的改进型编解码方法。通过对原数据添加数据的哈希值作为盐,弥补了Base58缺少效验机制的缺点。
编码步骤:
- 通过对原 byte[] 数据做两次 sha256 得到原数据的哈希,取其前4字节作为版本前缀checksum,添加到原 byte[] 数据的末尾。
- 把添加了版本前缀的 byte[] 数据做 Base58 编码得到对应的字符串。
from hashlib import sha256 __version__ = '1.0.3' # 58 character alphabet used alphabet