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