I need to convert strings to some form of hash. Is this possible in JavaScript?
I'm not utilizing a server-side language so I can't do it that way.
I need to convert strings to some form of hash. Is this possible in JavaScript?
I'm not utilizing a server-side language so I can't do it that way.
Based on accepted answer in ES6. Smaller, maintainable and works in modern browsers.
EDIT
based on my jsperf tests, the accepted answer is actually faster: http://jsperf.com/hashcodelordvlad
ORIGINAL
if anyone is interested, here is an improved ( faster ) version, which will fail on older browsers who lack the
reduce
array function.My quick (very long) one liner based on FNV's
Multiply+Xor
method:I'm a bit surprised nobody has talked about the new SubtleCrypto API yet.
To get an hash from a string, you can use the
subtle.digest
method :Here's a simple, well-distributed 53-bit hash. It's quite fast and has low collision rates.
It uses techniques similar to xxHash/MurmurHash, but not as thorough. It achieves avalanche (non-strict), so small changes in the input have big changes in the output, making it appear random:
53-bits is the limit of JS integers, and has significantly less collision chance than 32-bit hashes. But If 53 bits isn't enough for you, you can still use all 64 bits by constructing a hex string or array:
The catch is, constructing the hex string becomes the bottleneck on performance, and the array needs two comparison operators instead of one, which isn't as convenient.
Note: Even with the best 32-bit hash, you will have to deal with the fact that collisions will occur sooner or later. I.e. two different input strings will return the same hash value with a probability of at least 1 : 2^32.
In an answer to this question Which hashing algorithm is best for uniqueness and speed?, Ian Boyd posted a good in depth analysis. In short (as I interpret it), he comes to the conclusion that Murmur is best, followed by FNV-1a.
Java’s String.hashCode() algorithm that esmiralha proposed seems to be a variant of DJB2.
Some benchmarks with large input strings here: http://jsperf.com/32-bit-hash
When short input strings are hashed, murmur's performance drops, relative to DJ2B and FNV-1a: http://jsperf.com/32-bit-hash/3
So in general I would recommend murmur3.
See here for a JavaScript implementation: https://github.com/garycourt/murmurhash-js
If input strings are short and performance is more important than distribution quality, use DJB2 (as proposed by the accepted answer by esmiralha).
If quality and small code size are more important than speed, I use this implementation of FNV-1a (based on this code).