Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
FNV-1a Hash (http://isthe.com/chongo/tech/comp/fnv/) in JavaScript.
// 32 bit FNV-1a hash
// Ref.: http://isthe.com/chongo/tech/comp/fnv/
function fnv32a( str )
{
var FNV1_32A_INIT = 0x811c9dc5;
var hval = FNV1_32A_INIT;
for ( var i = 0; i < str.length; ++i )
{
hval ^= str.charCodeAt(i);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
return hval >>> 0;
}
/*
print( "Lorem -> " + fnv32a('Lorem') ); // Lorem -> 1789342528
*/
/* for Mac OSX JSC:
$ cat words.txt | /System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc -f fnv32a.js > tmp_js.txt
var line;
while((line = readline()) != "")
{
var re = /\"(.*)\"\,/;
var word = re.exec(line);
print( word[1] + " -> " + fnv32a(word[1]) );
}
*/
@moinism

This comment has been minimized.

Copy link

moinism commented Dec 12, 2013

Really really great

Can we reverse it? I mean get the original string of an FNV hash.

If so, please add that code too.

@ironwallaby

This comment has been minimized.

Copy link

ironwallaby commented Mar 24, 2014

No, that's impossible. A hash function is lossy—that is, it maps many possible values to a smaller number of them. Hence you can never recover the original string.

Anyway, thanks for writing this!

@prdoyle

This comment has been minimized.

Copy link

prdoyle commented Apr 19, 2016

I think you're missing a bit. Don't you need to add hval << 2?

@stuartpb

This comment has been minimized.

Copy link

stuartpb commented Aug 6, 2016

@prdoyle No. The shifts add the components that would be added when the hash is multiplied with the prime - by adding the shifts to the variable containing the hash, the right-most bit (which would be hval << 0, or a multiplication by 1) is incorporated inherently. (hval << 1, in turn, adds the multiplication by the second-rightmost bit's power of 2 (2), and so on, and so forth.)

@max0x7ba

This comment has been minimized.

Copy link

max0x7ba commented Sep 14, 2016

hval ^= str.charCodeAt(i); only works for 8-bit encodings.
Try "Я".charCodeAt(0).

@josiahbryan

This comment has been minimized.

Copy link

josiahbryan commented Sep 25, 2017

@max0x7ba How would you adjust it for non-8-bit encodings?

@erenes

This comment has been minimized.

Copy link

erenes commented Dec 5, 2017

It appears to work for me without problem if I try a Russian string in Firefox (57.0), IE11 and Chrome (64):

fnv32a("Сегодня я банан")
< 3081921716

"Ya" is code 1071 in my browser(s):

"Я".charCodeAt(0)
< 1071

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.