base32 crockford 编码与其他语言的实现结果不同?

需求倒是很简单,给一个Hex 格式的string, 对其进行 base32(crockford) 编码,求编码结果。下面是代码,期望结果是 "2HH0GC3SRC6PAYX9Z6WVGKCEK0TEF9QC8K7J8F312QSZYEYP64MN8Y9SXR", 实际得到 "MC8430YE31NJQQAFSQ6W4V3MR6KKTDV24SWJ3RR8NYFZKQNHH55A7JEFE"。

import base32_crockford
from base64 import b16decode

buffer_hex = "1462083079c30d657ba9f9b9b84d8e9834e7a6ec44cf243c6115f3ff3bd63129547939ee"
b = b16decode(buffer_hex.upper())
n = int.from_bytes(b, byteorder="big", signed=False)
result = base32_crockford.encode(n)
print(result) # output: MC8430YE31NJQQAFSQ6W4V3MR6KKTDV24SWJ3RR8NYFZKQNHH55A7JEFE, 与预期不符

因为换了其他语言比如nodejs, 很容易就拿到了期望的结果
package.json:

"base32-decode": "1.0.0",
"base32-encode": "1",

完整代码:

const base32Encode = require('base32-encode')

const buffer_hex = '1462083079c30d657ba9f9b9b84d8e9834e7a6ec44cf243c6115f3ff3bd63129547939ee'
const buf = Buffer.from(buffer_hex, 'hex')
const u8 = new Uint8Array(buf)
const result = base32Encode(u8, 'Crockford')
// output: 2HH0GC3SRC6PAYX9Z6WVGKCEK0TEF9QC8K7J8F312QSZYEYP64MN8Y9SXR, 这是期望的结果
console.log(result) 

可以对标这个在线网站的结果
https://cryptii.com/pipes/hex-to-base32
image.png

我尝试过修改python 脚本中的 int.from_bytes的参数,比如字节顺序改成 "little"小端序, singed=True,依然得不到期望结果。

阅读 460
1 个回答

n = int.from_bytes(b, byteorder="big", signed=False) 这步开始就不对了,node.js 的实现是 bytes 5 位一组转换并拼接的,而不是直接把一个大数整体转换。

重新写了一个,没有第三方依赖:

image.png

from base64 import b16decode

def crockford_b32encode(data: bytes) -> str:
    # 定义 crockford 字符集
    symbols = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
    # bytes 转二进制字符串
    bitstr = ''.join(f'{byte:08b}' for byte in data)
    # 填充为 5 的倍数
    padlen = (5 - (len(bitstr) % 5)) % 5
    bitstr += '0' * padlen
    # 编码
    encstr = ''.join([symbols[int(bitstr[i:i+5], 2)] for i in range(0, len(bitstr), 5)])
    return encstr

buffer_hex = "1462083079c30d657ba9f9b9b84d8e9834e7a6ec44cf243c6115f3ff3bd63129547939ee"
b = b16decode(buffer_hex.upper())
result = crockford_b32encode(b)
print(result)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题