V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
smallerpig
V2EX  ›  Python

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

  •  
  •   smallerpig ·
    smallerpig · 2020-03-09 21:11:49 +08:00 · 2649 次点击
    这是一个创建于 1722 天前的主题,其中的信息可能已经有所发展或是发生改变。

    平台本身是用 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 又不支持负数,导致最终多次计算之后的值不一致。

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

    3 条回复    2020-03-09 22:07:48 +08:00
    yyang179
        1
    yyang179  
       2020-03-09 21:50:15 +08:00 via Android
    试试把 bytes 转成 np.int8 的数组,然后再 sha256.update。
    wwqgtxx
        2
    wwqgtxx  
       2020-03-09 21:56:34 +08:00 via iPhone   ❤️ 2
    看了一下 python 代码部分,你在循环中 update 应该就违反了 java 代码的本意,python 的 hashlib 中,调用多次 update 之后会将多次的输入拼接后进行 hash,你可能需要要循环中重新初始化一个新的 hashlib.sha256
    smallerpig
        3
    smallerpig  
    OP
       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。
    感谢你的回复,解决了我一天的问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1314 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 17:53 · PVG 01:53 · LAX 09:53 · JFK 12:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.