Python中的字符串持久哈希

40 投票
5 回答
21667 浏览
提问于 2025-04-15 20:49

你想把一个任意的字符串转换成一个独特的整数,这个整数在不同的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'

撰写回答