Jenkins Hash的Python实现? [英] Python implementation of Jenkins Hash?

查看:144
本文介绍了Jenkins Hash的Python实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在詹金斯散列算法的本地Python实现?

我需要一个散列算法,它接受一个任意字符串并将其转换为一个32位整数。对于给定的字符串,它必须保证跨平台返回相同的整数。



我查看了ELF哈希算法,我发现了它的一个Python实现。鉴于上述标准,这可能是一个合适的替代品吗? ( http://www.partow.net/programming/hashfunctions/#ELFHashFunction

解决方案

这个本地python代码应该给你与原始lookup3.c相同的散列。

 #需要将U32限制为仅32位,使用& 0xffffffff 
#因为Python没有限制为32位的整数原生概念
#http://docs.python.org/library/stdtypes.html#numeric-types-int-float-long-complex

'''原始版权声明:
作者:Bob Jenkins,1996. bob_jenkins@burtleburtle.net。您可以以任何您希望使用的
代码,私人,教育或商业用途。免费。 (x(x)| <(k))|((x)> | b(b))。 (32-(k))))

def mix(a,b,c):
a& = 0xffffffff; b& = 0xffffffff; c& = 0xffffffff
a - = c; a& = 0xffffffff; a ^ = rot(c,4); a& = 0xffffffff; c + = b; c& = 0xffffffff
b - = a; b& = 0xffffffff; b ^ = rot(a,6); b& = 0xffffffff; a + = c; a& = 0xffffffff
c - = b; c& = 0xffffffff; c ^ = rot(b,8); c& = 0xffffffff; b + = a; b& = 0xffffffff
a - = c; a& = 0xffffffff; a ^ = rot(c,16); a& = 0xffffffff; c + = b; c& = 0xffffffff
b - = a; b& = 0xffffffff; b ^ = rot(a,19); b& = 0xffffffff; a + = c; a& = 0xffffffff
c - = b; c& = 0xffffffff; c ^ = rot(b,4); c& = 0xffffffff; b + = a; b& = 0xffffffff
返回a,b,c

def final(a,b,c):
a& = 0xffffffff; b& = 0xffffffff; c& = 0xffffffff
c ^ = b; c& = 0xffffffff; c - = rot(b,14); c& = 0xffffffff
a ^ = c; a& = 0xffffffff; a - = rot(c,11); a& = 0xffffffff
b ^ = a; b& = 0xffffffff; b - = rot(a,25); b& = 0xffffffff
c ^ = b; c& = 0xffffffff; c - = rot(b,16); c& = 0xffffffff
a ^ = c; a& = 0xffffffff; a - = rot(c,4); a& = 0xffffffff
b ^ = a; b& = 0xffffffff; b - = rot(a,14); b& = 0xffffffff
c ^ = b; c& = 0xffffffff; c - = rot(b,24); c& = 0xffffffff
return a,b,c
$ b $ def hashlittle2(data,initval = 0,initval2 = 0):
length = lenpos = len(data)

a = b = c =(0xdeadbeef +(length)+ initval)

c + = initval2; c& = 0xffffffff

p = 0#字符串偏移
,而lenpos> 12:
a + =(ord(data [p + 0])+(ord(data [p + 1])<8)+ 16)+(ord(data [p + 3])<24)); (ord(data [p + 4])+(ord(data [p + 6]))(< 8)+ ;< 16)+(ord(data [p + 7])<< 24)); b& = 0xffffffff $ bc + =(ord(data [p + 8])+(ord(data [p + 9])←8)+(ord(data [p + 10])< ;< 16)+(ord(data [p + 11])<< 24)); c& = 0xffffffff
a,b,c = mix(a,b,c)
p + = 12
lenpos - = 12

if lenpos == 12 (数据[p + 8])+(ord(数据[p + 8])+(数据[p + ORD(数据[p + 11])<< 24)); (数据[p + 4])+(ord(数据[p + 4])+(ord(数据[p + 5])) (数据[p + 7])<< 24)); (ord(data [p + 0])+(ord(data [p + 2])≤16)+(ord (数据[p + 3])<< 24)); (数据[p + 8])+(ord(数据[p + 9])<< 8)+(ord(数据[p + 10] )<< 16)); (数据[p + 4])+(ord(数据[p + 4])+(ord(数据[p + 5])) (数据[p + 7])<< 24)); (ord(data [p + 0])+(ord(data [p + 2])≤16)+(ord (数据[p + 3])<< 24)); (ord(data [p + 8])+(ord(data [p + 9])<< 8));如果lenpos == 10则为
。 (数据[p + 4])+(ord(数据[p + 4])+(ord(数据[p + 5])) (数据[p + 7])<< 24)); (ord(data [p + 0])+(ord(data [p + 2])≤16)+(ord (数据[p + 3])<< 24));
如果lenpos == 9:c + =(ord(data [p + 8])); (数据[p + 4])+(ord(数据[p + 4])+(ord(数据[p + 5])) (数据[p + 7])<< 24)); (ord(data [p + 0])+(ord(data [p + 2])≤16)+(ord (数据[p + 3])<< 24)); (数据[p + 4])+(ord(数据[p + 5])<< 8)+(ord(数据[p + 6] )< 16< 16)+(ord(data [p + 7])<< 24)); (ord(data [p + 0])+(ord(data [p + 2])≤16)+(ord (数据[p + 3])<< 24)); (数据[p + 4])+(ord(数据[p + 5])<< 8)+(ord(数据[p + 6] )<< 16)); (ord(data [p + 0])+(ord(data [p + 2])≤16)+(ord (数据[p + 3])<< 24)); (数据[p + 5])<< 8)+ ord(数据[p + 4])); bb = (ord(data [p + 0])+(ord(data [p + 2])≤16)+(ord (数据[p + 3])<24))
如果lenpos == 5:b + =(ord(data [p + 4])) (ord(data [p + 0])+(ord(data [p + 2])≤16)+(ord (数据[p + 3])<< 24)); (数据[p + 0])+(ord(数据[p + 1])<< 8)+(ord(数据[p + 2]如果lenpos == 3:a + =(ord(data [p + 0])+(ord(data [p + 3])) (数据[p + 1])<8)+(ord(数据[p + 2])<16))
如果lenpos == 2:a + = (p + 0))+(ord(data [p + 1])<8)) & = 0xffffffff; b& = 0xffffffff; c& = 0xffffffff
如果lenpos == 0:返回c,b

a,b,c = final(a,b,c)

返回c ,b

def hashlittle(data,initval = 0):
c,b = hashlittle2(data,initval,0)
返回c

if __name__ ==__main__:
import sys
hashstr ='Four score and seven years ago'
hash,hash2 = hashlittle2(hashstr,0xdeadbeef,0xdeadbeef)
print' %s:%x%x'%(hashstr,hash,hash2)

hash = hashlittle(hashstr,0)
print'%s:%x'%(hashstr ,散列)


Does there exist a native Python implementation of the Jenkins hash algorithm(s)?

I need a hash algorithm that takes an arbitrary string and turns it into an 32-bit integer. For a given string, it must guarantee to return the same integer across platforms.

I have looked at the ELF hash algorithm, of which I have found a Python implementation. Could this be a suitable replacement given the above criteria? (http://www.partow.net/programming/hashfunctions/#ELFHashFunction)

解决方案

This native python-code should give you the same hash as the original lookup3.c

# Need to constrain U32 to only 32 bits using the & 0xffffffff
# since Python has no native notion of integers limited to 32 bit
# http://docs.python.org/library/stdtypes.html#numeric-types-int-float-long-complex

'''Original copyright notice:
    By Bob Jenkins, 1996.  bob_jenkins@burtleburtle.net.  You may use this
    code any way you wish, private, educational, or commercial.  Its free.
'''

def rot(x,k):
    return (((x)<<(k)) | ((x)>>(32-(k))))

def mix(a, b, c):
    a &= 0xffffffff; b &= 0xffffffff; c &= 0xffffffff
    a -= c; a &= 0xffffffff; a ^= rot(c,4);  a &= 0xffffffff; c += b; c &= 0xffffffff
    b -= a; b &= 0xffffffff; b ^= rot(a,6);  b &= 0xffffffff; a += c; a &= 0xffffffff
    c -= b; c &= 0xffffffff; c ^= rot(b,8);  c &= 0xffffffff; b += a; b &= 0xffffffff
    a -= c; a &= 0xffffffff; a ^= rot(c,16); a &= 0xffffffff; c += b; c &= 0xffffffff
    b -= a; b &= 0xffffffff; b ^= rot(a,19); b &= 0xffffffff; a += c; a &= 0xffffffff
    c -= b; c &= 0xffffffff; c ^= rot(b,4);  c &= 0xffffffff; b += a; b &= 0xffffffff
    return a, b, c

def final(a, b, c):
    a &= 0xffffffff; b &= 0xffffffff; c &= 0xffffffff
    c ^= b; c &= 0xffffffff; c -= rot(b,14); c &= 0xffffffff
    a ^= c; a &= 0xffffffff; a -= rot(c,11); a &= 0xffffffff
    b ^= a; b &= 0xffffffff; b -= rot(a,25); b &= 0xffffffff
    c ^= b; c &= 0xffffffff; c -= rot(b,16); c &= 0xffffffff
    a ^= c; a &= 0xffffffff; a -= rot(c,4);  a &= 0xffffffff
    b ^= a; b &= 0xffffffff; b -= rot(a,14); b &= 0xffffffff
    c ^= b; c &= 0xffffffff; c -= rot(b,24); c &= 0xffffffff
    return a, b, c

def hashlittle2(data, initval = 0, initval2 = 0):
    length = lenpos = len(data)

    a = b = c = (0xdeadbeef + (length) + initval)

    c += initval2; c &= 0xffffffff

    p = 0  # string offset
    while lenpos > 12:
        a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24)); a &= 0xffffffff
        b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); b &= 0xffffffff
        c += (ord(data[p+8]) + (ord(data[p+9])<<8) + (ord(data[p+10])<<16) + (ord(data[p+11])<<24)); c &= 0xffffffff
        a, b, c = mix(a, b, c)
        p += 12
        lenpos -= 12

    if lenpos == 12: c += (ord(data[p+8]) + (ord(data[p+9])<<8) + (ord(data[p+10])<<16) + (ord(data[p+11])<<24)); b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
    if lenpos == 11: c += (ord(data[p+8]) + (ord(data[p+9])<<8) + (ord(data[p+10])<<16)); b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
    if lenpos == 10: c += (ord(data[p+8]) + (ord(data[p+9])<<8)); b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
    if lenpos == 9:  c += (ord(data[p+8])); b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
    if lenpos == 8:  b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16) + (ord(data[p+7])<<24)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
    if lenpos == 7:  b += (ord(data[p+4]) + (ord(data[p+5])<<8) + (ord(data[p+6])<<16)); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
    if lenpos == 6:  b += ((ord(data[p+5])<<8) + ord(data[p+4])); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24))
    if lenpos == 5:  b += (ord(data[p+4])); a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24));
    if lenpos == 4:  a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16) + (ord(data[p+3])<<24))
    if lenpos == 3:  a += (ord(data[p+0]) + (ord(data[p+1])<<8) + (ord(data[p+2])<<16))
    if lenpos == 2:  a += (ord(data[p+0]) + (ord(data[p+1])<<8))
    if lenpos == 1:  a += ord(data[p+0])
    a &= 0xffffffff; b &= 0xffffffff; c &= 0xffffffff
    if lenpos == 0: return c, b

    a, b, c = final(a, b, c)

    return c, b

def hashlittle(data, initval=0):
    c, b = hashlittle2(data, initval, 0)
    return c

if __name__ == "__main__":
    import sys
    hashstr = 'Four score and seven years ago'
    hash, hash2 = hashlittle2(hashstr, 0xdeadbeef, 0xdeadbeef)
    print '"%s": %x %x' % (hashstr, hash, hash2)

    hash = hashlittle(hashstr, 0)
    print '"%s": %x' % (hashstr, hash)

这篇关于Jenkins Hash的Python实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆