Implementación MD5 más rápida en JavaScript

236

Hay muchas implementaciones de JavaScript MD5 por ahí. ¿Alguien sabe cuál es el más avanzado, el más corregido y el más rápido?

Lo necesito para esta herramienta.

Powtac
fuente
2
¿Por qué necesita una implementación MD5 "rápida"?
AnthonyWJones
3
@AnthonyWJones ¿hay alguna necesidad de otro tipo de función md5? No es que una función md5 "lenta" realmente sirva para ningún propósito ... ¿o sí?
Lee Olayvar
55
@LeeOlayvar Cuanto más lenta es una función de criptografía, más tiempo se necesitaría para aplicar fuerza bruta a un hash determinado usando esa función.
Mathias Bynens,
45
@MathiasBynens Sí, pero por diseño, md5 es un hash rápido. Es decir, está diseñado para consumir grandes cantidades de datos y generar un hash muy, muy rápido. Esto es esencialmente lo último que desea para almacenar datos seguros, como contraseñas, etc., y es más adecuado / diseñado para identificar datos. Los hash lentos, por otro lado, están diseñados para ser lentos desde cero. Bruto forzar un hash lento, con un gran valor de trabajo, no es una tarea fácil. Como tal, los hash lentos son ideales para contraseñas. MD5 es malo para las contraseñas en muchos (¿la mayoría?). No soy un experto en este campo, así que tómalo con sal. :)
Lee Olayvar
16
Sí, pero como hay una especificación que exige el aspecto de un hash MD5, no importa si lo calcula de forma rápida o lenta. El resultado final es el mismo y será igualmente difícil / fácil de aplicar fuerza bruta. Por lo tanto, tiene sentido usar la implementación más rápida.
Stijn de Witt

Respuestas:

168

Escuché que la implementación de Joseph's Myers es bastante rápida. Además, tiene un extenso artículo sobre la optimización de Javascript que describe lo que aprendió al escribir su implementación. Es una buena lectura para cualquier persona interesada en el rendimiento de JavaScript.

http://www.webreference.com/programming/javascript/jkm3/

Su implementación MD5 se puede encontrar aquí

Matt Baker
fuente
124
"Para hacer mi código JavaScript MD5 más rápido que el de todos los demás, tuve que aprovechar las variables de función local". ¡Qué gran avance!
Glenn Maynard
11
Puede encontrar una demostración de esta biblioteca md5 aquí: jsfiddle.net/v28gq
Anderson Green
15
¿Cuál es la licencia para el código de Myers? Él no indica que tenga licencia (o no) en su sitio web por lo que puedo decir.
JeroenHoek
25
Me molesta que esta implementación cree un montón de funciones globales, así que envolví todo en un cierre, hice que cada función sea una variable y asigné la función md5 al objeto de la ventana. Obviamente, esto supone que hay un objeto de ventana, pero mantendrá privadas todas las funciones de soporte. No estoy seguro de cómo (si es que lo hace) afectará el rendimiento, pero debería ser mucho más seguro para su uso en aplicaciones grandes. gist.github.com/jhoff/7680711
jhoff
66
@jhoff Your Gist se ha bifurcado y mejorado un par de veces, también creo que la var add32línea 185 debería ser solo add32para encontrar la mejor bifurcación que pude y actualizarla a esta nueva versión: gist.github.com/MichaelPote/3f0cefaaa9578d7e30be
Mikepote
73

Te sugiero que uses CryptoJS en este caso.

Básicamente, CryptoJS es una colección creciente de algoritmos criptográficos estándar y seguros implementados en JavaScript utilizando las mejores prácticas y patrones. Son rápidos y tienen una interfaz consistente y simple.

Entonces, si desea calcular el hash MD5 de su cadena de contraseña, haga lo siguiente:

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/md5.js"></script>
<script>
    var passhash = CryptoJS.MD5(password).toString();

    $.post(
      'includes/login.php', 
      { user: username, pass: passhash },
      onLogin, 
      'json' );
</script>

Entonces, este script publicará el hash de su cadena de contraseña en el servidor.

Para obtener más información y asistencia sobre otros algoritmos de cálculo de hash, puede visitar:

http://code.google.com/p/crypto-js/

theCodeMachine
fuente
59
No debe usar md5 para contraseñas.
Lukas Liesis
3
Parece que esto quedará huérfano en poco tiempo, todavía en "google code". ¿Nadie lo mantiene?
MrYellow
2
md5 es rápido y si alguien descifra su sitio y su código de base de datos se filtra, siempre puede generar db con hashes y decodificar contraseñas. Dame tu base de datos en vivo con 10 millones de usuarios y código. Me divertiré con eso y publicaré en Internet mis resultados decodificados. Salud.
Lukas Liesis
2
El enlace lleva a una página 404 ahora
Adam F
29

Al seleccionar la biblioteca, también es importante ver si es compatible con marcos modernos como Bower, pasa jslint, es compatible con el modelo de complemento para JQuery o sistemas de módulos como AMD / RequireJS, además de estar en desarrollo activo y tener más de 1 contribuyentes. Hay un par de opciones que satisfacen algunos o todos estos criterios adicionales:

  • CryptoJS : esta es quizás la biblioteca más amplia donde cada algoritmo se puede usar por separado sin agregar grasa a su código JS. Además, como codificador / decodificador para UTF8, UTF16 y Base64. Mantengo repositorio GitHub que está registrado como paquete de Bower más instrucciones sobre cómo usarlo con RequireJS.
  • Spark MD5 : Esto se basa en el código JKM que otra respuesta menciona, que también es la implementación más rápida. Sin embargo, además, la implementación de Spark agrega soporte AMD, pasa jslint plus tiene modo incremental. No tiene Base64 o / p pero sí tiene o / p sin procesar (es decir, matriz de 32 bits int insead de cadena).
  • Complemento JQuery MD5 : muy simple, pero no parece tener modo sin formato.
  • JavaScript-MD5 : no es tan elegante o rápido como Spark, pero es más simple.

Ejemplo de CryptoJS:

//just include md5.js from the CryptoJS rollups folder
var hash = CryptoJS.MD5("Message");
console.log(hash.toString()); 

Hay una comparación de rendimiento entre las bibliotecas anteriores en http://jsperf.com/md5-shootout/7 . En mi máquina, las pruebas actuales (que son ciertamente antiguas) muestran que si está buscando velocidad, Spark MD5 es su mejor opción (y también lo es el código JKM simple). Sin embargo, si busca una biblioteca más completa, CryptoJS es su mejor opción, aunque es un 79% más lenta que Spark MD5. Sin embargo, me imagino que CryptoJS eventualmente alcanzará la misma velocidad, ya que es un proyecto un poco más activo.

Shital Shah
fuente
El enlace al "complemento jQuery MD5" me lleva a un sitio de malware. Eep!
Raffi
1
Parece que el sitio web original del complemento jQuery MD5 se cerró y ahora se redirige al vendedor de dominio genérico. He actualizado al complemento alojado en GitHub ahora.
Shital Shah
14

MD5 = function(e) {
    function h(a, b) {
        var c, d, e, f, g;
        e = a & 2147483648;
        f = b & 2147483648;
        c = a & 1073741824;
        d = b & 1073741824;
        g = (a & 1073741823) + (b & 1073741823);
        return c & d ? g ^ 2147483648 ^ e ^ f : c | d ? g & 1073741824 ? g ^ 3221225472 ^ e ^ f : g ^ 1073741824 ^ e ^ f : g ^ e ^ f
    }

    function k(a, b, c, d, e, f, g) {
        a = h(a, h(h(b & c | ~b & d, e), g));
        return h(a << f | a >>> 32 - f, b)
    }

    function l(a, b, c, d, e, f, g) {
        a = h(a, h(h(b & d | c & ~d, e), g));
        return h(a << f | a >>> 32 - f, b)
    }

    function m(a, b, d, c, e, f, g) {
        a = h(a, h(h(b ^ d ^ c, e), g));
        return h(a << f | a >>> 32 - f, b)
    }

    function n(a, b, d, c, e, f, g) {
        a = h(a, h(h(d ^ (b | ~c), e), g));
        return h(a << f | a >>> 32 - f, b)
    }

    function p(a) {
        var b = "",
            d = "",
            c;
        for (c = 0; 3 >= c; c++) d = a >>> 8 * c & 255, d = "0" + d.toString(16), b += d.substr(d.length - 2, 2);
        return b
    }
    var f = [],
        q, r, s, t, a, b, c, d;
    e = function(a) {
        a = a.replace(/\r\n/g, "\n");
        for (var b = "", d = 0; d < a.length; d++) {
            var c = a.charCodeAt(d);
            128 > c ? b += String.fromCharCode(c) : (127 < c && 2048 > c ? b += String.fromCharCode(c >> 6 | 192) : (b += String.fromCharCode(c >> 12 | 224), b += String.fromCharCode(c >> 6 & 63 | 128)), b += String.fromCharCode(c & 63 | 128))
        }
        return b
    }(e);
    f = function(b) {
        var a, c = b.length;
        a = c + 8;
        for (var d = 16 * ((a - a % 64) / 64 + 1), e = Array(d - 1), f = 0, g = 0; g < c;) a = (g - g % 4) / 4, f = g % 4 * 8, e[a] |= b.charCodeAt(g) << f, g++;
        a = (g - g % 4) / 4;
        e[a] |= 128 << g % 4 * 8;
        e[d - 2] = c << 3;
        e[d - 1] = c >>> 29;
        return e
    }(e);
    a = 1732584193;
    b = 4023233417;
    c = 2562383102;
    d = 271733878;
    for (e = 0; e < f.length; e += 16) q = a, r = b, s = c, t = d, a = k(a, b, c, d, f[e + 0], 7, 3614090360), d = k(d, a, b, c, f[e + 1], 12, 3905402710), c = k(c, d, a, b, f[e + 2], 17, 606105819), b = k(b, c, d, a, f[e + 3], 22, 3250441966), a = k(a, b, c, d, f[e + 4], 7, 4118548399), d = k(d, a, b, c, f[e + 5], 12, 1200080426), c = k(c, d, a, b, f[e + 6], 17, 2821735955), b = k(b, c, d, a, f[e + 7], 22, 4249261313), a = k(a, b, c, d, f[e + 8], 7, 1770035416), d = k(d, a, b, c, f[e + 9], 12, 2336552879), c = k(c, d, a, b, f[e + 10], 17, 4294925233), b = k(b, c, d, a, f[e + 11], 22, 2304563134), a = k(a, b, c, d, f[e + 12], 7, 1804603682), d = k(d, a, b, c, f[e + 13], 12, 4254626195), c = k(c, d, a, b, f[e + 14], 17, 2792965006), b = k(b, c, d, a, f[e + 15], 22, 1236535329), a = l(a, b, c, d, f[e + 1], 5, 4129170786), d = l(d, a, b, c, f[e + 6], 9, 3225465664), c = l(c, d, a, b, f[e + 11], 14, 643717713), b = l(b, c, d, a, f[e + 0], 20, 3921069994), a = l(a, b, c, d, f[e + 5], 5, 3593408605), d = l(d, a, b, c, f[e + 10], 9, 38016083), c = l(c, d, a, b, f[e + 15], 14, 3634488961), b = l(b, c, d, a, f[e + 4], 20, 3889429448), a = l(a, b, c, d, f[e + 9], 5, 568446438), d = l(d, a, b, c, f[e + 14], 9, 3275163606), c = l(c, d, a, b, f[e + 3], 14, 4107603335), b = l(b, c, d, a, f[e + 8], 20, 1163531501), a = l(a, b, c, d, f[e + 13], 5, 2850285829), d = l(d, a, b, c, f[e + 2], 9, 4243563512), c = l(c, d, a, b, f[e + 7], 14, 1735328473), b = l(b, c, d, a, f[e + 12], 20, 2368359562), a = m(a, b, c, d, f[e + 5], 4, 4294588738), d = m(d, a, b, c, f[e + 8], 11, 2272392833), c = m(c, d, a, b, f[e + 11], 16, 1839030562), b = m(b, c, d, a, f[e + 14], 23, 4259657740), a = m(a, b, c, d, f[e + 1], 4, 2763975236), d = m(d, a, b, c, f[e + 4], 11, 1272893353), c = m(c, d, a, b, f[e + 7], 16, 4139469664), b = m(b, c, d, a, f[e + 10], 23, 3200236656), a = m(a, b, c, d, f[e + 13], 4, 681279174), d = m(d, a, b, c, f[e + 0], 11, 3936430074), c = m(c, d, a, b, f[e + 3], 16, 3572445317), b = m(b, c, d, a, f[e + 6], 23, 76029189), a = m(a, b, c, d, f[e + 9], 4, 3654602809), d = m(d, a, b, c, f[e + 12], 11, 3873151461), c = m(c, d, a, b, f[e + 15], 16, 530742520), b = m(b, c, d, a, f[e + 2], 23, 3299628645), a = n(a, b, c, d, f[e + 0], 6, 4096336452), d = n(d, a, b, c, f[e + 7], 10, 1126891415), c = n(c, d, a, b, f[e + 14], 15, 2878612391), b = n(b, c, d, a, f[e + 5], 21, 4237533241), a = n(a, b, c, d, f[e + 12], 6, 1700485571), d = n(d, a, b, c, f[e + 3], 10, 2399980690), c = n(c, d, a, b, f[e + 10], 15, 4293915773), b = n(b, c, d, a, f[e + 1], 21, 2240044497), a = n(a, b, c, d, f[e + 8], 6, 1873313359), d = n(d, a, b, c, f[e + 15], 10, 4264355552), c = n(c, d, a, b, f[e + 6], 15, 2734768916), b = n(b, c, d, a, f[e + 13], 21, 1309151649), a = n(a, b, c, d, f[e + 4], 6, 4149444226), d = n(d, a, b, c, f[e + 11], 10, 3174756917), c = n(c, d, a, b, f[e + 2], 15, 718787259), b = n(b, c, d, a, f[e + 9], 21, 3951481745), a = h(a, q), b = h(b, r), c = h(c, s), d = h(d, t);
    return (p(a) + p(b) + p(c) + p(d)).toLowerCase()
};
<!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>

Zibri
fuente
pero parece que la implementación más rápida es esta: myersdaily.org/joseph/javascript/jkm-md5.js
Zibri
este enlace no funciona myersdaily.org/joseph/javascript/jkm-md5.js
Giggs
@Giggs solo usa google y lo encontrarás: pajhome.org.uk/crypt/md5/contrib/jkm-md5.js
Zibri
11

Encontré varios artículos sobre este tema. Todos sugirieron la implementación de Joseph Meyers.

ver: http://jsperf.com/md5-shootout en algunas pruebas

En Mi búsqueda de la velocidad máxima, miré este código y vi que podía mejorarse. Así que creé un nuevo script JS basado en el código Joseph Meyers.

ver Código mejorado de Jospeh Meyers

ez2
fuente
11
¿por qué bifurcarlo, en lugar de simplemente enviar su parche al encargado?
Nick Jennings
5

Solo necesito admitir navegadores HTML5 que admitan matrices mecanografiadas (DataView, ArrayBuffer, etc.) Creo que tomé el código de Joseph Myers y lo modifiqué para permitir pasar un Uint8Array. No capté todas las mejoras, y todavía hay probablemente algunos artefactos de matriz char () que se pueden mejorar. Necesitaba esto para agregar al proyecto PouchDB.

var PouchUtils = {};
PouchUtils.Crypto = {};
(function () {
    PouchUtils.Crypto.MD5 = function (uint8Array) {
        function md5cycle(x, k) {
            var a = x[0], b = x[1], c = x[2], d = x[3];

            a = ff(a, b, c, d, k[0], 7, -680876936);
            d = ff(d, a, b, c, k[1], 12, -389564586);
            c = ff(c, d, a, b, k[2], 17, 606105819);
            b = ff(b, c, d, a, k[3], 22, -1044525330);
            a = ff(a, b, c, d, k[4], 7, -176418897);
            d = ff(d, a, b, c, k[5], 12, 1200080426);
            c = ff(c, d, a, b, k[6], 17, -1473231341);
            b = ff(b, c, d, a, k[7], 22, -45705983);
            a = ff(a, b, c, d, k[8], 7, 1770035416);
            d = ff(d, a, b, c, k[9], 12, -1958414417);
            c = ff(c, d, a, b, k[10], 17, -42063);
            b = ff(b, c, d, a, k[11], 22, -1990404162);
            a = ff(a, b, c, d, k[12], 7, 1804603682);
            d = ff(d, a, b, c, k[13], 12, -40341101);
            c = ff(c, d, a, b, k[14], 17, -1502002290);
            b = ff(b, c, d, a, k[15], 22, 1236535329);

            a = gg(a, b, c, d, k[1], 5, -165796510);
            d = gg(d, a, b, c, k[6], 9, -1069501632);
            c = gg(c, d, a, b, k[11], 14, 643717713);
            b = gg(b, c, d, a, k[0], 20, -373897302);
            a = gg(a, b, c, d, k[5], 5, -701558691);
            d = gg(d, a, b, c, k[10], 9, 38016083);
            c = gg(c, d, a, b, k[15], 14, -660478335);
            b = gg(b, c, d, a, k[4], 20, -405537848);
            a = gg(a, b, c, d, k[9], 5, 568446438);
            d = gg(d, a, b, c, k[14], 9, -1019803690);
            c = gg(c, d, a, b, k[3], 14, -187363961);
            b = gg(b, c, d, a, k[8], 20, 1163531501);
            a = gg(a, b, c, d, k[13], 5, -1444681467);
            d = gg(d, a, b, c, k[2], 9, -51403784);
            c = gg(c, d, a, b, k[7], 14, 1735328473);
            b = gg(b, c, d, a, k[12], 20, -1926607734);

            a = hh(a, b, c, d, k[5], 4, -378558);
            d = hh(d, a, b, c, k[8], 11, -2022574463);
            c = hh(c, d, a, b, k[11], 16, 1839030562);
            b = hh(b, c, d, a, k[14], 23, -35309556);
            a = hh(a, b, c, d, k[1], 4, -1530992060);
            d = hh(d, a, b, c, k[4], 11, 1272893353);
            c = hh(c, d, a, b, k[7], 16, -155497632);
            b = hh(b, c, d, a, k[10], 23, -1094730640);
            a = hh(a, b, c, d, k[13], 4, 681279174);
            d = hh(d, a, b, c, k[0], 11, -358537222);
            c = hh(c, d, a, b, k[3], 16, -722521979);
            b = hh(b, c, d, a, k[6], 23, 76029189);
            a = hh(a, b, c, d, k[9], 4, -640364487);
            d = hh(d, a, b, c, k[12], 11, -421815835);
            c = hh(c, d, a, b, k[15], 16, 530742520);
            b = hh(b, c, d, a, k[2], 23, -995338651);

            a = ii(a, b, c, d, k[0], 6, -198630844);
            d = ii(d, a, b, c, k[7], 10, 1126891415);
            c = ii(c, d, a, b, k[14], 15, -1416354905);
            b = ii(b, c, d, a, k[5], 21, -57434055);
            a = ii(a, b, c, d, k[12], 6, 1700485571);
            d = ii(d, a, b, c, k[3], 10, -1894986606);
            c = ii(c, d, a, b, k[10], 15, -1051523);
            b = ii(b, c, d, a, k[1], 21, -2054922799);
            a = ii(a, b, c, d, k[8], 6, 1873313359);
            d = ii(d, a, b, c, k[15], 10, -30611744);
            c = ii(c, d, a, b, k[6], 15, -1560198380);
            b = ii(b, c, d, a, k[13], 21, 1309151649);
            a = ii(a, b, c, d, k[4], 6, -145523070);
            d = ii(d, a, b, c, k[11], 10, -1120210379);
            c = ii(c, d, a, b, k[2], 15, 718787259);
            b = ii(b, c, d, a, k[9], 21, -343485551);

            x[0] = add32(a, x[0]);
            x[1] = add32(b, x[1]);
            x[2] = add32(c, x[2]);
            x[3] = add32(d, x[3]);

        }

        function cmn(q, a, b, x, s, t) {
            a = add32(add32(a, q), add32(x, t));
            return add32((a << s) | (a >>> (32 - s)), b);
        }

        function ff(a, b, c, d, x, s, t) {
            return cmn((b & c) | ((~b) & d), a, b, x, s, t);
        }

        function gg(a, b, c, d, x, s, t) {
            return cmn((b & d) | (c & (~d)), a, b, x, s, t);
        }

        function hh(a, b, c, d, x, s, t) {
            return cmn(b ^ c ^ d, a, b, x, s, t);
        }

        function ii(a, b, c, d, x, s, t) {
            return cmn(c ^ (b | (~d)), a, b, x, s, t);
        }

        function md51(s) {
            txt = '';
            var n = s.length,
            state = [1732584193, -271733879, -1732584194, 271733878], i;
            for (i = 64; i <= s.length; i += 64) {
                md5cycle(state, md5blk(s.subarray(i - 64, i)));
            }
            s = s.subarray(i - 64);
            var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
            for (i = 0; i < s.length; i++)
                tail[i >> 2] |= s[i] << ((i % 4) << 3);
            tail[i >> 2] |= 0x80 << ((i % 4) << 3);
            if (i > 55) {
                md5cycle(state, tail);
                for (i = 0; i < 16; i++) tail[i] = 0;
            }
            tail[14] = n * 8;
            md5cycle(state, tail);
            return state;
        }

        /* there needs to be support for Unicode here,
         * unless we pretend that we can redefine the MD-5
         * algorithm for multi-byte characters (perhaps
         * by adding every four 16-bit characters and
         * shortening the sum to 32 bits). Otherwise
         * I suggest performing MD-5 as if every character
         * was two bytes--e.g., 0040 0025 = @%--but then
         * how will an ordinary MD-5 sum be matched?
         * There is no way to standardize text to something
         * like UTF-8 before transformation; speed cost is
         * utterly prohibitive. The JavaScript standard
         * itself needs to look at this: it should start
         * providing access to strings as preformed UTF-8
         * 8-bit unsigned value arrays.
         */
        function md5blk(s) { /* I figured global was faster.   */
            var md5blks = [], i; /* Andy King said do it this way. */
            for (i = 0; i < 64; i += 4) {
                md5blks[i >> 2] = s[i]
                + (s[i + 1] << 8)
                + (s[i + 2] << 16)
                + (s[i + 3] << 24);
            }
            return md5blks;
        }

        var hex_chr = '0123456789abcdef'.split('');

        function rhex(n) {
            var s = '', j = 0;
            for (; j < 4; j++)
                s += hex_chr[(n >> (j * 8 + 4)) & 0x0F]
                + hex_chr[(n >> (j * 8)) & 0x0F];
            return s;
        }

        function hex(x) {
            for (var i = 0; i < x.length; i++)
                x[i] = rhex(x[i]);
            return x.join('');
        }

        function md5(s) {
            return hex(md51(s));
        }

        function add32(a, b) {
            return (a + b) & 0xFFFFFFFF;
        }

        return md5(uint8Array);
    };
})();
Dr.YSG
fuente
1
Estoy interesado en el rendimiento total del sistema, por lo que mi demo incluye descargas xhr2 y tiendas PouchDB (BID). Puede probarlo y ver los resultados de rendimiento en codepen.io/DrYSG/pen/kdzft . Lo que me gustaría que una persona del algoritmo MD5 observara es las funciones add32 () y md5blks () y ver si no pueden acelerarse con matrices binarias Uint32Array ()
Dr.YSG
1
¿Qué txt = ''significa realmente?
Makarov Sergey
5

Escribí pruebas para comparar varias implementaciones de hash de JavaScript, incluida la mayoría de las implementaciones de MD5 mencionadas aquí. Para ejecutar las pruebas, vaya a http://brillout.github.io/test-javascript-hash-implementations/ y espere un poco.

Parece que la implementación de YaMD5 de la respuesta de R. Hill es la más rápida.

brillante
fuente
¡Gracias por el gran punto de referencia! YaMD5 con caracteres anchos parece lento, por lo que me quedaré con FastMD5 para uso genérico.
Alfonso Nishikawa
4

Me molestó que no pudiera encontrar una implementación que fuera rápida y compatible con cadenas Unicode.

Así que hice uno que admite cadenas Unicode y aún se muestra como más rápido (en el momento de la escritura) que las implementaciones de cadenas de solo ascii más rápidas actualmente:

https://github.com/gorhill/yamd5.js

Basado en el código de Joseph Myers, pero utiliza TypedArrays, además de otras mejoras.

R. Hill
fuente
Felicitaciones a usted. Este es en realidad el único hasta ahora que encontré que produce exactamente el mismo hash que la utilidad md5 en un servidor Unix. Bien hecho de hecho.
Jacques
4

Solo por diversión,

Éste tiene 42 líneas de largo, cabe en 120 caracteres horizontalmente y se ve bien. ¿Es rápido? Bueno, es lo suficientemente rápido y es aproximadamente lo mismo que todas las demás implementaciones de JS.

Solo quería algo que no se vea feo en mi archivo helpers.js y que no ralentice mi SublimeText con líneas cortas minificadas de 20 millas de largo.

Así que aquí está mi md5 favorito.

//  A formatted version of a popular md5 implementation.
//  Original copyright (c) Paul Johnston & Greg Holt.
//  The function itself is now 42 lines long.

function md5(inputString) {
    var hc="0123456789abcdef";
    function rh(n) {var j,s="";for(j=0;j<=3;j++) s+=hc.charAt((n>>(j*8+4))&0x0F)+hc.charAt((n>>(j*8))&0x0F);return s;}
    function ad(x,y) {var l=(x&0xFFFF)+(y&0xFFFF);var m=(x>>16)+(y>>16)+(l>>16);return (m<<16)|(l&0xFFFF);}
    function rl(n,c)            {return (n<<c)|(n>>>(32-c));}
    function cm(q,a,b,x,s,t)    {return ad(rl(ad(ad(a,q),ad(x,t)),s),b);}
    function ff(a,b,c,d,x,s,t)  {return cm((b&c)|((~b)&d),a,b,x,s,t);}
    function gg(a,b,c,d,x,s,t)  {return cm((b&d)|(c&(~d)),a,b,x,s,t);}
    function hh(a,b,c,d,x,s,t)  {return cm(b^c^d,a,b,x,s,t);}
    function ii(a,b,c,d,x,s,t)  {return cm(c^(b|(~d)),a,b,x,s,t);}
    function sb(x) {
        var i;var nblk=((x.length+8)>>6)+1;var blks=new Array(nblk*16);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;
    }
    var 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);
}

Pero realmente, lo publiqué simplemente por consideraciones estéticas. Además, con los comentarios son exactamente 4000 bytes. Por favor no preguntes por qué. No puedo encontrar una explicación adecuada para mi comportamiento OCD / rebelde. Además, gracias Paul Johnston, gracias Greg Holt. (Nota al margen: ustedes omitieron algunas palabras clave var, así que me tomé la libertad de agregarlas).

dkellner
fuente
@dkelner Cool. Me gustaría copiar / pegar su función para usar en mi aplicación. ¿Podría otorgar una licencia?
pinoyyid
No es necesario, es absolutamente gratuito, es un trabajo derivado de otra implementación gratuita. Así que úsalo y quizás comentes a los autores como lo hice yo.
dkellner
3

Node.js tiene soporte incorporado

const crypto = require('crypto')
crypto.createHash('md5').update('hello world').digest('hex')

El fragmento de código anterior calcula la cadena hexadecimal MD5 para la cadena hello world

La ventaja de esta solución es que no necesita instalar una biblioteca adicional.

Creo que la solución integrada debería ser la más rápida. Si no, deberíamos crear un problema / PR para el proyecto Node.js.

Tyler Long
fuente
1

js-md5 admite cadenas UTF-8, matriz, ArrayBuffer, AMD ...

y rápido. jsperf

emn178
fuente
1

Quizás este paquete sea útil
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>

eustatos
fuente
0

¿Por qué no prueba http://phpjs.org/functions/md5/ ?

Desafortunadamente, el rendimiento está limitado con cualquier script emulado, sin embargo, esto puede generar hash md5 real. Aunque recomendaría no usar md5 para las contraseñas, ya que es un hash de renderizado rápido.

Francis
fuente
-3

También puedes consultar mi implementación de md5 . Debería ser de aprox. lo mismo que el otro publicado anteriormente. Desafortunadamente, el rendimiento está limitado por el bucle interno que es imposible de optimizar más.


fuente
-4

Si el rendimiento de su aplicación está limitado por una implementación de Javascript de MD5, entonces realmente está haciendo algo mal. Considere un cambio arquitectónico (Sugerencia: use MD5 con menos frecuencia)

MarkR
fuente
3
No estoy usando MD5 en una aplicación "nativa" con JS, es una herramienta de verificación MD5 en línea: bruechner.de/md5file/js ya no necesita una aplicación nativa para MD5;)
powtac