处理Python 2.x和3.x中的缓冲区

时间:2014-02-07 05:18:16

标签: python

尝试在Python 2.x和3.x中对文件进行粗略的哈希处理。必须使用此哈希函数 - 不是内置于一个。

使用

get_file_hash("my-file.txt")

3.x有效。 2.x给出错误,因为传入值的类型是'str'。

错误说

    value = content[0] << 7
    TypeError: unsupported operand type(s) for <<: 'str' and 'int'

这是代码

def c_mul(a,b):
    return eval(hex((int(a) * b) & 0xFFFFFFFF)[:-1])

def get_hash(content):
    value = 0
    if len(content) > 0:
        print (type(content))
        print (type(content[0]))
        value = content[0] << 7
        for char in content:
            value = c_mul(1000003, value) ^ char
        value = value ^ len(content)
        if value == -1:
            value = -2
    return value

def get_file_hash(filename):
    with open(filename, "rb") as pyfile:
        return get_hash(pyfile.read())

如何解决get_hash或get_file_hash这样适用于2.x和3.x?

1 个答案:

答案 0 :(得分:4)

file.read()对于以二进制模式打开的文件,在Python 3中返回bytes,在Python 2中返回str(== bytes)。

但是iteratring bytes对象在两个版本中产生不同的结果:

>>> list(b'123') # In Python 3.x, yields `int`s
[49, 50, 51]
>>> list(b'123') # In Python 2.x, yields `string`s
['1', '2', '3']

使用bytearray。迭代它将在两个版本中产生int

>>> list(bytearray(b'123')) # Python 3.x
[49, 50, 51]
>>> list(bytearray(b'123')) # Python 2.x
[49, 50, 51]

def c_mul(a,b):
    return (a * b) & 0xFFFFFFFF

def get_hash(content):
    content = bytearray(content) # <-----
    value = 0
    if len(content) > 0:
        value = content[0] << 7
        for char in content:
            value = c_mul(1000003, value) ^ char
        value = value ^ len(content)
        if value == -1:
            value = -2
    return value

def get_file_hash(filename):
    with open(filename, "rb") as pyfile:
        return get_hash(pyfile.read())

顺便说一句,我修改了c_mul不使用hexeval。 (我假设您使用它来删除Python 2.x中的尾随L

>>> hex(289374982374)
'0x436017d0e6L'
#            ^