在java中一個hashCode算法,可以用來計算一個字符串的hash值,今天一個朋友突然問俺能不能在js中計算hashCode,要求和java的hashCode計算結果一樣。
對于java的hashCode,以前到現(xiàn)在也一直沒有了解過其算法,不過猜想應該也不會太難,于是現(xiàn)在java中寫了這段代碼進行測試:
運行結果:899755
按下Ctrl鍵點擊hashCode方法名跟進去看了下其算法,發(fā)現(xiàn)是很簡單的幾句代碼,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public int hashCode() { int h = hash; if (h == 0) { int off = offset; char val[] = value; int len = count; for (int i = 0; i < len; i++) { h = 31*h + val[off++]; } hash = h; } return h; } |
這下好,簡單移植過去到js里就應該ok了。于是寫出如下JS代碼:
1
2
3
4
5
6
7
8
9
10
11
|
function hashCode(str){ var h = 0, off = 0; var len = str.length; for ( var i = 0; i < len; i++){ h = 31 * h + str.charCodeAt(off++); } return h; } alert(hashCode( '沈陽' )); </script> |
運行結果:899755
OK,與java計算結果一樣。本以為這么就搞定了,然后想著再隨便找個串測試下:
“沈陽沈陽啊”,在JAVA中運行結果為:1062711668,然而到js中成了:26832515444。
狂暈,這隨便一試就有問題了!后思考片刻,突然想到Java中int長度好像是21億左右,js中就沒這限制了。問題應該就是在這里了,于是對之前的方法做了一點改造:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<script> function hashCode(str){ var h = 0, off = 0; var len = str.length; for ( var i = 0; i < len; i++){ h = 31 * h + str.charCodeAt(off++); } var t=-2147483648*2; while (h>2147483647){ h+=t } return h; } alert(hashCode( '沈陽沈陽啊' )); </script> |
再次測試!OK!大功告成。沒有什么技術含量,一點小總結
2013-02-19更新,上面那個效率比較低下,當內(nèi)容很長的時候會當?shù)簦旅娴拇a是優(yōu)化后的代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<script> function hashCode(str) { var h = 0; var len = str.length; var t = 2147483648; for ( var i = 0; i < len; i++) { h = 31 * h + str.charCodeAt(i); if (h > 2147483647) h %= t; //java int溢出則取模 } /*var t = -2147483648 * 2; while (h > 2147483647) { h += t }*/ return h; } alert(hashCode( 'C#同一時間N個線程在并發(fā)執(zhí)行,其余在隊列中如何實現(xiàn)' )); //1107373715 </script> |
看過外人寫的
Javascript implementation of Java's String.hashCode() method 21
這里是Java的直接替代品字符串.hashCode()用Javascript實現(xiàn)的方法。
我編寫這個函數(shù)是為了滿足工作中的一個需求。顯然,后端工程師認為hashCode()是一個標準函數(shù)。這個項目的一個障礙不僅是如何翻譯Java中用來生成hashCode()的數(shù)學公式,還包括如何強制Javascript使用32位整數(shù)數(shù)學(這不是一個小的壯舉)。
幸運的是,我發(fā)現(xiàn)Java支持位運算符,這些運算符被限制在32位整數(shù)數(shù)學中。
下面是Javascript生成的字符串原型。使用這個原型,您可以簡單地對任何字符串調(diào)用.hashCode(),例如“some string”.hashCode(),并接收一個數(shù)字哈希代碼(更具體地說,是一個Java等效代碼),如1395333309。
1
2
3
4
5
6
7
8
9
10
|
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; } |
另外分享一個phpcom中用的函數(shù)
1
|
String.prototype.hashCode = function () { for ( var a = 31,b = 0,c = this .length; b < c;) a ^= (a << 5) + (a >> 2) + this .charCodeAt(b++); return a}; |
以上就是javascript中實現(xiàn)兼容JAVA的hashCode算法代碼分享的詳細內(nèi)容,更多關于javascript兼容JAVA的hashCode算法的資料請關注服務器之家其它相關文章!