najszybsza implementacja MD5 w JavaScript

236

Istnieje wiele implementacji JavaScript MD5. Czy ktoś wie, który jest najbardziej zaawansowany, najbardziej naprawiony i najszybszy?

Potrzebuję tego do tego narzędzia.

powtac
źródło
2
Dlaczego potrzebujesz „szybkiej” implementacji MD5?
AnthonyWJones
3
@AnthonyWJones czy istnieje potrzeba innego rodzaju funkcji md5? To nie jest tak, że „wolna” funkcja md5 naprawdę służy jakimś celom, prawda?
Lee Olayvar,
5
@LeeOlayvar Im wolniejsza jest funkcja kryptograficzna, tym dłużej trwa brutalizowanie danego skrótu za pomocą tej funkcji.
Mathias Bynens,
45
@MathiasBynens Tak, ale z założenia md5 to szybki skrót. Oznacza to, że jest przeznaczony do pobierania dużych ilości danych i generowania skrótu bardzo, bardzo szybko. Jest to zasadniczo ostatnia rzecz, jakiej chcesz przechowywać bezpieczne dane, takie jak hasła / itp., I lepiej nadaje się / służy do identyfikacji danych. Z drugiej strony powolne hasze są zaprojektowane tak, aby były powolne od podstaw. Brutalne zmuszanie do powolnego mieszania z dużą wartością roboczą nie jest łatwym zadaniem. Jako takie, wolne hashe są idealne do haseł. MD5 jest zły dla haseł w wielu (większości?) Przypadkach. Nie jestem ekspertem w tej dziedzinie, więc weź to z solą. :)
Lee Olayvar,
16
Tak, ale ponieważ istnieje specyfikacja, która określa, jak wygląda skrót MD5, nie ma znaczenia, czy obliczasz go szybko, czy wolno. Wynik końcowy jest taki sam i będzie równie trudny / łatwy do brutalnej siły. Więc to nie ma sensu używać najszybszą realizację.
Stijn de Witt

Odpowiedzi:

168

Słyszałem, że implementacja Myers Josepha jest dość szybka. Dodatkowo ma obszerny artykuł na temat optymalizacji Javascript, opisujący czego się nauczył podczas pisania swojej implementacji. Jest to dobra lektura dla wszystkich zainteresowanych wydajnym javascript.

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

Jego implementację MD5 można znaleźć tutaj

Matt Baker
źródło
123
„Aby mój kod JavaScript MD5 był szybszy niż wszystkich innych, musiałem skorzystać z lokalnych zmiennych funkcji.” Co za przełom!
Glenn Maynard,
11
Demonstrację tej biblioteki md5 można znaleźć tutaj: jsfiddle.net/v28gq
Anderson Green
15
Jaka jest licencja na kod Myers? O ile mi wiadomo, nie wskazuje, że jest on licencjonowany (lub nie) na jego stronie internetowej.
JeroenHoek
25
Niepokoi mnie to, że ta implementacja tworzy kilka globalnych funkcji, więc zawarłem całość w zamknięciu, uczyniłem każdą funkcję zmienną i przypisałem funkcję md5 do obiektu okna. Zakłada się oczywiście, że istnieje obiekt okna, ale zachowa prywatność wszystkich funkcji pomocniczych. Nie jestem pewien, w jaki sposób (jeśli w ogóle) wpłynie to na wydajność, ale powinno być znacznie bezpieczniejsze w użyciu w dużych aplikacjach. gist.github.com/jhoff/7680711
jhoff
6
@jhoff Your Gist został kilkakrotnie rozwidlony i ulepszony, myślę też, że var add32on-line 185 powinien być właśnie add32dlatego znalazłem najlepszy widelec, jaki mogłem i zaktualizowałem go do nowej wersji: gist.github.com/MichaelPote/3f0cefaaa9578d7e30be
Mikepote,
73

Sugerowałbym użycie CryptoJS w tym przypadku.

Zasadniczo CryptoJS to rosnąca kolekcja standardowych i bezpiecznych algorytmów kryptograficznych implementowanych w JavaScript z wykorzystaniem najlepszych praktyk i wzorców. Są szybkie i mają spójny i prosty interfejs.

Więc jeśli chcesz obliczyć skrót MD5 swojego hasła, wykonaj następujące czynności:

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

Więc ten skrypt wyśle ​​hash ciągu hasła na serwer.

Aby uzyskać więcej informacji i wsparcie dotyczące innych algorytmów obliczania wartości skrótu, możesz odwiedzić:

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

theCodeMachine
źródło
59
Nie powinieneś używać md5 do haseł.
Lukas Liesis
3
Wygląda na to, że wkrótce zostanie osierocony, nadal w „kodzie Google”. Nikt nie utrzymuje?
MrYellow
2
md5 jest szybki i jeśli ktoś włamie się na twoją stronę, a twoja baza danych i kod wyciekną, zawsze możesz wygenerować bazę danych za pomocą skrótów i dekodować hasła. Daj mi swoją bazę danych na żywo z 10 milionami użytkowników i kodem. Będę się dobrze bawić i zamieszczać w Internecie moje odkodowane wyniki. Twoje zdrowie.
Lukas Liesis,
2
Link prowadzi teraz do strony 404
Adam F
29

Wybierając bibliotekę, ważne jest również, aby sprawdzić, czy obsługuje nowoczesne frameworki, takie jak Bower, przekazuje jslint, obsługuje model wtyczek dla JQuery lub systemów modułowych, takich jak AMD / RequireJS, poza aktywnym rozwojem i ma więcej niż 1 współautorów. Istnieje kilka opcji, które spełniają niektóre lub wszystkie z tych dodatkowych kryteriów:

  • CryptoJS : Jest to być może najbardziej rozbudowana biblioteka, w której każdy algorytm może być używany osobno, bez dodawania tłuszczu do kodu JS. Plus jako koder / dekoder dla UTF8, UTF16 i Base64. I utrzymać GitHub repozytorium , który jest zarejestrowany jako pakiet Bower powiększonej o instrukcje jak go używać z RequireJS.
  • Spark MD5 : jest oparty na kodzie JKM, który wspomina inna odpowiedź, co jest również szybszą implementacją. Jednak dodatkowo, implementacja Spark dodaje obsługę AMD, przechodzi jslint plus ma tryb przyrostowy. Nie ma Base64 o / p, ale ma surowe o / p (tj. Tablica 32-bitowej int-inady ciągu).
  • Wtyczka JQuery MD5 : bardzo prosta, ale wydaje się, że nie ma trybu raw.
  • JavaScript-MD5 : Nie tak wymyślny ani szybki jak Spark, ale prostszy.

Przykład z CryptoJS:

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

Porównanie wydajności powyższych bibliotek znajduje się na stronie http://jsperf.com/md5-shootout/7 . Na mojej maszynie obecne testy (które są wprawdzie stare) pokazują, że jeśli szukasz prędkości, Spark MD5 jest najlepszym wyborem (podobnie jak zwykły kod JKM). Jeśli jednak szukasz bardziej wszechstronnej biblioteki, najlepszym rozwiązaniem jest CryptoJS, chociaż jest on o 79% wolniejszy niż Spark MD5. Jednak wyobrażam sobie, że CryptoJS ostatecznie osiągnie taką samą prędkość, ponieważ jest nieco bardziej aktywnym projektem.

Shital Shah
źródło
Link do „wtyczki jQuery MD5” prowadzi mnie do strony ze złośliwym oprogramowaniem. Eep!
Raffi
1
Wygląda na to, że oryginalna witryna wtyczki jQuery MD5 została zamknięta, a teraz przekierowuje do ogólnego sprzedawcy domen. Zaktualizowałem teraz wtyczkę hostowaną w GitHub.
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
źródło
ale wydaje się, że najszybszą implementacją jest ta: myersdaily.org/joseph/javascript/jkm-md5.js
Zibri
ten link nie działa myersdaily.org/joseph/javascript/jkm-md5.js
Giggs
@Giggs po prostu użyj google, a znajdziesz go: pajhome.org.uk/crypt/md5/contrib/jkm-md5.js
Zibri
11

Znalazłem wiele artykułów na ten temat. Wszyscy zasugerowali wdrożenie Josepha Meyersa.

patrz: http://jsperf.com/md5-shootout na temat niektórych testów

W moim dążeniu do najwyższej prędkości spojrzałem na ten kod i zobaczyłem, że można go poprawić. Więc stworzyłem nowy skrypt JS oparty na kodzie Josepha Meyersa.

zobacz Ulepszony kod Jospeh Meyers

ez2
źródło
11
dlaczego rozwidlać go, zamiast po prostu przesłać łatkę z powrotem do opiekuna?
Nick Jennings
5

Muszę tylko obsługiwać przeglądarki HTML5 obsługujące tablice tekstowe (DataView, ArrayBuffer itp.). Myślę, że wziąłem kod Josepha Myersa i zmodyfikowałem go, aby obsługiwał przekazywanie tablicy Uint8Array. Nie złapałem wszystkich ulepszeń i prawdopodobnie nadal istnieje kilka artefaktów tablicy char (), które można ulepszyć. Potrzebowałem tego do dodania do projektu 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
źródło
1
Jestem zainteresowany całkowitą wydajnością systemu, więc moje demo zawiera pliki do pobrania xhr2 i sklepy PouchDB (IDB). Możesz spróbować i zobaczyć wyniki wydajności na codepen.io/DrYSG/pen/kdzft . Chciałbym, aby osoba zajmująca się algorytmem MD5 spojrzała na funkcje add32 () i md5blks () i przekonała się, czy nie można ich przyspieszyć za pomocą tablic binarnych Uint32Array ()
Dr.YSG
1
Co txt = ''to właściwie znaczy?
Makarow Siergiej
5

Napisałem testy, aby porównać kilka implementacji skrótu JavaScript, w tym większość wspomnianych tu implementacji MD5. Aby uruchomić testy, przejdź do http://brillout.github.io/test-javascript-hash-implementations/ i poczekaj chwilę.

Wydaje się, że wdrożenie odpowiedzi YaMD5 przez R. Hilla jest najszybsze.

brillout
źródło
Dziękujemy za świetny test! YaMD5 z szerokimi znakami wydaje się być powolny, więc pozostanę przy FastMD5, aby użyć go w sposób ogólny.
Alfonso Nishikawa,
4

Niepokoiło mnie to, że nie mogłem znaleźć implementacji, która jest zarówno szybka, jak i obsługuje ciągi Unicode.

Stworzyłem więc taki, który obsługuje ciągi Unicode i wciąż pokazuje jako szybszy (w momencie pisania) niż najszybsze obecnie implementacje ciągów tylko ascii:

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

Na podstawie kodu Josepha Myersa, ale używa TypedArrays oraz innych ulepszeń.

R. Hill
źródło
Uznanie dla ciebie. Jest to właściwie jedyny jak dotąd, jaki znalazłem, który daje dokładnie taki sam skrót jak narzędzie md5 na serwerze Unix. Rzeczywiście dobra robota.
Jacques
4

Dla żartu,

ten ma 42 linie, mieści się w 120 znakach w poziomie i wygląda dobrze. Czy to jest szybkie Cóż - jest wystarczająco szybki i mniej więcej taki sam jak wszystkie inne implementacje JS.

Chciałem po prostu czegoś, co nie wygląda brzydko w moim pliku helpers.js i nie spowalnia mojego SublimeText za pomocą 20-milowej długości zminimalizowanej jedno-liniowej.

Oto mój ulubiony 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);
}

Ale tak naprawdę zamieściłem to tylko ze względów estetycznych. Ponadto z komentarzami jest to dokładnie 4000 bajtów. Proszę nie pytać dlaczego. Nie mogę znaleźć właściwego wyjaśnienia dla mojego zachowania OCD / rebeliantów. Również dziękuję Paul Johnston, dziękuję Greg Holt. (Uwaga dodatkowa: pominęliście kilka słów kluczowych var, więc mogłem je dodać).

dkellner
źródło
@dkelner Cool. Chciałbym skopiować / wkleić twoją funkcję do użycia w mojej aplikacji. Czy mógłbyś udzielić licencji
pinoyyid
Nie ma potrzeby, jest całkowicie darmowy, jest pochodną innej darmowej implementacji. Więc po prostu użyj go i może skomentuj autorów tak jak ja.
dkellner
3

Node.js ma wbudowane wsparcie

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

Fragment kodu powyżej oblicza ciąg szesnastkowy MD5 dla ciągu hello world

Zaletą tego rozwiązania jest to, że nie trzeba instalować dodatkowej biblioteki.

Myślę, że wbudowane rozwiązanie powinno być najszybsze. Jeśli nie, powinniśmy utworzyć emisję / PR dla projektu Node.js.

Tyler Long
źródło
1

js-md5 obsługuje łańcuch UTF-8, tablicę, ArrayBuffer, AMD ....

i szybko. jsperf

emn178
źródło
1

Może ten pakiet był przydatny
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
źródło
0

Dlaczego nie spróbować http://phpjs.org/functions/md5/ ?

Niestety wydajność jest ograniczona w przypadku dowolnego emulowanego skryptu, jednak może to renderować prawdziwy hasz md5. Chociaż odradzałbym używanie md5 do haseł, ponieważ jest to szybko renderowany skrót.

Francis
źródło
-3

Możesz także sprawdzić moją implementację md5 . Powinno być ok. takie same jak inne opublikowane powyżej. Niestety wydajność jest ograniczona wewnętrzną pętlą, której dalsza optymalizacja nie jest możliwa.


źródło
-4

Jeśli wydajność Twojej aplikacji jest ograniczona przez implementację MD5 JavaScript, to naprawdę robisz coś złego. Zastanów się nad zmianą architektury (wskazówka: rzadziej używaj MD5)

MarkR
źródło
3
Im nie używając MD5 w „rodzimym” aplikacji z JS, jego narzędzie sprawdzania MD5 internetowym: bruechner.de/md5file/js nie potrzebuje natywnej aplikacji dla MD5 już;)
powtac