Reputation: 4659
I need a very simple hash function in Python that will convert a string to an integer from 0 to 255.
For example:
>>> hash_function("abc_123")
32
>>> hash_function("any-string-value")
99
It does not matter what the integer is as long as I get the same integer every time I call the function.
I want to use the integer to generate a random subnet mask based on the name of the network.
Upvotes: 10
Views: 13524
Reputation: 1121186
You could just use the modulus of the hash()
function output:
def onebyte_hash(s):
return hash(s) % 256
This is what dictionaries and sets use (hash modulus the internal table size).
Demo:
>>> onebyte_hash('abc_123')
182
>>> onebyte_hash('any-string-value')
12
Caveat: On Python 3.3 and up, hash randomisation is enabled by default, and between restarts of Python you'll get different values. The hash, then, is only stable if you don't restart the Python process or set PYTHONHASHSEED
to a fixed decimal number (with 0
disabling it altogether). On Python 2 and 3.0 through to 3.2 hash randomisation is either not available or only enabled if you set a seed explicitly.
Another alternative is to just hashlib.md5()
and just take (integer value of) the first byte:
import hashlib
try:
# Python 2; Python 3 will throw an exception here as bytes are required
hashlib.md5('')
def onebyte_hash(s):
return ord(hashlib.md5(s).digest()[0])
except TypeError:
# Python 3; encode the string first, return first byte
def onebyte_hash(s):
return hashlib.md5(s.encode('utf8')).digest()[0]
MD5 is a well-establish cryptographic hash, the output is stable across Python versions and independent of hash randomisation.
The disadvantage of the latter would be that it'd be marginally slower; Python caches string hashes on the string object, so retrieving the hash later on is fast and cheap most of the time.
Upvotes: 27