Implémentation MD5 la plus rapide en JavaScript

236

Il existe de nombreuses implémentations JavaScript MD5. Quelqu'un sait-il lequel est le plus avancé, le plus corrigé et le plus rapide?

J'en ai besoin pour cet outil.

powtac
la source
2
Pourquoi avez-vous besoin d'une implémentation MD5 "rapide"?
AnthonyWJones
3
@AnthonyWJones a-t-il besoin d'un autre type de fonction md5? Ce n'est pas comme si une fonction md5 "lente" sert vraiment à n'importe quel but ... n'est-ce pas?
Lee Olayvar
5
@LeeOlayvar Plus une fonction de cryptographie est lente, plus il faudrait de temps pour forcer un hachage donné à l'aide de cette fonction.
Mathias Bynens
45
@MathiasBynens Oui mais de par sa conception, md5 est un hachage rapide. C'est-à-dire qu'il est conçu pour consommer de grandes quantités de données et produire un hachage très, très rapidement. C'est essentiellement la dernière chose que vous souhaitez pour stocker des données sécurisées telles que les mots de passe / etc, et est mieux adapté / conçu pour identifier les données. Les hachages lents, d'autre part, sont conçus pour être lents à partir de zéro. Forcer brutalement un hachage lent, avec une grande valeur de travail, n'est pas une tâche facile. En tant que tel, les hachages lents sont idéaux pour les mots de passe. MD5 est mauvais pour les mots de passe dans de nombreux cas (la plupart?). Je ne suis pas un expert dans ce domaine, alors prenez cela avec du sel. :)
Lee Olayvar
16
Oui, mais comme il existe une spécification qui impose à quoi ressemble un hachage MD5, peu importe que vous le calculiez rapidement ou lentement. Le résultat final est le même et sera tout aussi difficile / facile à forcer brutalement. Il est donc logique d'utiliser l'implémentation la plus rapide.
Stijn de Witt

Réponses:

168

J'ai entendu que la mise en œuvre de Joseph Myers est assez rapide. De plus, il a un long article sur l'optimisation Javascript décrivant ce qu'il a appris lors de l'écriture de son implémentation. C'est une bonne lecture pour quiconque s'intéresse au javascript performant.

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

Son implémentation MD5 peut être trouvée ici

Matt Baker
la source
124
"Afin de rendre mon code JavaScript MD5 plus rapide que tout le monde, j'ai dû tirer parti des variables de fonction locales." Quelle percée!
Glenn Maynard
11
Une démonstration de cette bibliothèque md5 peut être trouvée ici: jsfiddle.net/v28gq
Anderson Green
15
Quelle est la licence du code Myers? Il n'indique pas qu'il est autorisé (ou non) sur son site Web pour autant que je sache.
JeroenHoek
25
Cela me dérange que cette implémentation crée un tas de fonctions globales, j'ai donc enveloppé le tout dans une fermeture, fait de chaque fonction une variable et assigné la fonction md5 à l'objet window. Cela suppose évidemment qu'il existe un objet window, mais cela gardera toutes les fonctions de support privées. Je ne sais pas comment (le cas échéant) cela affectera les performances, mais il devrait être beaucoup plus sûr pour une utilisation dans de grandes applications. gist.github.com/jhoff/7680711
jhoff
6
@jhoff Your Gist a été bifurqué et amélioré à quelques reprises, je pense également que la var add32ligne 185 devrait être juste add32pour que je trouve la meilleure fourche possible et que je la mette à
Mikepote
73

Je vous suggère d'utiliser CryptoJS dans ce cas.

Fondamentalement, CryptoJS est une collection croissante d'algorithmes cryptographiques standard et sécurisés implémentés en JavaScript en utilisant les meilleures pratiques et modèles. Ils sont rapides et ont une interface cohérente et simple.

Donc, si vous souhaitez calculer le hachage MD5 de votre chaîne de mot de passe, procédez comme suit:

<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>

Ce script affichera donc le hachage de votre chaîne de mot de passe sur le serveur.

Pour plus d'informations et d'assistance sur d'autres algorithmes de calcul de hachage, vous pouvez visiter:

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

theCodeMachine
la source
59
Vous ne devez pas utiliser md5 pour les mots de passe.
Lukas Liesis
3
On dirait que ce sera orphelin d'ici peu, toujours sur "google code". Personne ne maintient?
MrYellow
2
md5 est rapide et si quelqu'un fissure votre site et que votre db & code fuit, vous pouvez toujours générer db avec des hachages et décoder des mots de passe. Donnez-moi votre base de données en direct avec 10 millions d'utilisateurs et de code. Je vais m'amuser avec ça et poster sur internet mes résultats décodés. À votre santé.
Lukas Liesis
2
Le lien mène à une page 404 maintenant
Adam F
29

Lors de la sélection de la bibliothèque, il est également important de voir si elle prend en charge les cadres modernes tels que Bower, passe jslint, prend en charge le modèle de plug-in pour JQuery ou les systèmes de modules tels que AMD / RequireJS en plus d'être en développement actif et d'avoir plus de 1 contributeurs. Il existe quelques options qui satisfont à certains ou à tous ces critères supplémentaires:

  • CryptoJS : C'est peut-être la bibliothèque la plus étendue où chaque algorithme peut être utilisé séparément sans ajouter de graisse à votre code JS. De plus, il sert d'encodeur / décodeur pour UTF8, UTF16 et Base64. Je gère le référentiel github qui est enregistré en tant que package Bower ainsi que des instructions sur la façon de l'utiliser avec RequireJS.
  • Spark MD5 : Ceci est basé sur le code JKM que d'autres réponses mentionnent, ce qui est également la mise en œuvre la plus rapide. Cependant, en plus, l'implémentation Spark ajoute le support AMD, passe jslint plus a un mode incrémental. Il n'a pas Base64 o / p mais il a o / p brut (c'est-à-dire un tableau de 32 bits int à l'intérieur de la chaîne).
  • Plugin JQuery MD5 : Très simple sur terre mais ne semble pas avoir de mode brut.
  • JavaScript-MD5 : pas aussi sophistiqué ou rapide que Spark mais plus simple.

Exemple de CryptoJS:

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

Il existe une comparaison des performances entre les bibliothèques ci-dessus sur http://jsperf.com/md5-shootout/7 . Sur ma machine, les tests actuels (qui sont certes anciens) montrent que si vous recherchez la vitesse, Spark MD5 est votre meilleur pari (tout comme le code JKM). Cependant, si vous recherchez une bibliothèque plus complète, CryptoJS est votre meilleur choix, bien qu'il soit 79% plus lent que Spark MD5. Cependant, j'imagine que CryptoJS atteindrait finalement la même vitesse car c'est un projet un peu plus actif.

Shital Shah
la source
Le lien vers le "plugin jQuery MD5" me conduit vers un site de malware. Eep!
Raffi
1
On dirait que le site Web d'origine du plugin jQuery MD5 a été arrêté et qu'il est désormais redirigé vers le vendeur de domaine générique. J'ai mis à jour le plugin hébergé dans GitHub maintenant.
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
la source
mais il semble que l'implémentation la plus rapide soit celle-ci: myersdaily.org/joseph/javascript/jkm-md5.js
Zibri
ce lien ne fonctionne pas myersdaily.org/joseph/javascript/jkm-md5.js
Giggs
@Giggs utilise simplement google et vous le trouverez: pajhome.org.uk/crypt/md5/contrib/jkm-md5.js
Zibri
11

J'ai trouvé un certain nombre d'articles sur ce sujet. Ils ont tous suggéré la mise en œuvre de Joseph Meyers.

voir: http://jsperf.com/md5-shootout sur certains tests

dans ma quête de la vitesse ultime, j'ai regardé ce code, et j'ai vu qu'il pouvait être amélioré. J'ai donc créé un nouveau script JS basé sur le code Joseph Meyers.

voir Code Jospeh Meyers amélioré

ez2
la source
11
pourquoi le bifurquer, au lieu de simplement renvoyer votre patch au responsable?
Nick Jennings du
5

Je n'ai besoin que de prendre en charge les navigateurs HTML5 qui prennent en charge les tableaux typés (DataView, ArrayBuffer, etc.) Je pense que j'ai pris le code Joseph Myers et l'ai modifié pour prendre en charge le passage dans un Uint8Array. Je n'ai pas remarqué toutes les améliorations, et il y a probablement encore quelques artefacts de tableau char () qui peuvent être améliorés. J'en avais besoin pour l'ajouter au projet 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
la source
1
Je suis intéressé par la performance totale du système, donc ma démo comprend des téléchargements xhr2 et des magasins PouchDB (IDB). Vous pouvez l'essayer et voir les résultats des performances sur codepen.io/DrYSG/pen/kdzft . Ce que j'aimerais qu'une personne de l'algorithme MD5 regarde, ce sont les fonctions add32 () et md5blks () et voir si elles ne peuvent pas être accélérées par des tableaux typés binaires Uint32Array ()
Dr.YSG
1
Qu'est txt = ''- ce que cela signifie réellement?
Makarov Sergey
5

J'ai écrit des tests pour comparer plusieurs implémentations de hachage JavaScript, y compris la plupart des implémentations MD5 mentionnées ici. Pour exécuter les tests, accédez à http://brillout.github.io/test-javascript-hash-implementations/ et attendez un peu.

Il semble que l' implémentation YaMD5 de la réponse de R. Hill soit la plus rapide.

briller
la source
Merci pour la grande référence !! YaMD5 avec des caractères larges semble lent, donc je m'en tiendrai à FastMD5 pour une utilisation générique.
Alfonso Nishikawa
4

Cela m'a dérangé de ne pas trouver d'implémentation à la fois rapide et compatible avec les chaînes Unicode.

J'en ai donc créé un qui prend en charge les chaînes Unicode et qui s'affiche toujours plus rapidement (au moment de la rédaction) que les implémentations ascii-only-strings actuellement les plus rapides:

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

Basé sur le code de Joseph Myers, mais utilise TypedArrays, ainsi que d'autres améliorations.

R. Hill
la source
Bravo à vous. C'est en fait le seul à ce jour que j'ai trouvé qui donne exactement le même hachage que l'utilitaire md5 sur un serveur Unix. Bravo en effet.
Jacques
4

Juste pour le fun,

celui-ci est de 42 lignes de long, tient en 120 caractères horizontalement et semble bon. C'est rapide? Eh bien - c'est assez rapide et c'est à peu près la même chose que toutes les autres implémentations JS.

Je voulais juste quelque chose qui ne semble pas moche dans mon fichier helpers.js et qui ne ralentisse pas mon SublimeText avec des lignes de ligne minifiées de 20 miles de long.

Voici donc mon md5 préféré.

//  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);
}

Mais vraiment, je l'ai posté simplement pour des raisons esthétiques. De plus, avec les commentaires, c'est exactement 4000 octets. S'il vous plaît, ne demandez pas pourquoi. Je ne peux pas trouver d'explication appropriée pour mon comportement OCD / rebelle. Merci aussi Paul Johnston, merci Greg Holt. (Remarque: vous avez omis quelques mots clés var , j'ai donc pris la liberté de les ajouter.)

dkellner
la source
@dkelner Cool. Je voudrais copier / coller votre fonction pour l'utiliser dans mon application. S'il vous plaît pourriez-vous accorder une licence
pinoyyid
Il n'y a pas besoin, c'est absolument gratuit à utiliser, c'est un travail dérivé d'une autre implémentation gratuite. Alors utilisez-le et commentez peut-être les auteurs comme je l'ai fait.
dkellner
3

Node.js a un support intégré

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

L'extrait de code ci-dessus calcule la chaîne hexadécimale MD5 pour la chaîne hello world

L'avantage de cette solution est que vous n'avez pas besoin d'installer de bibliothèque supplémentaire.

Je pense que la solution intégrée devrait être la plus rapide. Sinon, nous devons créer un problème / PR pour le projet Node.js.

Tyler Long
la source
1

js-md5 prend en charge la chaîne UTF-8, le tableau, ArrayBuffer, AMD ....

et vite. jsperf

emn178
la source
1

Peut-être que ce package était utile
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
la source
0

Pourquoi ne pas essayer http://phpjs.org/functions/md5/ ?

Malheureusement, les performances sont limitées avec tout script émulé, mais cela peut rendre un vrai hachage md5. Bien que je déconseille d'utiliser md5 pour les mots de passe, car il s'agit d'un hachage à rendu rapide.

Francis
la source
-3

Vous pouvez également vérifier mon implémentation md5 . Elle devrait être d'env. le même que l'autre affiché ci-dessus. Malheureusement, les performances sont limitées par la boucle interne qui est impossible à optimiser davantage.


la source
-4

Si les performances de votre application sont limitées par une implémentation Javascript de MD5, alors vous faites vraiment quelque chose de mal. Envisagez un changement architectural (Astuce: utilisez MD5 moins souvent)

MarkR
la source
3
Je n'utilise pas MD5 dans une application "native" avec JS, c'est un outil de vérification MD5 en ligne: bruechner.de/md5file/js plus besoin d'application native pour MD5;)
powtac