V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
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 · Mar 9, 2020 · 3423 views
    This topic created in 2239 days ago, the information mentioned may be changed or developed.

    平台本身是用 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 replies    2020-03-09 22:07:48 +08:00
    yyang179
        1
    yyang179  
       Mar 9, 2020 via Android
    试试把 bytes 转成 np.int8 的数组,然后再 sha256.update。
    wwqgtxx
        2
    wwqgtxx  
       Mar 9, 2020 via iPhone   ❤️ 2
    看了一下 python 代码部分,你在循环中 update 应该就违反了 java 代码的本意,python 的 hashlib 中,调用多次 update 之后会将多次的输入拼接后进行 hash,你可能需要要循环中重新初始化一个新的 hashlib.sha256
    smallerpig
        3
    smallerpig  
    OP
       Mar 9, 2020
    @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。
    感谢你的回复,解决了我一天的问题。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3397 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 12:23 · PVG 20:23 · LAX 05:23 · JFK 08:23
    ♥ Do have faith in what you're doing.