Java 代码的多次 sha256 摘要的 Python 实现

2020-03-09 21:11:49 +08:00
 smallerpig

平台本身是用 java 写的,想用 python 同样实现一套,但是使用的终端已经内置了加密算法,所以算法不可变,算法逻辑中间有一段大概是这样:

        byte[] value = Utf8.encode(inputString) // 工具类实现字符串转 byte[]
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256")
        for (int i = 0; i < 1024; i++) {
            value = messageDigest.digest(value);
             // 因 java 语言的特性,上面获取摘要的的字节数组是里面是包含负数的,包含负数数据的 byte[]又直接进行摘要。
        }
        return new String(Hex.encode(value)) // Hex 工具类转成 16 进制字符串

实现相同算法时使用 python3:

sha256 = hashlib.sha256()
bs = bytes(inputString, encoding="utf-8")
sha256.update(bs)  
for i in range(0,1023):
    sha256.update(sha256.digest())  # 此时拿到的 bytes 与 java 拿到的其实已经是不一样了,所以最终拿到的摘要值也就不同了
print(sha256.hexdigest())

其实平台使用的的摘要方式如果是 1024 次摘要十六进制字符串的摘要的话,那其实与语言特性就无关了,但是实现方式却是使用连续对字节数组(byte[])进行摘要。python 的 bytes 又不支持负数,导致最终多次计算之后的值不一致。

大佬们看看怎么解决这个问题。

2646 次点击
所在节点    Python
3 条回复
yyang179
2020-03-09 21:50:15 +08:00
试试把 bytes 转成 np.int8 的数组,然后再 sha256.update。
wwqgtxx
2020-03-09 21:56:34 +08:00
看了一下 python 代码部分,你在循环中 update 应该就违反了 java 代码的本意,python 的 hashlib 中,调用多次 update 之后会将多次的输入拼接后进行 hash,你可能需要要循环中重新初始化一个新的 hashlib.sha256
smallerpig
2020-03-09 22:07:48 +08:00
@wwqgtxx 大佬你说的是正确的,用你的方法修改了 Python 方法:
``` python
temp = bytes(inputString, encoding="utf-8")
for i in range(0, 1024):
sha256 = hashlib.sha256()
sha256.update(temp)
temp = sha256.digest()

```
核心就是把实例化 sha256 的操作放到循环里面去,这样每次一个,而不是每次在同一个 hashlib.sha256 对象里去 update。
感谢你的回复,解决了我一天的问题。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/651333

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX