-
-
Save amakukha/7854a3e910cb5866b53bf4b2af1af968 to your computer and use it in GitHub Desktop.
DJB2 Hash in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Proper (fast) Python implementations of Dan Bernstein's DJB2 32-bit hashing function | |
# | |
# DJB2 has terrible avalanching performance, though. | |
# For example, it returns the same hash values for these strings: "xy", "yX", "z7". | |
# I recommend using Murmur3 hash. Or, at least, FNV-1a or SDBM hashes below. | |
import functools | |
djb2 = lambda x: functools.reduce(lambda x,c: 0xFFFFFFFF & (x*33 + c), x, 5381) | |
sdbm = lambda x: functools.reduce(lambda x,c: 0xFFFFFFFF & (x*65599 + c), x, 0) | |
fnv1a_32 = lambda x: functools.reduce(lambda x,c: 0xFFFFFFFF & ((x^c)*0x1000193), x, 0x811c9dc5) | |
hex(djb2(b'hello, world')) == '0xb0e4250d' | |
hex(sdbm(b'hello, world')) == '0xee6fb30c' | |
hex(fnv1a_32(b'hello, world')) == '0x4d0ea41d' | |
# ...Versions for strings with regular functions | |
def hash_djb2(s): | |
hash = 5381 | |
for x in s: | |
hash = ((( hash << 5) + hash) + ord(x)) & 0xFFFFFFFF | |
return hash | |
def hash_sdbm(s): | |
hash = 0 | |
for x in s: | |
hash = ((hash << 16) + (hash << 6) + ord(x) - hash) & 0xFFFFFFFF | |
return hash | |
def hash_fnv1a_32(s): | |
hash = 0x811c9dc5 | |
for x in s: | |
hash = ((ord(x) ^ hash) * 0x01000193) & 0xFFFFFFFF | |
return hash | |
hex(hash_djb2(u'hello world, 世界')) == '0xa6bd702f' | |
hex(hash_sdbm(u'Åland Islands')) == '0x5f5ba0ee' | |
hex(hash_fnv1a_32(u'Świętosław')) == '0x16cf4524' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You don't need
itertools.chain
, since you have optionalinitial
value infunctools.reduce
.