在java中一個(gè)hashCode算法,可以用來計(jì)算一個(gè)字符串的hash值,今天一個(gè)朋友突然問俺能不能在js中計(jì)算hashCode,要求和java的hashCode計(jì)算結(jié)果一樣。
對于java的hashCode,以前到現(xiàn)在也一直沒有了解過其算法,不過猜想應(yīng)該也不會(huì)太難,于是現(xiàn)在java中寫了這段代碼進(jìn)行測試:
運(yùn)行結(jié)果:899755
按下Ctrl鍵點(diǎn)擊hashCode方法名跟進(jìn)去看了下其算法,發(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; } |
這下好,簡單移植過去到j(luò)s里就應(yīng)該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> |
運(yùn)行結(jié)果:899755
OK,與java計(jì)算結(jié)果一樣。本以為這么就搞定了,然后想著再隨便找個(gè)串測試下:
“沈陽沈陽啊”,在JAVA中運(yùn)行結(jié)果為:1062711668,然而到j(luò)s中成了:26832515444。
狂暈,這隨便一試就有問題了!后思考片刻,突然想到Java中int長度好像是21億左右,js中就沒這限制了。問題應(yīng)該就是在這里了,于是對之前的方法做了一點(diǎn)改造:
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!大功告成。沒有什么技術(shù)含量,一點(diǎn)小總結(jié)
2013-02-19更新,上面那個(gè)效率比較低下,當(dāng)內(nèi)容很長的時(shí)候會(huì)當(dāng)?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#同一時(shí)間N個(gè)線程在并發(fā)執(zhí)行,其余在隊(duì)列中如何實(shí)現(xiàn)' )); //1107373715 </script> |
看過外人寫的
Javascript implementation of Java's String.hashCode() method 21
這里是Java的直接替代品字符串.hashCode()用Javascript實(shí)現(xiàn)的方法。
我編寫這個(gè)函數(shù)是為了滿足工作中的一個(gè)需求。顯然,后端工程師認(rèn)為hashCode()是一個(gè)標(biāo)準(zhǔn)函數(shù)。這個(gè)項(xiàng)目的一個(gè)障礙不僅是如何翻譯Java中用來生成hashCode()的數(shù)學(xué)公式,還包括如何強(qiáng)制Javascript使用32位整數(shù)數(shù)學(xué)(這不是一個(gè)小的壯舉)。
幸運(yùn)的是,我發(fā)現(xiàn)Java支持位運(yùn)算符,這些運(yùn)算符被限制在32位整數(shù)數(shù)學(xué)中。
下面是Javascript生成的字符串原型。使用這個(gè)原型,您可以簡單地對任何字符串調(diào)用.hashCode(),例如“some string”.hashCode(),并接收一個(gè)數(shù)字哈希代碼(更具體地說,是一個(gè)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; } |
另外分享一個(gè)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中實(shí)現(xiàn)兼容JAVA的hashCode算法代碼分享的詳細(xì)內(nèi)容,更多關(guān)于javascript兼容JAVA的hashCode算法的資料請關(guān)注服務(wù)器之家其它相關(guān)文章!