самая быстрая реализация 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 можно найти здесь


124
«Чтобы сделать мой JavaScript-код MD5 быстрее, чем все остальные, мне пришлось воспользоваться преимуществами локальных переменных функций». Какой прорыв!
Гленн Мейнард

11
Демонстрацию этой библиотеки md5 можно найти здесь: jsfiddle.net/v28gq
Андерсон Грин

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

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

6
@jhoff Ваш 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 Code". Никто не поддерживал?
MrYellow

2
MD5 работает быстро, и если кто-то взломает ваш сайт и у вас утечет ваш db-код, вы всегда можете сгенерировать db с хэшами и декодировать пароли. Дайте мне вашу живую базу данных с 10M пользователей и кода. Я получу удовольствие от этого и опубликую в Интернете мои расшифрованные результаты. Приветствия.
Лукас Лиезис

2
Ссылка ведет на страницу 404 сейчас
Адам Ф


29

При выборе библиотеки также важно выяснить, поддерживает ли она современные фреймворки, такие как Bower, передает jslint, поддерживает модель плагинов для JQuery или модульные системы, такие как AMD / RequireJS, в дополнение к активной разработке и имеет более 1 участника. Есть несколько вариантов, которые удовлетворяют некоторым или всем этим дополнительным критериям:

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

Пример из 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 сейчас.
Шиталь Шах

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 просто используйте Google, и вы найдете его: pajhome.org.uk/crypt/md5/contrib/jkm-md5.js
Zibri

11

Я нашел много статей на эту тему. Все они предложили реализацию Джозефа Мейерса.

см: http://jsperf.com/md5-shootout по некоторым тестам

В моем стремлении к максимальной скорости я посмотрел на этот код и увидел, что его можно улучшить. Поэтому я создал новый JS-скрипт на основе кода Джозефа Мейерса.

см. улучшенный код Jospeh Meyers


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/ и немного подождите.

Похоже, что реализация R.M Hill's в YaMD5 - самая быстрая.


Спасибо за отличный тест !! YaMD5 с широкими символами кажется медленным, поэтому я остановлюсь на FastMD5 для общего использования.
Альфонсо

4

Меня беспокоило, что я не смог найти реализацию, которая быстрая и поддерживала строки Unicode.

Таким образом, я создал тот, который поддерживает строки Unicode и все еще показывает как быстрее (на момент написания), чем самые быстрые в настоящее время реализации ascii-only-strings:

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

Основано на коде Джозефа Майерса, но использует TypedArrays, а также другие улучшения.


Слава тебе. На самом деле это единственный пока, который я обнаружил, который дает тот же хеш, что и утилита md5 на сервере Unix. Молодцы действительно.
Жак

4

Просто для удовольствия,

длина этой строки составляет 42 строки, она вмещает 120 символов по горизонтали и выглядит хорошо. Это быстро? Что ж, это достаточно быстро и примерно так же, как и все другие реализации JS.

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

Так вот мой любимый мд5.

//  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 байтов. Пожалуйста, не спрашивайте почему. Я не могу придумать правильное объяснение моего поведения ОКР / повстанцев. Также спасибо Пол Джонстон, спасибо Грег Холт. (Примечание: вы, ребята, пропустили несколько ключевых слов var, поэтому я позволил себе добавить их.)


@dkelner Круто. Я хотел бы скопировать / вставить вашу функцию для использования в моем приложении. Пожалуйста, не могли бы вы дать лицензию
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 MD5, то вы действительно делаете что-то не так. Рассмотрим архитектурные изменения (подсказка: используйте MD5 реже)


3
Я не использую MD5 в «нативном» приложении с JS, это онлайн-инструмент проверки MD5: bruechner.de/md5file/js Больше не нужно нативное приложение для MD5;)
powtac
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.