Python中字符串的持久散列

时间:2010-03-24 20:14:17

标签: python

如何将任意字符串转换为唯一的整数,这在Python会话和平台上是相同的?例如,hash('my string')不起作用,因为为每个Python会话和平台返回了不同的值。

5 个答案:

答案 0 :(得分:31)

使用哈希算法(如MD5或SHA1),然后通过hexdigest转换int()

>>> import hashlib
>>> int(hashlib.md5('Hello, world!').hexdigest(), 16)
144653930895353261282233826065192032313L

答案 1 :(得分:8)

如果哈希函数真的不适合你,你可以把字符串变成一个数字。

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'

答案 2 :(得分:3)

以下是我在此处列出的算法的python27实现: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)

答案 3 :(得分:2)

首先,您可能确实希望整数实际上是唯一的。如果您这样做,那么您的号码可能会无限制。如果那真的是你想要的那么你可以使用bignum库并将字符串的位解释为(可能是非常大的)整数的表示。如果你的字符串可以包含\ 0字符,那么你应该在前面添加一个1,这样你可以区分,例如“\ 0 \ 0”来自“\ 0”。

现在,如果你喜欢有限大小的数字,你将使用某种形式的散列。 MD5可以正常工作,但对于规定的目的来说太过分了。我推荐使用sdbm,它工作得很好。在C中它看起来像这样:

static unsigned long sdbm(unsigned char *str)
{
    unsigned long hash = 0;
    int c;

    while (c = *str++)
        hash = c + (hash << 6) + (hash << 16) - hash;

    return hash;
}

http://www.cse.yorku.ca/~oz/hash.html也提供了一些其他哈希函数。

答案 4 :(得分:0)

这是另一种选择,相当粗糙(可能有许多碰撞)并且不太清晰。

它的工作原理是为不同的字符串生成一个int(以及后来的颜色):

aString = "don't panic"
reduce( lambda x,y:x+y, map( lambda x:ord(x[0])*x[1],zip( aString, range( 1, len( aString ) ) ) ) )