函数给出错误的python 3打印结果

时间:2019-02-20 15:50:32

标签: python-3.x

我在这里对这个问题进行了详尽的研究:

并且我尝试了各种布局以使其正常工作。

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'

2 个答案:

答案 0 :(得分:2)

在Python 3中,strbytes是不同的类型,而在Python 2中是相同的。在Python 3中,只有bytes个对象具有decode()函数,并且只有str个对象具有encode(),因此您无法执行a.decode('hex'),因为astr

此外,还删除了"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个对象,但是您可以转换bytesstr以及使用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的返回值相等。