JavaScript中最快的MD5实现

313

有许多MD5 JavaScript实现可用。是否有人知道哪一个是最先进的、最经过修补的和最快的呢?

我需要它用于这个工具


4
为什么需要“快速”的MD5实现? - AnthonyWJones
12
@AnthonyWJones,是否还需要其他类型的MD5函数?慢速MD5函数似乎并没有实际用途,是吗? - Lee Olayvar
6
加密算法越慢,使用该算法对哈希值进行暴力破解所需的时间就越长。 - Mathias Bynens
58
@MathiasBynens 是的,但是按设计,md5 是一种快速哈希算法。也就是说,它被设计成能够快速处理大量数据并输出哈希值。然而,这恰恰不适合存储安全数据(如密码等),而应该使用更适合的慢哈希算法。与此相反,慢哈希算法从一开始就被设计成缓慢的。在工作负载较大的情况下,暴力破解慢哈希算法并不容易。因此,对于密码来说,慢哈希算法是理想的选择。在许多(或者大多数?)情况下,MD5 对于密码来说不太安全。我不是这个领域的专家,所以请谨慎对待这些内容。 :) - Lee Olayvar
20
是的,但由于有一个规范要求MD5哈希值的样子,所以无论您计算速度快还是慢都无关紧要。最终结果相同,并且破解难度/易度也同样。因此,使用最快的实现方式是有意义的。 - Stijn de Witt
显示剩余6条评论
22个回答

6

3
链接未找到(404)。 - Mechanic

4
我很不满意找不到一个既快速又支持Unicode字符串的实现。因此,我制作了一个支持Unicode字符串的实现,而且在编写时仍然比当前最快的只支持ascii-only-strings实现更快(参见这里): https://github.com/gorhill/yamd5.js 该实现基于Joseph Myers的代码,但使用了TypedArrays和其他改进。

向您致敬。这是迄今为止我发现的唯一一个能够产生与Unix服务器上md5实用程序完全相同哈希值的工具。确实做得很好。 - Jacques

2

js-md5 支持 UTF-8 字符串、数组、ArrayBuffer、AMD 等等...

而且速度快。 jsperf


2

这里是另一个比我的以前的版本快25%的版本:D

function MD5(r) {
var o, e, n, f = [ -680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, -1530992060, 1272893353, -155497632, -1094730640, 681279174, -358537222, -722521979, 76029189, -640364487, -421815835, 530742520, -995338651, -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, -145523070, -1120210379, 718787259, -343485551 ], t = [ o = 1732584193, e = 4023233417, ~o, ~e ], c = [], a = unescape(encodeURI(r)) + "\u0080", d = a.length;
for (r = --d / 4 + 2 | 15, c[--r] = 8 * d; ~d; ) c[d >> 2] |= a.charCodeAt(d) << 8 * d--;
for (i = a = 0; i < r; i += 16) {
    for (d = t; 64 > a; d = [ n = d[3], o + ((n = d[0] + [ o & e | ~o & n, n & o | ~n & e, o ^ e ^ n, e ^ (o | ~n) ][d = a >> 4] + f[a] + ~~c[i | 15 & [ a, 5 * a + 1, 3 * a + 5, 7 * a ][d]]) << (d = [ 7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21 ][4 * d + a++ % 4]) | n >>> -d), o, e ]) o = 0 | d[1], 
    e = d[2];
    for (a = 4; a; ) t[--a] += d[a];
}
for (r = ""; 32 > a; ) r += (t[a >> 3] >> 4 * (1 ^ a++) & 15).toString(16);
return r;
}
<!DOCTYPE html>
<html>
<body onload="md5.value=MD5(a.value);">

<form oninput="md5.value=MD5(a.value)">Enter String:
<input type="string" id="a" name="a" value="https://www.zibri.org"></br></br>MD5:<output id="md5" name="md5" for="a"></output>
</form>

</body>
</html>


1

这是由@dkellner和@Eonasdan实现的md5算法的ES6版本:

const md5 = inputString => {
   const hc = '0123456789abcdef';
   const rh = n => {let j,s='';for(j=0;j<=3;j++) s+=hc.charAt((n>>(j*8+4))&0x0F)+hc.charAt((n>>(j*8))&0x0F);return s;}
   const ad = (x,y) => {let l=(x&0xFFFF)+(y&0xFFFF);let m=(x>>16)+(y>>16)+(l>>16);return (m<<16)|(l&0xFFFF);}
   const rl = (n,c) => (n<<c)|(n>>>(32-c));
   const cm = (q,a,b,x,s,t) => ad(rl(ad(ad(a,q),ad(x,t)),s),b);
   const ff = (a,b,c,d,x,s,t) => cm((b&c)|((~b)&d),a,b,x,s,t);
   const gg = (a,b,c,d,x,s,t) => cm((b&d)|(c&(~d)),a,b,x,s,t);
   const hh = (a,b,c,d,x,s,t) => cm(b^c^d,a,b,x,s,t);
   const ii = (a,b,c,d,x,s,t) => cm(c^(b|(~d)),a,b,x,s,t);
   const sb = x => {
      let i;const nblk=((x.length+8)>>6)+1;const blks=[];for(i=0;i<nblk*16;i++) { blks[i]=0 };
      for(i=0;i<x.length;i++) {blks[i>>2]|=x.charCodeAt(i)<<((i%4)*8);}
      blks[i>>2]|=0x80<<((i%4)*8);blks[nblk*16-2]=x.length*8;return blks;
   }
   let i,x=sb(inputString),a=1732584193,b=-271733879,c=-1732584194,d=271733878,olda,oldb,oldc,oldd;
   for(i=0;i<x.length;i+=16) {olda=a;oldb=b;oldc=c;oldd=d;
      a=ff(a,b,c,d,x[i+ 0], 7, -680876936);d=ff(d,a,b,c,x[i+ 1],12, -389564586);c=ff(c,d,a,b,x[i+ 2],17,  606105819);
      b=ff(b,c,d,a,x[i+ 3],22,-1044525330);a=ff(a,b,c,d,x[i+ 4], 7, -176418897);d=ff(d,a,b,c,x[i+ 5],12, 1200080426);
      c=ff(c,d,a,b,x[i+ 6],17,-1473231341);b=ff(b,c,d,a,x[i+ 7],22,  -45705983);a=ff(a,b,c,d,x[i+ 8], 7, 1770035416);
      d=ff(d,a,b,c,x[i+ 9],12,-1958414417);c=ff(c,d,a,b,x[i+10],17,     -42063);b=ff(b,c,d,a,x[i+11],22,-1990404162);
      a=ff(a,b,c,d,x[i+12], 7, 1804603682);d=ff(d,a,b,c,x[i+13],12,  -40341101);c=ff(c,d,a,b,x[i+14],17,-1502002290);
      b=ff(b,c,d,a,x[i+15],22, 1236535329);a=gg(a,b,c,d,x[i+ 1], 5, -165796510);d=gg(d,a,b,c,x[i+ 6], 9,-1069501632);
      c=gg(c,d,a,b,x[i+11],14,  643717713);b=gg(b,c,d,a,x[i+ 0],20, -373897302);a=gg(a,b,c,d,x[i+ 5], 5, -701558691);
      d=gg(d,a,b,c,x[i+10], 9,   38016083);c=gg(c,d,a,b,x[i+15],14, -660478335);b=gg(b,c,d,a,x[i+ 4],20, -405537848);
      a=gg(a,b,c,d,x[i+ 9], 5,  568446438);d=gg(d,a,b,c,x[i+14], 9,-1019803690);c=gg(c,d,a,b,x[i+ 3],14, -187363961);
      b=gg(b,c,d,a,x[i+ 8],20, 1163531501);a=gg(a,b,c,d,x[i+13], 5,-1444681467);d=gg(d,a,b,c,x[i+ 2], 9,  -51403784);
      c=gg(c,d,a,b,x[i+ 7],14, 1735328473);b=gg(b,c,d,a,x[i+12],20,-1926607734);a=hh(a,b,c,d,x[i+ 5], 4,    -378558);
      d=hh(d,a,b,c,x[i+ 8],11,-2022574463);c=hh(c,d,a,b,x[i+11],16, 1839030562);b=hh(b,c,d,a,x[i+14],23,  -35309556);
      a=hh(a,b,c,d,x[i+ 1], 4,-1530992060);d=hh(d,a,b,c,x[i+ 4],11, 1272893353);c=hh(c,d,a,b,x[i+ 7],16, -155497632);
      b=hh(b,c,d,a,x[i+10],23,-1094730640);a=hh(a,b,c,d,x[i+13], 4,  681279174);d=hh(d,a,b,c,x[i+ 0],11, -358537222);
      c=hh(c,d,a,b,x[i+ 3],16, -722521979);b=hh(b,c,d,a,x[i+ 6],23,   76029189);a=hh(a,b,c,d,x[i+ 9], 4, -640364487);
      d=hh(d,a,b,c,x[i+12],11, -421815835);c=hh(c,d,a,b,x[i+15],16,  530742520);b=hh(b,c,d,a,x[i+ 2],23, -995338651);
      a=ii(a,b,c,d,x[i+ 0], 6, -198630844);d=ii(d,a,b,c,x[i+ 7],10, 1126891415);c=ii(c,d,a,b,x[i+14],15,-1416354905);
      b=ii(b,c,d,a,x[i+ 5],21,  -57434055);a=ii(a,b,c,d,x[i+12], 6, 1700485571);d=ii(d,a,b,c,x[i+ 3],10,-1894986606);
      c=ii(c,d,a,b,x[i+10],15,   -1051523);b=ii(b,c,d,a,x[i+ 1],21,-2054922799);a=ii(a,b,c,d,x[i+ 8], 6, 1873313359);
      d=ii(d,a,b,c,x[i+15],10,  -30611744);c=ii(c,d,a,b,x[i+ 6],15,-1560198380);b=ii(b,c,d,a,x[i+13],21, 1309151649);
      a=ii(a,b,c,d,x[i+ 4], 6, -145523070);d=ii(d,a,b,c,x[i+11],10,-1120210379);c=ii(c,d,a,b,x[i+ 2],15,  718787259);
      b=ii(b,c,d,a,x[i+ 9],21, -343485551);a=ad(a,olda);b=ad(b,oldb);c=ad(c,oldc);d=ad(d,oldd);
   }
   return rh(a)+rh(b)+rh(c)+rh(d);
}

1
也许这个包很有用
https://www.npmjs.com/package/pure-md5

console.time('latin');
const latin = md5('hello');
console.timeEnd('latin');

console.log('Привет: ', md5('Привет'));
console.log('嘿: ', md5('嘿'));
<script src="https://unpkg.com/pure-md5@latest/lib/index.js"></script>


0

0

为什么不试试http://phpjs.org/functions/md5/呢?

不幸的是,使用任何模拟脚本都会受到性能限制,但它可以生成真实的md5哈希。尽管如此,我建议不要将md5用于密码,因为它是一种快速生成的哈希算法。


-1
强烈推荐SparkMD5,它支持多种不同类型的数据获取md5,并在大多数情况下具有良好的性能。与其他md5库相比,它每周的下载量最高。
例如,Blob数据:
import SparkMD5 from 'spark-md5'

export async function computeMd5(data: Blob): Promise<string> {
  const buffer = await readAsArrayBuffer(data)
  const spark = new SparkMD5.ArrayBuffer()
  spark.append(buffer)
  return spark.end()
}

在Chrome v117中,比js-md5更好。

1
根据目前的写法,你的回答不够清晰。请编辑以添加更多细节,帮助其他人理解这如何回答所提出的问题。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - undefined

-3

你也可以查看我的md5实现。它应该与上面发布的其他实现大致相同。不幸的是,性能受到内部循环的限制,无法进一步优化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接