schnellste MD5-Implementierung in JavaScript


236

Es gibt viele MD5-JavaScript-Implementierungen. Weiß jemand, welches am weitesten fortgeschritten, am fehlerhaftesten und am schnellsten ist?

Ich brauche es für dieses Tool.


2
Warum benötigen Sie eine "schnelle" MD5-Implementierung?
AnthonyWJones

3
@AnthonyWJones Wird eine andere Art von MD5-Funktion benötigt? Es ist nicht so, dass eine "langsame" md5-Funktion wirklich irgendeinen Zweck erfüllt.
Lee Olayvar

5
@LeeOlayvar Je langsamer eine Kryptografiefunktion ist, desto länger würde es dauern, einen bestimmten Hash mit dieser Funktion zu erzwingen.
Mathias Bynens

45
@MathiasBynens Ja, aber von Natur aus ist md5 ein schneller Hash. Das heißt, es wurde entwickelt, um große Datenmengen zu verbrauchen und einen Hash sehr, sehr schnell auszugeben. Dies ist im Wesentlichen das Letzte, was Sie zum Speichern sicherer Daten wie Kennwörter / usw. benötigen, und eignet sich besser zum Identifizieren von Daten. Langsame Hashes hingegen sind so konzipiert, dass sie von Grund auf langsam sind. Das brutale Erzwingen eines langsamen Hashs mit einem hohen Arbeitswert ist keine leichte Aufgabe. Daher sind langsame Hashes ideal für Passwörter. MD5 ist in vielen (den meisten?) Fällen schlecht für Passwörter. Ich bin kein Experte auf diesem Gebiet, also nimm das mit Salz. :)
Lee Olayvar

16
Ja, aber da es eine Spezifikation gibt , die vorschreibt, wie ein MD5-Hash aussieht, spielt es keine Rolle, ob Sie ihn schnell oder langsam berechnen. Das Endergebnis ist das gleiche und wird ebenso schwierig / leicht zu bruteforce sein. Es ist also sinnvoll, die schnellste Implementierung zu verwenden.
Stijn de Witt

Antworten:


168

Ich habe gehört, dass Josephs Myers-Implementierung ziemlich schnell ist. Zusätzlich hat er einen langen Artikel über die Javascript-Optimierung, in dem er beschreibt, was er beim Schreiben seiner Implementierung gelernt hat. Es ist eine gute Lektüre für alle, die sich für performantes Javascript interessieren.

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

Seine MD5-Implementierung finden Sie hier


123
"Um meinen JavaScript MD5-Code schneller als den aller anderen zu machen, musste ich lokale Funktionsvariablen nutzen." Was für ein Durchbruch!
Glenn Maynard

11
Eine Demonstration dieser md5-Bibliothek finden Sie hier: jsfiddle.net/v28gq
Anderson Green

15
Was ist die Lizenz für Myers 'Code? Er gibt nicht an, dass es auf seiner Website lizenziert ist (oder nicht), soweit ich das beurteilen kann.
JeroenHoek

25
Es stört mich, dass diese Implementierung eine Reihe globaler Funktionen erstellt. Deshalb habe ich das Ganze in einen Abschluss eingeschlossen, jede Funktion zu einer Variablen gemacht und dem Fensterobjekt die Funktion md5 zugewiesen. Dies setzt natürlich voraus, dass es ein Fensterobjekt gibt, aber es werden alle unterstützenden Funktionen privat bleiben. Ich bin nicht sicher, wie (wenn überhaupt) dies die Leistung beeinflusst, aber es sollte für die Verwendung in großen Anwendungen viel sicherer sein. gist.github.com/jhoff/7680711
jhoff

6
@jhoff Ihr Gist wurde ein paar Mal gegabelt und verbessert. Ich denke auch, dass die var add32Online- add32Gabel 185 sein sollte, damit ich die beste Gabel fand, die ich konnte, und sie auf diese neue Version aktualisiert habe: gist.github.com/MichaelPote/3f0cefaaa9578d7e30be
Mikepote

72

Ich würde vorschlagen, dass Sie in diesem Fall CryptoJS verwenden.

Grundsätzlich ist CryptoJS eine wachsende Sammlung von standardmäßigen und sicheren kryptografischen Algorithmen, die in JavaScript unter Verwendung von Best Practices und Mustern implementiert werden. Sie sind schnell und haben eine konsistente und einfache Oberfläche.

Wenn Sie also den MD5-Hash Ihrer Kennwortzeichenfolge berechnen möchten, gehen Sie wie folgt vor:

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

Dieses Skript sendet also den Hash Ihrer Kennwortzeichenfolge an den Server.

Weitere Informationen und Unterstützung zu anderen Hash-Berechnungsalgorithmen finden Sie unter:

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


59
Sie sollten md5 nicht für Kennwörter verwenden.
Lukas Liesis

3
Sieht so aus, als würde dies in Kürze verwaist sein, immer noch auf "Google Code". Niemand unterhält?
MrYellow

2
md5 ist schnell und wenn jemand Ihre Site knackt und Ihre Datenbank und Ihr Code durchgesickert sind, können Sie immer eine Datenbank mit Hashes generieren und Passwörter dekodieren. Gib mir deine Live-Datenbank mit 10 Millionen Benutzern und Code. Ich werde Spaß damit haben und meine entschlüsselten Ergebnisse im Internet veröffentlichen. Prost.
Lukas Liesis

2
Der Link führt jetzt zu einer 404 Seite
Adam F


29

Bei der Auswahl der Bibliothek ist es auch wichtig zu prüfen, ob sie moderne Frameworks wie Bower unterstützt, jslint übergibt, das Plugin-Modell für JQuery oder Modulsysteme wie AMD / RequireJS unterstützt, zusätzlich zur aktiven Entwicklung und mit mehr als 1 Mitwirkenden. Es gibt einige Optionen, die einige oder alle dieser zusätzlichen Kriterien erfüllen:

  • CryptoJS : Dies ist möglicherweise die umfangreichste Bibliothek, in der jeder Algorithmus separat verwendet werden kann, ohne dass Ihrem JS-Code Fett hinzugefügt wird. Plus als Encoder / Decoder für UTF8, UTF16 und Base64. Ich verwalte ein Github-Repository , das als Bower-Paket registriert ist, sowie Anweisungen zur Verwendung mit RequireJS.
  • Spark MD5 : Dies basiert auf JKM-Code, den andere Antworten erwähnen, was auch die schnellere Implementierung ist. Zusätzlich zur Spark-Implementierung wird jedoch AMD-Unterstützung hinzugefügt, und jslint plus verfügt über einen inkrementellen Modus. Es hat kein Base64-O / P, aber es hat Raw-O / P (dh ein Array von 32-Bit-Int anstelle eines Strings).
  • JQuery MD5-Plugin : Sehr einfach, bodenständig, scheint aber keinen Raw-Modus zu haben.
  • JavaScript-MD5 : Nicht so schick oder schnell wie Spark, aber einfacher.

Beispiel aus CryptoJS:

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

Es gibt einen Leistungsvergleich zwischen den oben genannten Bibliotheken unter http://jsperf.com/md5-shootout/7 . Auf meiner Maschine zeigen aktuelle Tests (die zugegebenermaßen alt sind), dass Spark MD5 die beste Wahl ist, wenn Sie nach Geschwindigkeit suchen (und ebenso einfacher JKM-Code). Wenn Sie jedoch nach einer umfassenderen Bibliothek suchen, ist CryptoJS die beste Wahl, obwohl es 79% langsamer als Spark MD5 ist. Ich würde mir jedoch vorstellen, dass CryptoJS irgendwann die gleiche Geschwindigkeit erreichen würde, da es ein etwas aktiveres Projekt ist.


Der Link zum "jQuery MD5 Plugin" führt mich zu einer Malware-Site. Eep!
Raffi

1
Es sieht so aus, als ob die ursprüngliche Website für das jQuery MD5-Plugin heruntergefahren wurde und jetzt an den generischen Domainverkäufer weitergeleitet wird. Ich habe jetzt auf das in GitHub gehostete Plugin aktualisiert.
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>


aber es scheint, dass die schnellste Implementierung diese ist: myersdaily.org/joseph/javascript/jkm-md5.js
Zibri

Dieser Link funktioniert nicht myersdaily.org/joseph/javascript/jkm-md5.js
Giggs

@Giggs benutze einfach Google und du wirst es finden: pajhome.org.uk/crypt/md5/contrib/jkm-md5.js
Zibri

11

Ich habe eine Reihe von Artikeln zu diesem Thema gefunden. Sie alle schlugen die Umsetzung von Joseph Meyers vor.

Siehe: http://jsperf.com/md5-shootout zu einigen Tests

Auf meiner Suche nach der ultimativen Geschwindigkeit habe ich mir diesen Code angesehen und festgestellt, dass er verbessert werden kann. Also habe ich ein neues JS-Skript erstellt, das auf dem Joseph Meyers-Code basiert.

Siehe Verbesserter Jospeh Meyers-Code


11
Warum gabeln Sie es, anstatt Ihren Patch nur an den Betreuer zurückzusenden?
Nick Jennings


5

Ich muss nur HTML5-Browser unterstützen, die typisierte Arrays unterstützen (DataView, ArrayBuffer usw.). Ich glaube, ich habe den Joseph Myers-Code genommen und ihn so geändert, dass er die Übergabe eines Uint8Array unterstützt. Ich habe nicht alle Verbesserungen festgestellt, und es gibt wahrscheinlich noch einige char () - Array-Artefakte, die verbessert werden können. Ich brauchte dies, um es dem PouchDB-Projekt hinzuzufügen.

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

1
Ich interessiere mich für die Gesamtsystemleistung. Meine Demo enthält also xhr2-Downloads und PouchDB (IDB) -Speicher. Sie können es versuchen und die Leistungsergebnisse unter codepen.io/DrYSG/pen/kdzft anzeigen . Ich möchte, dass sich eine Person mit MD5-Algorithmus die Funktionen add32 () und md5blks () ansieht und prüft, ob sie nicht durch binär typisierte Arrays beschleunigt werden können. Uint32Array ()
Dr.YSG

1
Was txt = ''bedeutet eigentlich?
Makarov Sergey

5

Ich habe Tests geschrieben, um mehrere JavaScript-Hash-Implementierungen zu vergleichen, einschließlich der meisten hier erwähnten MD5-Implementierungen. Um die Tests auszuführen, gehen Sie zu http://brillout.github.io/test-javascript-hash-implementations/ und warten Sie etwas.

Es scheint, dass die YaMD5- Implementierung der Antwort von R. Hill die schnellste ist.


Vielen Dank für den tollen Benchmark !! YaMD5 mit breiten Zeichen scheint langsam zu sein, daher werde ich mich für die allgemeine Verwendung an FastMD5 halten.
Alfonso Nishikawa

4

Es hat mich gestört, dass ich keine Implementierung finden konnte, die sowohl schnell ist als auch Unicode-Zeichenfolgen unterstützt.

Also habe ich eine erstellt, die Unicode-Zeichenfolgen unterstützt und (zum Zeitpunkt des Schreibens) immer noch schneller ist als die derzeit schnellsten Implementierungen von Nur-ASCII-Zeichenfolgen:

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

Basierend auf dem Code von Joseph Myers, verwendet jedoch TypedArrays und andere Verbesserungen.


Hut ab. Dies ist tatsächlich der einzige, den ich bisher gefunden habe, der genau den gleichen Hash liefert wie das Dienstprogramm md5 auf einem Unix-Server. In der Tat gut gemacht.
Jacques

4

Nur zum Spaß,

Dieser ist 42 Zeilen lang, passt horizontal in 120 Zeichen und sieht gut aus. Ist es schnell Nun - es ist schnell genug und ungefähr das gleiche wie alle anderen JS-Implementierungen.

Ich wollte nur etwas, das in meiner Datei helpers.js nicht hässlich aussieht und meinen SublimeText nicht mit 20 Meilen langen minimierten Einzeilern verlangsamt.

Also hier ist mein Lieblings-MD5.

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

Aber wirklich, ich habe es nur aus ästhetischen Gründen gepostet. Außerdem sind es mit den Kommentaren genau 4000 Bytes. Bitte fragen Sie nicht warum. Ich kann keine richtige Erklärung für mein Verhalten bei Zwangsstörungen / Rebellen finden. Danke auch Paul Johnston, danke Greg Holt. (Randnotiz: Ihr habt ein paar var- Schlüsselwörter weggelassen, also habe ich mir erlaubt, sie hinzuzufügen.)


@dkelner Cool. Ich möchte Ihre Funktion kopieren / einfügen, um sie in meiner App zu verwenden.
Könnten

Es gibt keine Notwendigkeit, es ist absolut kostenlos zu verwenden, es ist eine abgeleitete Arbeit von einer anderen kostenlosen Implementierung. Also benutze es einfach und kommentiere die Autoren vielleicht so wie ich.
dkellner

3

Node.js verfügt über eine integrierte Unterstützung

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

Das obige Code-Snippet berechnet die MD5-Hex-Zeichenfolge für die Zeichenfolge hello world

Der Vorteil dieser Lösung ist, dass Sie keine zusätzliche Bibliothek installieren müssen.

Ich denke, eingebaute Lösung sollte die schnellste sein. Wenn nicht, sollten wir issue / PR für das Node.js-Projekt erstellen.



1

Vielleicht war dieses Paket nützlich
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

Warum versuchen Sie es nicht mit http://phpjs.org/functions/md5/ ?

Leider ist die Leistung bei jedem emulierten Skript begrenzt, dies kann jedoch echten MD5-Hash rendern. Obwohl ich davon abraten würde, md5 für Passwörter zu verwenden, da es sich um einen schnell gerenderten Hash handelt.



-3

Sie können auch meine md5-Implementierung überprüfen . Es sollte ca. sein. das gleiche wie das andere oben gepostet. Leider ist die Leistung durch die innere Schleife begrenzt, die nicht mehr optimiert werden kann.


-4

Wenn die Leistung Ihrer Anwendung durch eine Javascript-Implementierung von MD5 eingeschränkt wird, machen Sie wirklich etwas falsch. Betrachten Sie eine architektonische Änderung (Hinweis: Verwenden Sie MD5 seltener)


3
Ich benutze MD5 nicht in einer "nativen" Anwendung mit JS, es ist ein Online-MD5- Prüftool : bruechner.de/md5file/js keine native App mehr für MD5
erforderlich
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.