Here is a direct replacement for Java’s String.hashCode() method implemented in Javascript.
I wrote this function to fulfill a requirement at work. Apparently, the back-end engineers thought hashCode() was a standard function. One of the hurdles for this project was not only figuring out how to translate the mathematical formula used in Java to generate hashCode()’s but also how to force Javascript to use 32bit integer math (no small feat).
Fortunately, I discovered that Java supports bitwise operators which are constrained to 32bit integer math.
So here’s the resulting String prototype in Javascript. With this prototype you can simply call .hashCode() on any string, ie. “some string”.hashCode(), and receive a numerical hash code (more specifically, a Java equivalent) such as 1395333309.
String.prototype.hashCode = function(){
var hash = 0;
if (this.length == 0) return hash;
for (i = 0; i < this.length; i++) {
char = this.charCodeAt(i);
hash = ((hash<<5)-hash)+char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}


#1 by David on June 23, 2010 - 2:15 pm
Quote
A left shift would be faster than a multiply.
The length better be low enough that 31^length < 2^31.
#2 by Bora on February 22, 2011 - 11:33 am
Quote
The length should be approx. less than 10 characters, or it reaches maxint boundaries and shifts to a minus integer.
Java must handle this some other way.
#3 by James on May 27, 2011 - 6:47 am
Quote
code is undefined, not 0
declare your variables properly and you won’t get such bugs
#4 by Chris on June 1, 2011 - 11:04 am
Quote
I’m guessing this line
if (this.length == 0) return code;
Is meant to be
if (this.length == 0) return hash;
As you have no variable ‘code’ anywhere. And agree about the shift operations, usually a lot quicker than multiplies..
#5 by wes on June 1, 2011 - 2:20 pm
Quote
You’re right, that should be hash instead of code.
As for the negative numbers produced by long strings, that is desired behavior because Java calculates hashCodes in 32bit.
I’ve also updated the post to use a left shift.
#6 by mileusna on February 2, 2012 - 12:55 pm
Quote
I get negative hash with some strings. Is that OK? How can I make it positive in all cases?
#7 by wes on February 2, 2012 - 1:26 pm
Quote
Yes, this function was modeled on Java’s hashCode function: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#hashCode()
..which uses Java’s int data type which, being 32bit, means that large results will be negative:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html