Triển khai MD5 nhanh nhất trong JavaScript


236

Có rất nhiều triển khai JavaScript MD5 ngoài kia. Có ai biết cái nào là tiên tiến nhất, nhiều lỗi nhất và nhanh nhất không?

Tôi cần nó cho công cụ này .


2
Tại sao bạn cần triển khai MD5 "nhanh"?
AnthonyWJones

3
@AnthonyWJones có cần bất kỳ loại chức năng md5 nào khác không? Nó không giống như một hàm md5 "chậm" thực sự phục vụ cho bất kỳ mục đích nào .. phải không?
Lee Olayvar

5
@LeeOlayvar Chức năng mã hóa càng chậm thì càng mất nhiều thời gian để bẻ khóa một hàm băm nhất định bằng cách sử dụng hàm đó.
Mathias Bynens

45
@MathiasBynens Có nhưng theo thiết kế, md5 là một hàm băm nhanh. Điều đó có nghĩa là, nó được thiết kế để tiêu thụ một lượng lớn dữ liệu và tạo ra một hàm băm rất, rất nhanh. Đây thực chất là điều cuối cùng bạn muốn để lưu trữ dữ liệu an toàn như mật khẩu / vv và phù hợp hơn / được thiết kế để xác định dữ liệu. Mặt khác băm chậm, được thiết kế để chậm từ mặt đất lên. Brute buộc băm chậm, với giá trị công việc lớn, không phải là một nhiệm vụ dễ dàng. Như vậy, băm chậm là lý tưởng cho mật khẩu. MD5 là xấu cho mật khẩu trong nhiều trường hợp (hầu hết?). Tôi không phải là một chuyên gia trong lĩnh vực này, vì vậy hãy dùng nó với muối. :)
Lee Olayvar

16
Có, nhưng vì có một thông số bắt buộc băm MD5 trông như thế nào, nên việc bạn tính toán nhanh hay chậm không thành vấn đề. Kết quả cuối cùng là như nhau và sẽ khó như nhau / dễ bị tàn bạo. Vì vậy, nó ý nghĩa để sử dụng thực hiện nhanh nhất.
Stijn de Witt

Câu trả lời:


168

Tôi đã nghe việc triển khai Myers của Joseph khá nhanh. Ngoài ra, anh ta có một bài viết dài về tối ưu hóa Javascript mô tả những gì anh ta đã học được khi viết bài thực hiện. Đó là một bài đọc tốt cho bất cứ ai quan tâm đến javascript biểu diễn.

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

Triển khai MD5 của anh ấy có thể được tìm thấy ở đây


123
"Để làm cho mã MD5 JavaScript của tôi nhanh hơn các mã khác, tôi đã phải tận dụng các biến chức năng cục bộ." Thật là một bước đột phá!
Glenn Maynard

11
Một bản trình diễn của thư viện md5 này có thể được tìm thấy ở đây: jsfiddle.net/v28gq
Anderson Green

15
Giấy phép cho mã Myers là gì? Anh ta không cho biết rằng nó được cấp phép (hoặc không) trên trang web của anh ta như tôi có thể nói.
JeroenHoek

25
Điều này làm phiền tôi rằng việc triển khai này tạo ra một loạt các hàm toàn cục, vì vậy tôi đã gói toàn bộ mọi thứ trong một bao đóng, biến mỗi hàm thành một biến và gán hàm md5 cho đối tượng cửa sổ. Điều này rõ ràng là giả sử có một đối tượng cửa sổ, nhưng nó sẽ giữ tất cả các chức năng hỗ trợ riêng tư. Tôi không chắc làm thế nào (nếu có) điều này sẽ ảnh hưởng đến hiệu suất, nhưng nó sẽ an toàn hơn nhiều khi sử dụng trong các ứng dụng lớn. gist.github.com/jhoff/7680711
jhoff

6
@jhoff Gist của bạn đã được rẽ nhánh và cải thiện một vài lần, tôi cũng nghĩ rằng var add32dòng 185 nên chỉ add32để tôi tìm được ngã ba tốt nhất có thể và cập nhật nó lên phiên bản mới này: gist.github.com/MichaelPote/3f0cefaaa9578d7e30be
Mikepote

73

Tôi sẽ đề nghị bạn sử dụng CryptoJS trong trường hợp này.

Về cơ bản CryptoJS là một tập hợp ngày càng tăng các thuật toán mã hóa tiêu chuẩn và an toàn được triển khai trong JavaScript bằng cách sử dụng các thực tiễn và mẫu tốt nhất. Chúng nhanh, và chúng có một giao diện nhất quán và đơn giản.

Vì vậy, nếu bạn muốn tính băm MD5 của chuỗi mật khẩu của mình thì hãy làm như sau:

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

Vì vậy, tập lệnh này sẽ đăng băm chuỗi mật khẩu của bạn lên máy chủ.

Để biết thêm thông tin và hỗ trợ về các thuật toán tính toán băm khác, bạn có thể truy cập:

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


59
Bạn không nên sử dụng md5 cho mật khẩu.
Lukas Liesis

3
Có vẻ như điều này sẽ mồ côi trước đó rất lâu, vẫn còn trên "mã google". Không ai duy trì?
MrYellow

2
md5 rất nhanh và nếu ai đó bẻ khóa trang web của bạn và mã db & mã của bạn bị rò rỉ, bạn luôn có thể tạo db bằng cách băm và giải mã mật khẩu. Hãy cho tôi cơ sở dữ liệu trực tiếp của bạn với 10 triệu người dùng và mã. Tôi sẽ có niềm vui với điều đó và đăng trên internet kết quả giải mã của tôi. Chúc mừng.
Lukas Liesis

2
Liên kết dẫn đến Trang 404 ngay bây giờ
Adam F


29

Trong khi chọn thư viện, điều quan trọng là phải xem liệu nó có hỗ trợ các khung hiện đại như Bower, vượt qua jslint, hỗ trợ mô hình plugin cho JQuery hoặc các hệ thống mô-đun như AMD / RequireJS ngoài việc đang phát triển tích cực và có nhiều hơn 1 người đóng góp. Có một số tùy chọn thỏa mãn một số hoặc tất cả các tiêu chí bổ sung sau:

  • CryptoJS : Đây có lẽ là thư viện mở rộng nhất, nơi mỗi thuật toán có thể được sử dụng riêng mà không cần thêm chất béo vào mã JS của bạn. Thêm vào đó là bộ mã hóa / giải mã cho UTF8, UTF16 và Base64. Tôi duy trì kho lưu trữ github được đăng ký dưới dạng gói Bower cộng với hướng dẫn về cách sử dụng nó với RequireJS.
  • Spark MD5 : Điều này dựa trên mã JKM mà câu trả lời khác đề cập cũng là triển khai nhanh hơn. Tuy nhiên, việc triển khai Spark bổ sung hỗ trợ AMD, vượt qua jslint plus có chế độ gia tăng. Nó không có Base64 o / p nhưng nó không có o / p thô (tức là mảng intead của chuỗi 32 bit).
  • Plugin JQuery MD5 : Rất đơn giản nhưng dường như không có chế độ thô.
  • JavaScript-MD5 : Không cầu kỳ hay nhanh như Spark nhưng đơn giản hơn.

Ví dụ từ CryptoJS:

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

Có một so sánh hiệu suất giữa các thư viện trên tại http://jsperf.com/md5-shootout/7 . Trong các thử nghiệm hiện tại trên máy của tôi (đã được thừa nhận cũ) cho thấy rằng nếu bạn đang tìm kiếm tốc độ Spark MD5 là đặt cược tốt nhất của bạn (và mã JKM đơn giản cũng vậy). Tuy nhiên, nếu bạn tìm kiếm thư viện toàn diện hơn thì CryptoJS là lựa chọn tốt nhất của bạn mặc dù nó chậm hơn 79% so với Spark MD5. Tuy nhiên tôi sẽ tưởng tượng CryptoJS cuối cùng sẽ đạt được tốc độ tương tự như dự án tích cực hơn một chút.


Liên kết đến "jQuery MD5 plugin" dẫn tôi đến một trang web chứa phần mềm độc hại. Eep!
Raffi

1
Có vẻ như trang web gốc cho plugin MD5 của jQuery đã ngừng hoạt động và giờ đây nó đã chuyển hướng đến người bán tên miền chung. Tôi đã cập nhật plugin được lưu trữ trong GitHub ngay bây giờ.
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>


nhưng có vẻ như cách triển khai nhanh nhất là cái này: myersdaily.org/joseph/javascript/jkm-md5.js
Zibri

liên kết này không hoạt động myersd Daily.org/joseph/javascript/jkm-md5.js
Giggs

@Giggs chỉ cần sử dụng google và bạn sẽ tìm thấy nó: pyjome.org.uk/crypt/md5/contrib/jkm-md5.js
Zibri

11

Tôi tìm thấy một số bài viết về chủ đề này. Tất cả họ đều đề nghị Joseph Meyers thực hiện.

xem: http://jsperf.com/md5-shootout trên một số bài kiểm tra

Trong nhiệm vụ của tôi về tốc độ tối đa tôi đã xem mã này, tôi thấy rằng nó có thể được cải thiện. Vì vậy, tôi đã tạo ra một tập lệnh JS mới dựa trên mã Joseph Meyers.

xem mã cải tiến Jospeh Meyers


11
Tại sao lại dùng nó, thay vì chỉ gửi bản vá của bạn cho người bảo trì?
Nick Jennings


5

Tôi chỉ cần hỗ trợ các trình duyệt HTML5 hỗ trợ các mảng đã nhập (DataView, ArrayBuffer, v.v.) Tôi nghĩ rằng tôi đã lấy mã Joseph Myers và sửa đổi nó để hỗ trợ chuyển qua Uint8Array. Tôi đã không nắm bắt được tất cả các cải tiến và có thể vẫn còn một số tạo tác mảng char () có thể được cải thiện. Tôi cần điều này để thêm vào dự án 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
Tôi quan tâm đến tổng hiệu năng hệ thống, vì vậy bản demo của tôi bao gồm các bản tải xuống xhr2 và các cửa hàng PouchDB (IDB). Bạn có thể dùng thử và xem kết quả hiệu suất tại codepen.io/DrYSG/pen/kdzft . Những gì tôi muốn một người làm thuật toán MD5 nhìn vào là các hàm add32 () và md5blks () và xem liệu chúng có thể được tăng tốc bởi các mảng được gõ nhị phân Uint32Array ()
Dr.YSG

1
Điều txt = ''đó thực sự có nghĩa là gì?
Makarov Serge

5

Tôi đã viết các bài kiểm tra để so sánh một số triển khai băm JavaScript, bao gồm hầu hết các triển khai MD5 được đề cập ở đây. Để chạy thử nghiệm, hãy truy cập http://brillout.github.io/test-javascript-hash-im THỰCations / và đợi một chút.

Có vẻ như việc triển khai YaMD5 trong câu trả lời của R. Hill là nhanh nhất.


Cảm ơn bạn cho điểm chuẩn tuyệt vời !! YaMD5 với các ký tự rộng có vẻ chậm, vì vậy tôi sẽ sử dụng FastMD5 để sử dụng chung.
Alfonso Nishikawa

4

Điều đó làm phiền tôi rằng tôi không thể tìm thấy một triển khai nào vừa nhanh và hỗ trợ các chuỗi Unicode.

Vì vậy, tôi đã tạo một chuỗi hỗ trợ các chuỗi Unicode và vẫn hiển thị nhanh hơn (tại thời điểm viết) so với các triển khai chuỗi chỉ ascii nhanh nhất hiện tại:

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

Dựa trên mã của Joseph Myers, nhưng sử dụng TypedArrays, cộng với các cải tiến khác.


Kudos cho bạn. Đây thực sự là lần duy nhất cho đến nay tôi thấy mang lại hàm băm chính xác giống như tiện ích md5 trên máy chủ Unix. Thực hiện tốt.
Jacques

4

Chỉ để cho vui

cái này dài 42 dòng, vừa vặn với 120 ký tự theo chiều ngang và trông rất đẹp. Có nhanh không Chà - nó đủ nhanh và nó gần giống như tất cả các triển khai JS khác.

Tôi chỉ muốn một cái gì đó mà không nhìn xấu xí trong tập tin helpers.js của tôi và không làm chậm SublimeText của tôi với 20 dặm dài minified một lớp lót.

Vì vậy, đây là md5 yêu thích của tôi.

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

Nhưng thực sự, tôi chỉ đăng nó ra khỏi những cân nhắc thẩm mỹ. Ngoài ra, với các ý kiến, nó chính xác là 4000 byte. Xin đừng hỏi tại sao. Tôi không thể đưa ra một lời giải thích phù hợp cho hành vi OCD / nổi loạn của mình. Ngoài ra, cảm ơn bạn Paul Johnston, cảm ơn bạn Greg Holt. (Lưu ý bên lề: các bạn đã bỏ qua một vài từ khóa var vì vậy tôi đã tự do thêm chúng.)


@dkelner Mát mẻ. Tôi muốn sao chép / dán chức năng của bạn để sử dụng trong ứng dụng của tôi. Xin vui lòng bạn có thể cấp giấy phép
pinoyyid

Không có nhu cầu, nó hoàn toàn miễn phí để sử dụng, đó là một tác phẩm bắt nguồn từ một triển khai miễn phí khác. Vì vậy, chỉ cần sử dụng nó và có thể nhận xét các tác giả như tôi đã làm.
dkellner

3

Node.js có hỗ trợ tích hợp

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

Đoạn mã trên tính toán chuỗi hex MD5 cho chuỗi hello world

Ưu điểm của giải pháp này là bạn không cần cài đặt thêm thư viện.

Tôi nghĩ rằng xây dựng trong giải pháp nên là nhanh nhất. Nếu không, chúng ta nên tạo vấn đề / PR cho dự án Node.js.




0

Tại sao không thử http://phpjs.org/fiances/md5/ ?

Thật không may, hiệu suất bị hạn chế với bất kỳ tập lệnh mô phỏng nào, tuy nhiên điều này có thể khiến băm md5 thực sự. Mặc dù tôi sẽ khuyên bạn không nên sử dụng md5 cho mật khẩu, vì đây là hàm băm được kết xuất nhanh.



-3

Bạn cũng có thể kiểm tra việc thực hiện md5 của tôi . Nó sẽ được khoảng. giống như những gì được đăng ở trên. Thật không may, hiệu suất bị giới hạn bởi vòng lặp bên trong không thể tối ưu hóa nhiều hơn.


-4

Nếu hiệu suất của ứng dụng của bạn bị giới hạn bởi triển khai MD5 của Javascript, thì bạn thực sự đã làm sai điều gì đó. Xem xét thay đổi kiến ​​trúc (Gợi ý: sử dụng MD5 ít thường xuyên hơn)


3
Tôi không sử dụng MD5 trong ứng dụng "gốc" với JS, công cụ kiểm tra MD5 trực tuyến của nó: bruechner.de/md5file/js không cần ứng dụng gốc cho MD5 nữa;)
powtac
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.