найшвидша реалізація MD5 в JavaScript


236

Існує багато реалізацій JavaScript MD5 там. Хтось знає, який з них є найсучаснішим, найпотаємнішим і найшвидшим?

Мені це потрібно для цього інструменту.


2
Для чого потрібна "швидка" реалізація MD5?
AnthonyWJones

3
@AnthonyWJones Чи потрібен будь-який інший тип функції md5? Це не схоже на те, що "повільна" функція md5 справді виконує будь-яку мету .. чи не так?
Лі Олайвар

5
@LeeOlayvar Чим повільніше функція криптографії, тим довше знадобиться, щоб використати дану хеш за допомогою цієї функції.
Матіас Байненс

45
@MathiasBynens Так, але за дизайном, md5 - це швидкий хеш. Тобто, він призначений для споживання великої кількості даних та виведення хешу дуже, дуже швидко. Це по суті останнє, що потрібно для зберігання захищених даних, таких як паролі / тощо, і краще підходить / призначене для ідентифікації даних. Повільні хеши з іншого боку, розроблені так, щоб вони були повільними від землі вгору. Брутне форсування повільного хешу, що має велике робоче значення, - завдання не з легких. Таким чином, повільні хеші ідеально підходять для паролів. MD5 поганий для паролів у багатьох (більшості?) Випадках. Я не фахівець у цій галузі, тому прийміть це з сіллю. :)
Лі Олайвар

16
Так, але оскільки існує специфікація , яка визначає, як виглядає хеш MD5, не має значення, чи вичислите його швидко чи повільно. Кінцевий результат однаковий і буде однаково важким / легким для грубої сили. Тож має сенс використовувати найшвидшу реалізацію.
Штійн де Вітт

Відповіді:


168

Я чув, що впровадження Джозефа Майєрса досить швидко. Крім того, у нього є велика стаття про оптимізацію Javascript, в якій описується те, що він дізнався під час написання програми. Це добре читати для всіх, хто зацікавлений у виконанні JavaScript.

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

Його реалізацію MD5 можна знайти тут


123
"Щоб зробити мій код JavaScript MD5 швидше, ніж всі інші, мені довелося скористатися локальними змінними функцій." Який прорив!
Гленн Мейнард

11
Демонстрацію цієї бібліотеки md5 можна знайти тут: jsfiddle.net/v28gq
Anderson Green

15
Що таке ліцензія на код Майєрса? Наскільки він не вказує, що це ліцензовано (чи ні) на його веб-сайті.
JeroenHoek

25
Мене непокоїть, що ця реалізація створює купу глобальних функцій, тому я завернув всю справу в закриття, зробив кожну функцію змінною і призначив функцію md5 об’єкту вікна. Очевидно, якщо припустити, що існує об’єкт вікна, але він збереже всі підтримуючі функції приватними. Я не впевнений, як (якщо взагалі) це вплине на продуктивність, але це має бути набагато безпечнішим для використання у великих програмах. gist.github.com/jhoff/7680711
jhoff

6
@jhoff Your Gist був роздвоєний і вдосконалений кілька разів, я також думаю, що var add32лінія 185 повинна бути просто add32такою, що я знайшов найкращу вилку, яку я міг, і оновив її до нової версії: gist.github.com/MichaelPote/3f0cefaaa9578d7e30be
Mikepote

73

Я б запропонував вам використовувати CryptoJS в цьому випадку.

В основному CryptoJS - це зростаюча колекція стандартних та захищених криптографічних алгоритмів, реалізованих у JavaScript, використовуючи кращі практики та шаблони. Вони швидкі, і мають стійкий і простий інтерфейс.

Отже, якщо ви хочете обчислити хеш MD5 вашого рядка пароля, виконайте наступне:

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

Тож цей скрипт опублікує хеш рядка вашого пароля на сервері.

Для отримання додаткової інформації та підтримки щодо інших алгоритмів обчислення хешу ви можете відвідати:

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


59
Ви не повинні використовувати md5 для паролів.
Лукас Лейсіс

3
Схоже, це буде осиротінням недовго, все ще на "коді Google". Ніхто не підтримує?
MrYellow

2
md5 швидкий, і якщо хтось зламає ваш сайт, і ваш db & код просочився, ви завжди можете генерувати db за допомогою хешей та декодування паролів. Дайте мені вашу живу базу даних з 10-мільйонними користувачами та кодом. Я буду веселитися цим і розміщу в Інтернеті свої розшифровані результати. Ура.
Лукас Лейсіс

2
Посилання веде на сторінку 404 зараз
Адам Ф


29

Під час вибору бібліотеки також важливо перевірити, чи підтримує вона сучасні рамки, такі як Bower, передає jslint, підтримує модуль плагінів для JQuery або модульні системи, такі як AMD / RequireJS, на додаток до активного розвитку та має більше 1 учасника. Є кілька варіантів, які відповідають деяким або всім цим додатковим критеріям:

  • CryptoJS : Це, мабуть, найширша бібліотека, де кожен алгоритм можна використовувати окремо, не додаючи жир у свій JS-код. Плюс це як кодер / декодер для UTF8, UTF16 та Base64. Я підтримую сховище github, яке зареєстровано як пакет Bower плюс інструкції, як ним користуватися RequireJS.
  • Іскровий MD5 : Це засновано на JKM-коді, який інша відповідь згадує, що також є швидшою реалізацією. Однак крім того, реалізація Spark додає підтримку AMD, передає jslint plus і має поступовий режим. У нього немає Base64 o / p, але він має необроблений o / p (тобто масив 32-розрядних int непрохідних рядків).
  • Плагін JQuery MD5 : Дуже простий вниз, але, здається, не має сирого режиму.
  • JavaScript-MD5 : Не настільки вигадливий чи швидкий, як Іскра, але простіший.

Приклад з CryptoJS:

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

Існує порівняння продуктивності між вищезазначеними бібліотеками на веб-сайті http://jsperf.com/md5-shootout/7 . На моїх машинах поточні випробування (які, правда, старі) показують, що якщо ви шукаєте швидкість Spark MD5 - це найкраща ставка (і так це звичайний код JKM). Однак якщо ви шукаєте більш всебічну бібліотеку, то CryptoJS - найкраща ставка, хоча вона на 79% повільніше, ніж Spark MD5. Однак я думаю, що CryptoJS врешті-решт досягне такої ж швидкості, як і трохи активніший проект.


Посилання на "jQuery MD5 плагін" веде мене на сайт зловмисних програм. Eep!
Раффі

1
Схоже, що оригінальний веб-сайт для плагіна jQuery MD5 закрився, і його тепер переадресовує на продавця загального домену. Зараз я оновив плагін, розміщений у 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>


але здається, найшвидша реалізація саме ця: myersdaily.org/joseph/javascript/jkm-md5.js
Zibri

це посилання не працює myersdaily.org/joseph/javascript/jkm-md5.js
Giggs

@Giggs просто використовуйте google, і ви знайдете його: pajhome.org.uk/crypt/md5/contrib/jkm-md5.js
Zibri

11

Я знайшов низку статей на цю тему. Усі вони запропонували Джозефу Майєру реалізацію

дивіться: http://jsperf.com/md5-shootout про деякі тести

в Моїх пошуках максимальної швидкості я подивився на цей код, і побачив, що його можна вдосконалити. Тому я створив новий сценарій JS на основі коду Джозефа Майєрса.

див. Удосконалений код Джоспеха Майєрса


11
навіщо роздрібнювати його, а не просто надсилати свій патч назад в сервіс?
Нік Дженнінгс


5

Мені потрібно лише підтримувати браузери HTML5, які підтримують набрані масиви (DataView, ArrayBuffer тощо). Я думаю, що я взяв код Джозефа Майєрса і змінив його для підтримки передачі в Uint8Array. Я не впіймав усіх покращень, і, мабуть, є деякі артефакти масиву char (), які можна вдосконалити. Мені це було потрібно для додавання до проекту 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);
    };
})();

1
Мене цікавить загальна продуктивність системи, тому моя демонстрація включає завантаження xhr2 та магазини PouchDB (IDB). Ви можете спробувати його і побачити результати роботи на codepen.io/DrYSG/pen/kdzft . Що я хотів би подивитися на алгоритм MD5 - це функції add32 () та md5blks () і побачити, чи не можуть вони бути прискорені дворядні друковані масиви Uint32Array ()
Dr.YSG,

1
Що txt = ''насправді означає?
Макаров Сергій

5

Я написав тести для порівняння декількох хеш-версій JavaScript, включаючи більшість MD5-реалізацій, згаданих тут. Щоб запустити тести, перейдіть на сторінку http://brillout.github.io/test-javascript-hash-implementations/ і трохи почекайте.

Здається, реалізація відповіді Р. Хілла YaMD5 найшвидша.


Дякую за чудовий орієнтир !! YaMD5 з широкими символами здається повільним, тому я буду дотримуватися FastMD5 для загального використання.
Альфонсо Нішікава

4

Мене непокоїло, що я не можу знайти реалізацію, яка є одночасно швидкою та підтримує рядки Unicode.

Тож я зробив такий, який підтримує рядки Unicode і все ще показує настільки ж швидші (на момент написання), що й зараз найшвидші реалізації ascii-string-string:

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

На основі коду Джозефа Майєрса, але він використовує TypedArrays, а також інші вдосконалення.


Кудо вам. Це насправді єдине, доки я виявив, що дає точно такий же хеш, як утиліта md5 на сервері Unix. Молодці дійсно.
Жак

4

Задля розваги,

ця довжина на 42 рядки, вміщається в 120 символів по горизонталі і виглядає добре. Це швидко? Ну - це досить швидко і приблизно так само, як і всі інші впровадження JS.

Я просто хотів, щоб щось не виглядало некрасиво у моєму файлі helpers.js і не сповільнювало мій SublimeText за допомогою 20-милі довгих мінімізованих одноколірних ліній.

Тож ось мій улюблений 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);
}

Але насправді я опублікував це лише з естетичних міркувань. Також з коментарями це рівно 4000 байт. Не питай, чому. Я не можу придумати належного пояснення моїй поведінці OCD / повстанців. Також дякую Пол Джонстон, дякую Грегу Холту. (Примітка сторони: ви , хлопці , опущені кілька Var ключових слів , так що я взяв на себе сміливість їх додавання.)


@dkelner Cool. Я хотів би скопіювати / вставити вашу функцію для використання в моєму додатку. Будь ласка, можете надати ліцензію
pinoyyid

Немає потреби, це абсолютно безкоштовно у використанні, це похідне від іншої вільної реалізації. Тому просто використовуйте його і, можливо, коментуйте авторів, як я.
dkellner

3

Node.js має вбудовану підтримку

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

Фрагмент коду вище обчислює шістнадцятковий рядок MD5 для рядка hello world

Перевага цього рішення полягає в тому, що вам не потрібно встановлювати додаткову бібліотеку.

Я думаю, що вбудоване рішення повинно бути швидшим. Якщо ні, ми повинні створити проблему / PR для проекту Node.js.




0

Чому б не спробувати http://phpjs.org/functions/md5/ ?

На жаль, продуктивність обмежена будь-яким емульованим сценарієм, однак це може зробити реальний хеш md5. Хоча я б радив не використовувати md5 для паролів, оскільки це швидкозроблений хеш.


0

Набагато швидше хешування повинно бути можливим шляхом обчислення на графічній карті (реалізуйте алгоритм хешування в WebGL), як там обговорювалося про SHA256: Чи можна обчислити хешами sha256 у браузері за допомогою відеокарти користувача, наприклад. за допомогою WebGL або Flash?


-3

Ви також можете перевірити мою реалізацію md5 . Він повинен бути прибл. те саме, що й інші, розміщені вище. На жаль, продуктивність обмежена внутрішнім циклом, який неможливо оптимізувати більше.


-4

Якщо продуктивність вашої програми обмежена реалізацією Javascript JavaScript MD5, то ви дійсно робите щось не так. Розгляньте архітектурну зміну (Підказка: рідше використовуйте MD5)


3
Я не використовую MD5 у "рідному" додатку з JS, його онлайн-інструментом перевірки MD5: bruechner.de/md5file/js більше немає потреби в рідній програмі для MD5;)
powtac
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.