我在这里对这个问题进行了详尽的研究:
并且我尝试了各种布局以使其正常工作。
print(merkle(txtHashes))
ha = merkle(txtHashes)
print(ha)
代码来自此处的Python 2.7脚本,如下所示:
import hashlib
# Hash pairs of items recursively until a single value is obtained
def merkle(hashList):
if len(hashList) == 1:
return hashList[0]
newHashList = []
# Process pairs. For odd length, the last is skipped
for i in range(0, len(hashList)-1, 2):
newHashList.append(hash2(hashList[i], hashList[i+1]))
if len(hashList) % 2 == 1: # odd, hash last item twice
newHashList.append(hash2(hashList[-1], hashList[-1]))
return merkle(newHashList)
def hash2(a, b):
# Reverse inputs before and after hashing
# due to big-endian / little-endian nonsense
a1 = a.decode('hex')[::-1]
b1 = b.decode('hex')[::-1]
h = hashlib.sha256(hashlib.sha256(a1+b1).digest()).digest()
return h[::-1].encode('hex')
txtHashes = [
"00baf6626abc2df808da36a518c69f09b0d2ed0a79421ccfde4f559d2e42128b",
"91c5e9f288437262f218c60f986e8bc10fb35ab3b9f6de477ff0eb554da89dea",
"46685c94b82b84fa05b6a0f36de6ff46475520113d5cb8c6fb060e043a0dbc5c"]
print merkle(txtHashes)
这在Python 2.7上有效,即使将底线更改为
,我也无法在Python 3上使用它print(merkle(txtHashes))
给出错误:
Traceback (most recent call last):
File "C:/Python30/MerkleRootTrial.py", line 126, in <module>
print(merkle(txtHashes))
File "C:/Python30/MerkleRootTrial.py", line 10, in merkle
newHashList.append(hash2(hashList[i], hashList[i+1]))
File "C:/Python30/MerkleRootTrial.py", line 18, in hash2
a1 = a.decode('hex')[::-1]
AttributeError: 'str' object has no attribute 'decode'
答案 0 :(得分:2)
在Python 3中,str
和bytes
是不同的类型,而在Python 2中是相同的。在Python 3中,只有bytes
个对象具有decode()
函数,并且只有str
个对象具有encode()
,因此您无法执行a.decode('hex')
,因为a
是str
。
此外,还删除了"hex"
之类的一些(我想是全部?)伪编码(以及"zip"
和"rot13"
等其他一些伪编码),因此您无法转换{{ 1}}和strings
使用bytes
从/到十六进制。相反,您可以使用en/decode()
:
binascii
请注意,import binascii
binascii.hexlify(a) # instead of a.encode("hex")
binascii.unhexlify(a) # instead of a.decode("hex")
仅接受hexlify()
个对象(这才有意义),这两个方法也都返回bytes
个对象,但是您可以转换bytes
到str
以及使用bytes
的另一种方式:
en/decode()
根据您的情况,您需要b"abc".decode() -> "abc"
"abc".encode() -> b"abc"
更改为import binascii
:
hash2
答案 1 :(得分:1)
要添加到benediktwerner的答案中,您还可以使用python 3.x中的以下两种方法将十六进制字符串解码为字节:
import codecs
a1 = codecs.decode(a, 'hex_codec')[::-1]
或者,如果您不想导入:
a1 = bytes.fromhex(a)[::-1]
从这两个示例中,a1的返回值相等。