我试图在Java中复制python2.7函数的行为,但是在通过SHA-256散列运行(看起来)相同的字节序列时,得到的结果不同。字节是通过以特定方式操作一个非常大的整数(正好2048位长)生成的(我的Python代码示例的第二行)。在
对于我的示例,原始的2048位整数在Python和Java中分别存储为big_int
和{
我要复制的Python2代码:
raw_big_int = ("%x" % big_int).decode("hex")
buff = struct.pack(">i", len(raw_big_int) + 1) + "\x00" + raw_big_int
pprint("Buffer contains: " + buff)
pprint("Encoded: " + buff.encode("hex").upper())
digest = hashlib.sha256(buff).digest()
pprint("Digest contains: " + digest)
pprint("Encoded: " + digest.encode("hex").upper())
运行此代码将输出以下内容(注意我真正感兴趣的结果是最后一个结果—十六进制编码的摘要。其他3个指纹只是为了看看引擎盖下面发生了什么):
^{pr2}$下面是到目前为止我的Java代码。测试时,输入缓冲区的值相同,摘要的值不同。(bigInt
包含一个BigInteger
对象,该对象与上面Python示例中的big_int
相同)
byte[] rawBigInt = bigInt.toByteArray();
ByteBuffer buff = ByteBuffer.allocate(rawBigInt.length + 4);
buff.order(ByteOrder.BIG_ENDIAN);
buff.putInt(rawBigInt.length).put(rawBigInt);
System.out.print("Buffer contains: ");
System.out.println( DatatypeConverter.printHexBinary(buff.array()) );
MessageDigest hash = MessageDigest.getInstance("SHA-256");
hash.update(buff);
byte[] digest = hash.digest();
System.out.print("Digest contains: ");
System.out.println( DatatypeConverter.printHexBinary(digest) );
注意,在我的Python示例中,我使用len(raw_big_int) + 1
压缩启动缓冲区,而在Java中,我只使用rawBigInt.length
开始。在用Java编写代码时,我还省略了额外的0字节("\x00"
)。我做这两件事的原因是一样的——在我的测试中,对一个BigInteger
调用toByteArray()
返回了一个byte
数组,它已经以一个0字节的开头,比Python的字节序列正好长1个字节。所以,至少在我的测试中,len(raw_big_int) + 1
等于{rawBigInt
以0字节开头,raw_big_int
没有。在
好吧,除此之外,下面是Java代码的输出:
Buffer contains: 0000010100E3BBD3849450FF9C27D050F2F0732C615EF069AC7EEBB95FB06DA226668D7E57A0B3CDF9F0A8A28F8502D4267FFCE8D0F2E27922D084636BC218ADF681B1B07119AB641B3EC82467D7D267E031D472A386222B4E5C8C0AB7711C200CA8BC579B74B0AEFFC38A4780B69A7DD92A9F101414CCC0B6A9182A012F65430E511B5D0AC21F9EB68DBF62C7CE0CA1A382984885A15CB2F127AF6D587C82E7258F0E54AAE4042A91D9F465F78CD6E584A8012A861C788CF0649C4F73EB68BC31D627B1B0CF79D7288BEA496636B4B770CD6763CABB9401B526D74DF99C6FF3108755C36A42333F7676C44A59C93EA36365630186E96381462D1D0FDDBFE8E96BBDE76335
Digest contains: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
如您所见,在Python和Java中,缓冲区内容看起来是相同的,但是摘要明显不同。有人能指出我哪里出错了吗?在
我怀疑这与Python存储字节的奇怪方式有关——变量raw_big_int
和buff
在解释器中显示为str
类型,当它们自己打印出来时,有一种奇怪的格式,带有'\x',几乎与某些地方的字节本身相同,其他人在胡言乱语。我没有足够的Python经验来理解这里到底发生了什么,我的搜索也没有结果。在
另外,由于我正在尝试将Python代码移植到Java中,所以不能只更改Python—我的目标是编写接受相同输入并生成相同输出的Java代码。我到处找了一下(this question似乎特别相关),但没有找到任何可以帮助我的东西。提前感谢你,如果没有别的,只是为了阅读这个冗长的问题!:)
在Java中,数据在缓冲区中,但是光标位置都是错误的。将数据写入ByteBuffer后,如下所示,x表示数据,0是缓冲区中未写入的字节:
光标位于所写数据的后面。此时的read将从},这是您尚未写入的字节。在
position
读取到{相反,您希望:
^{pr2}$其中,位置为0,限制为已写入的字节数。要到达那里,请致电^{} 。翻转缓冲区从概念上将其从写入模式切换到读取模式。我之所以说“概念上的”,是因为bytebuffer没有明确的读写模式,但是你应该把它们当作是有读写模式的。在
(相反的操作是^{} ,它返回到读取模式。)
相关问题 更多 >
编程相关推荐