偶然发现node支持的hash函数比以前知道的多了很多,把他们都拉出来遛一遛看看大家都速度怎么样:
'use strict';
function murmurhash2_32(str, seed) {
var
l = str.length,
h = seed ^ l,
i = 0,
k;
while (l >= 4) {
k =
((str.charCodeAt(i) & 0xff)) |
((str.charCodeAt(++i) & 0xff) << 8) |
((str.charCodeAt(++i) & 0xff) << 16) |
((str.charCodeAt(++i) & 0xff) << 24);
k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
k ^= k >>> 24;
k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;
l -= 4;
++i;
}
switch (l) {
case 3: h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
case 2: h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
case 1: h ^= (str.charCodeAt(i) & 0xff);
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
}
h ^= h >>> 13;
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
h ^= h >>> 15;
return h >>> 0;
}
function murmurhash3_32(key, seed) {
var remainder, bytes, h1, h1b, c1, c1b, c2, c2b, k1, i;
remainder = key.length & 3; // key.length % 4
bytes = key.length - remainder;
h1 = seed;
c1 = 0xcc9e2d51;
c2 = 0x1b873593;
i = 0;
while (i < bytes) {
k1 =
((key.charCodeAt(i) & 0xff)) |
((key.charCodeAt(++i) & 0xff) << 8) |
((key.charCodeAt(++i) & 0xff) << 16) |
((key.charCodeAt(++i) & 0xff) << 24);
++i;
k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;
h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));
}
k1 = 0;
switch (remainder) {
case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
case 1: k1 ^= (key.charCodeAt(i) & 0xff);
k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
}
h1 ^= key.length;
h1 ^= h1 >>> 16;
h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 13;
h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;
h1 ^= h1 >>> 16;
return h1 >>> 0;
}
const crypto = require("crypto");
const hashs = crypto.getHashes();
var n = 100000,result=[];
for(var h=0;h<hashs.length;h++){
var t = Date.now();
for(var i=0;i<n;i++){
crypto.createHash(hashs[h]).update("abcdefghijklmnopqrstuvwxyz0123456789","ascii");
}
result.push([hashs[h] , (Date.now()-t)]);
}
var t = Date.now();
for(var i=0;i<n;i++){
murmurhash3_32("abcdefghijklmnopqrstuvwxyz0123456789","ascii",12);
}
result.push(["murmurhash3_32" , (Date.now()-t)]);
var t = Date.now();
for(var i=0;i<n;i++){
murmurhash3_32("abcdefghijklmnopqrstuvwxyz0123456789","ascii",12).toString(16)+murmurhash3_32("abcdefghijklmnopqrstuvwxyz0123456789","ascii",123).toString(16);
}
result.push(["murmurhash3_32_twice" , (Date.now()-t)]);
result.sort((a,b)=>a[1]-b[1])
console.log(result.join("\n"))
因为digest的时候会产生转string的计算,这样对于哈希结果比较长的算法不公平,因此测试的时候只做update没有做digest。
结果系统内置的hash算法里面md4/md5 基本都能保持在最快,其他的差距其实也都很小。一般md5也就够用了。
而murmurhash算法虽然没有系统内置的算法加速,但是速度却快得多。当然算出的结果也比较短,抗冲突性差的多,需要的时候可以用两轮murmurhash来提升抗冲突性,性能上仍然能内置算法的性能更高。
murmurhash3_32,21
murmurhash3_32_twice,50
md5,103
md4,104
ripemd160,106
sha256,107
blake2s256,108
sha224,109
sha512-224,110
ssl3-md5,110
sm3,111
md5-sha1,112
whirlpool,112
sha384,113
RSA-SHA256,115
blake2b512,115
ripemd,115
sha512-256,115
ssl3-sha1,115
RSA-RIPEMD160,116
RSA-SHA1,116
md4WithRSAEncryption,116
ripemd160WithRSA,117
RSA-MD5,120
RSA-SHA1-2,121
sha1WithRSAEncryption,121
sha256WithRSAEncryption,121
sha512,121
RSA-SM3,122
sm3WithRSAEncryption,122
sha3-224,123
RSA-SHA224,124
rmd160,125
sha512-224WithRSAEncryption,125
sha512WithRSAEncryption,125
md5WithRSAEncryption,126
sha384WithRSAEncryption,126
sha512-256WithRSAEncryption,126
sha3-512,127
sha224WithRSAEncryption,128
shake128,129
RSA-SHA512,132
sha3-384,132
RSA-SHA384,134
RSA-SHA512/256,135
sha3-256,136
shake256,137
RSA-SHA512/224,138
RSA-SHA3-256,139
RSA-SHA3-224,142
RSA-SHA3-512,145
id-rsassa-pkcs1-v1_5-with-sha3-224,146
id-rsassa-pkcs1-v1_5-with-sha3-256,146
id-rsassa-pkcs1-v1_5-with-sha3-384,147
id-rsassa-pkcs1-v1_5-with-sha3-512,151
RSA-SHA3-384,152
RSA-MD4,160
sha1,180
mdc2,275
mdc2WithRSA,291
RSA-MDC2,305