Python中的字符串持久哈希
你想把一个任意的字符串转换成一个独特的整数,这个整数在不同的Python会话和平台上都应该是一样的。比如说,使用 hash('my string')
这个方法就不行,因为在每次Python会话和不同的平台上返回的值都不一样。
5 个回答
3
这是我用Python 2.7实现的一些算法,具体可以在这里找到:http://www.cse.yorku.ca/~oz/hash.html。我也不知道这些算法是否高效。
from ctypes import c_ulong
def ulong(i): return c_ulong(i).value # numpy would be better if available
def djb2(L):
"""
h = 5381
for c in L:
h = ((h << 5) + h) + ord(c) # h * 33 + c
return h
"""
return reduce(lambda h,c: ord(c) + ((h << 5) + h), L, 5381)
def djb2_l(L):
return reduce(lambda h,c: ulong(ord(c) + ((h << 5) + h)), L, 5381)
def sdbm(L):
"""
h = 0
for c in L:
h = ord(c) + (h << 6) + (h << 16) - h
return h
"""
return reduce(lambda h,c: ord(c) + (h << 6) + (h << 16) - h, L, 0)
def sdbm_l(L):
return reduce(lambda h,c: ulong(ord(c) + (h << 6) + (h << 16) - h), L, 0)
def loselose(L):
"""
h = 0
for c in L:
h += ord(c);
return h
"""
return sum(ord(c) for c in L)
def loselose_l(L):
return reduce(lambda h,c: ulong(ord(c) + h), L, 0)
50
使用一种哈希算法,比如MD5或SHA1,然后通过 int()
来转换 hexdigest
:
>>> import hashlib
>>> int(hashlib.md5('Hello, world!').hexdigest(), 16)
144653930895353261282233826065192032313L
9
如果哈希函数对你来说真的不合适,你可以把字符串转换成一个数字。
my_string = 'my string'
def string_to_int(s):
ord3 = lambda x : '%.3d' % ord(x)
return int(''.join(map(ord3, s)))
In[10]: string_to_int(my_string)
Out[11]: 109121032115116114105110103L
这个过程是可逆的,也就是说你可以通过 chr
函数将每三个字符映射回去。
def int_to_string(n)
s = str(n)
return ''.join([chr(int(s[i:i+3])) for i in range(0, len(s), 3)])
In[12]: int_to_string(109121032115116114105110103L)
Out[13]: 'my string'