尝试在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?
答案 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
不使用hex
,eval
。 (我假设您使用它来删除Python 2.x中的尾随L
。
>>> hex(289374982374)
'0x436017d0e6L'
# ^