您如何将任意字符串转换为唯一的整数,使其在Python会话和平台之间保持一致?例如
hash('my string')
不可行,因为每个Python会话和平台都会返回不同的值。hash('my string')
不可行,因为每个Python会话和平台都会返回不同的值。使用哈希算法,例如MD5或SHA1,然后通过int()
将hexdigest
转换:
>>> import hashlib
>>> int(hashlib.md5('Hello, world!').hexdigest(), 16)
144653930895353261282233826065192032313L
int(hashlib.md5('Hello, world!').hexdigest()[:8], 16)
将会小于 2^32, int(hashlib.md5('Hello, world!').hexdigest()[:16], 16)
将会小于 2^64。 - PeterTypeError: Unicode-objects must be encoded before hashing
的错误提示,那么你需要对字符串进行编码,例如:int(hashlib.md5('Hello, world!'.encode('utf-8')).hexdigest(), 16)
。 - Dylan Hoggmy_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'
这里是我对http://www.cse.yorku.ca/~oz/hash.html中列出的算法的Python27实现。
不确定它们是否高效。
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)
首先,你可能并不真的想要整数实际上是唯一的。如果是这样的话,你的数字可能是无限大小的。如果确实是你想要的,那么你可以使用一个大整数库,并将字符串的位解释为(潜在非常大的)整数的表示形式。如果你的字符串可以包含\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还提供了一些其他的哈希函数。
这里还有另一个选项,相当粗糙(可能有很多冲突),并且不太可读。
它对于生成不同字符串的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 ) ) ) ) )