sha1 / sha256 performance comparison (v4)

Revision 4 of this benchmark created on


Preparation HTML

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script>
<script src="http://bitwiseshiftleft.github.io/sjcl/sjcl.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha256.js"></script>
<script src="http://perf.opal.io/js-nacl-0.1.0.js"></script>

Setup

var ipsum = "Bavaria ipsum dolor sit amet spernzaln nimma wia gscheid af wos gwiss schüds nei Weibaleid und glei wirds no fui lustiga? Mi Kaiwe und Graudwiggal, pfundig! Is des liab und wea nia ausgähd, kummt nia hoam Zwedschgndadschi dahoam Leonhardifahrt nix Gwiass woass ma ned back mas, Wurscht. Soi im Beidl bittschön Trachtnhuat, Spotzerl Biazelt. Glacht du dadst ma scho daugn auf gehds beim Schichtl Brotzeit Mamalad Schbozal Kirwa is, hoggd dahoam! Schneid san mi, hallelujah sog i, luja ja, wo samma denn Auffisteign gfreit mi hogg di hera auf der Oim, da gibt’s koa Sünd. Kimmt auszutzeln auf der Oim, da gibt’s koa Sünd Kaiwe Fünferl, i des is a gmahde Wiesn Watschnpladdla mehra hogg di hera Vergeltsgott. Griasnoggalsubbm gwiss nois hallelujah sog i, luja, Fingahaggln di. Kimmt auf gehds beim Schichtl i hab an do legst di nieda, Hemad sei mogsd a Bussal Blosmusi. Weibaleid a Marei gscheckate a liabs Deandl nia oans, zwoa, gsuffa Blosmusi. Zwedschgndadschi gscheid Weibaleid, Biagadn do legst di nieda Meidromml nix Gwiass woass ma ned hoam Obazda. Bussal von i mog di fei Zwedschgndadschi i Goaßmaß sammawiedaguad i bin a woschechta Bayer! Kimmt hinter’m Berg san a no Leit hi sammawiedaguad gscheckate, mogsd a Bussal Biakriagal nix Sauwedda. Hallelujah sog i, luja auffi Breihaus so Gaudi Obazda Sauakraud ham, du dadst ma scho daugn. Schmankal obandeln du dadst ma scho daugn, Schaung kost nix Broadwurschtbudn an resch i bin a woschechta Bayer Hetschapfah um Godds wujn! Des is a gmahde Wiesn hoggd i waar soweid sog i. Breihaus Xaver iabaroi weida gwiss, Buam. Moand af no a Maß a Hoiwe, do Schdeckalfisch ozapfa fias gscheit Ramasuri! Wolln a Maß und no a Maß Breihaus, wui nia need oba so schee Kuaschwanz. Trihöleridi dijidiholleri zünftig Namidog Griasnoggalsubbm vui so mechad des is a gmahde Wiesn guad hod. No a Maß back mas allerweil pfundig Wiesn, Griasnoggalsubbm! Hoggd gar nia need Schneid, Hemad Gamsbart Musi: Hoid mechad Zwedschgndadschi nimma Sepp Mamalad nimmds no. Radi Biagadn bittschön, sowos Zidern. Kumm geh lem und lem lossn Servas nia need ghupft wia gsprunga vo de Radler des is a gmahde Wiesn? De Sonn etza i ned sammawiedaguad Wurscht, wea ko, dea ko? Jo mei nois Bladl a ganze Fingahaggln Wurscht anbandeln a des is schee. Aba g’hupft wia gsprunga lem und lem lossn Gams do, Reiwadatschi des dahoam no a Maß des is a gmahde Wiesn. Is ma Wuascht i hab an a liabs Deandl Almrausch wuid Ramasuri, es wia. I mog di fei wolln Schorsch kummd Fingahaggln, Radi in da pfiad de sog i aasgem? Großherzig nackata des basd scho Almrausch hod. Dahoam wui Gschicht no a Maß Brodzeid, sauba nimmds! Fingahaggln mim wia da Buachbinda Wanninger Obazda, i hob di narrisch gean gscheckate hea. Zwoa mim Radl foahn Haberertanz wos back mas Kuaschwanz nia Namidog hoid. Heid gfoids ma sagrisch guad da, hog di hi so sog i Zidern hoid gwiss eam. Am acht’n Tag schuf Gott des Bia allerweil sog i singd. Biazelt pfenningguat Haberertanz blärrd di is, gor Steckerleis da? Kumm geh koa g’hupft wia gsprunga a liabs Deandl Graudwiggal kimmt nia Almrausch. Etza in da greana Au Wurschtsolod Diandldrahn mogsd a Bussal, so. Maibam sauba Baamwach, hoggd owe Gaudi Edlweiss baddscher Radler oba. Dahoam schoo schaugn wos a liabs Deandl, gfreit mi! Hetschapfah sog i Biazelt blärrd Weiznglasl gelbe Rüam obandeln, helfgod i daad. Singan Kneedl Klampfn singd um Godds wujn, a Habedehre. Midanand Gidarn barfuaßat gschmeidig Habedehre Zwedschgndadschi, Watschnpladdla. Om auf’n Gipfe auf gehds beim Schichtl a Maß und no a Maß, trihöleridi dijidiholleri! Guglhupf Wurscht blärrd de damischa, weida amoi oamoi. Vergeltsgott hogg ma uns zamm wos nia need. Auf gehds beim Schichtl Almrausch Maderln woaß gscheid. Am acht’n Tag schuf Gott des Bia Oachkatzlschwoaf Trachtnhuat unbandig Biaschlegl kummd hoid, gwihss midanand da. Om auf’n Gipfe hawadere midananda etza, pfiad de. Wiavui san gfreit mi pfiad de i hab an Engelgwand hod Klampfn dringma aweng ham! Biaschlegl dahoam i mogsd a Bussal.";
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    /*  SHA-1 implementation in JavaScript | (c) Chris Veness 2002-2013 | www.movable-type.co.uk      */
    /*   - see http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html                             */
    /*         http://csrc.nist.gov/groups/ST/toolkit/examples.html                                   */
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    var Sha1 = {};  // Sha1 namespace
    
    /**
     * Generates SHA-1 hash of string
     *
     * @param {String} msg                String to be hashed
     * @param {Boolean} [utf8encode=true] Encode msg as UTF-8 before generating hash
     * @returns {String}                  Hash of msg as hex character string
     */
    Sha1.hash = function(msg, utf8encode) {
      utf8encode =  (typeof utf8encode == 'undefined') ? true : utf8encode;
      
      // convert string to UTF-8, as SHA only deals with byte-streams
      if (utf8encode) msg = Utf8.encode(msg);
      
      // constants [§4.2.1]
      var K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
      
      // PREPROCESSING 
      
      msg += String.fromCharCode(0x80);  // add trailing '1' bit (+ 0's padding) to string [§5.1.1]
      
      // convert string msg into 512-bit/16-integer blocks arrays of ints [§5.2.1]
      var l = msg.length/4 + 2;  // length (in 32-bit integers) of msg + ‘1’ + appended length
      var N = Math.ceil(l/16);   // number of 16-integer-blocks required to hold 'l' ints
      var M = new Array(N);
      
      for (var i=0; i<N; i++) {
        M[i] = new Array(16);
        for (var j=0; j<16; j++) {  // encode 4 chars per integer, big-endian encoding
          M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) | 
            (msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3));
        } // note running off the end of msg is ok 'cos bitwise ops on NaN return 0
      }
      // add length (in bits) into final pair of 32-bit integers (big-endian) [§5.1.1]
      // note: most significant word would be (len-1)*8 >>> 32, but since JS converts
      // bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
      M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14])
      M[N-1][15] = ((msg.length-1)*8) & 0xffffffff;
      
      // set initial hash value [§5.3.1]
      var H0 = 0x67452301;
      var H1 = 0xefcdab89;
      var H2 = 0x98badcfe;
      var H3 = 0x10325476;
      var H4 = 0xc3d2e1f0;
      
      // HASH COMPUTATION [§6.1.2]
      
      var W = new Array(80); var a, b, c, d, e;
      for (var i=0; i<N; i++) {
      
        // 1 - prepare message schedule 'W'
        for (var t=0;  t<16; t++) W[t] = M[i][t];
        for (var t=16; t<80; t++) W[t] = Sha1.ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
        
        // 2 - initialise five working variables a, b, c, d, e with previous hash value
        a = H0; b = H1; c = H2; d = H3; e = H4;
        
        // 3 - main loop
        for (var t=0; t<80; t++) {
          var s = Math.floor(t/20); // seq for blocks of 'f' functions and 'K' constants
          var T = (Sha1.ROTL(a,5) + Sha1.f(s,b,c,d) + e + K[s] + W[t]) & 0xffffffff;
          e = d;
          d = c;
          c = Sha1.ROTL(b, 30);
          b = a;
          a = T;
        }
        
        // 4 - compute the new intermediate hash value
        H0 = (H0+a) & 0xffffffff;  // note 'addition modulo 2^32'
        H1 = (H1+b) & 0xffffffff; 
        H2 = (H2+c) & 0xffffffff; 
        H3 = (H3+d) & 0xffffffff; 
        H4 = (H4+e) & 0xffffffff;
      }
    
      return Sha1.toHexStr(H0) + Sha1.toHexStr(H1) + 
        Sha1.toHexStr(H2) + Sha1.toHexStr(H3) + Sha1.toHexStr(H4);
    }
    
    //
    // function 'f' [§4.1.1]
    //
    Sha1.f = function(s, x, y, z)  {
      switch (s) {
      case 0: return (x & y) ^ (~x & z);           // Ch()
      case 1: return x ^ y ^ z;                    // Parity()
      case 2: return (x & y) ^ (x & z) ^ (y & z);  // Maj()
      case 3: return x ^ y ^ z;                    // Parity()
      }
    }
    
    //
    // rotate left (circular left shift) value x by n positions [§3.2.5]
    //
    Sha1.ROTL = function(x, n) {
      return (x<<n) | (x>>>(32-n));
    }
    
    //
    // hexadecimal representation of a number 
    //   (note toString(16) is implementation-dependant, and  
    //   in IE returns signed numbers when used on full words)
    //
    Sha1.toHexStr = function(n) {
      var s="", v;
      for (var i=7; i>=0; i--) { v = (n>>>(i*4)) & 0xf; s += v.toString(16); }
      return s;
    }
    
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    /*  Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple          */
    /*              single-byte character encoding (c) Chris Veness 2002-2013                         */
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    var Utf8 = {};  // Utf8 namespace
    
    /**
     * Encode multi-byte Unicode string into utf-8 multiple single-byte characters 
     * (BMP / basic multilingual plane only)
     *
     * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars
     *
     * @param {String} strUni Unicode string to be encoded as UTF-8
     * @returns {String} encoded string
     */
    Utf8.encode = function(strUni) {
      // use regular expressions & String.replace callback function for better efficiency 
      // than procedural approaches
      var strUtf = strUni.replace(
          /[\u0080-\u07ff]/g,  // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz
          function(c) { 
            var cc = c.charCodeAt(0);
            return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }
        );
      strUtf = strUtf.replace(
          /[\u0800-\uffff]/g,  // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz
          function(c) { 
            var cc = c.charCodeAt(0); 
            return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }
        );
      return strUtf;
    }
    
    /**
     * Decode utf-8 encoded string back into multi-byte Unicode characters
     *
     * @param {String} strUtf UTF-8 string to be decoded back to Unicode
     * @returns {String} decoded string
     */
    Utf8.decode = function(strUtf) {
      // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char!
      var strUni = strUtf.replace(
          /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,  // 3-byte chars
          function(c) {  // (note parentheses for precence)
            var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f); 
            return String.fromCharCode(cc); }
        );
      strUni = strUni.replace(
          /[\u00c0-\u00df][\u0080-\u00bf]/g,                 // 2-byte chars
          function(c) {  // (note parentheses for precence)
            var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;
            return String.fromCharCode(cc); }
        );
      return strUni;
    }
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    /*  SHA-256 implementation in JavaScript | (c) Chris Veness 2002-2010 | www.movable-type.co.uk    */
    /*   - see http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html                             */
    /*         http://csrc.nist.gov/groups/ST/toolkit/examples.html                                   */
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    var Sha256 = {};  // Sha256 namespace
    
    /**
     * Generates SHA-256 hash of string
     *
     * @param {String} msg                String to be hashed
     * @param {Boolean} [utf8encode=true] Encode msg as UTF-8 before generating hash
     * @returns {String}                  Hash of msg as hex character string
     */
    Sha256.hash = function(msg, utf8encode) {
        utf8encode =  (typeof utf8encode == 'undefined') ? true : utf8encode;
        
        // convert string to UTF-8, as SHA only deals with byte-streams
        if (utf8encode) msg = Utf8.encode(msg);
        
        // constants [§4.2.2]
        var K = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
                 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
                 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
                 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
                 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
                 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
                 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
                 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
        // initial hash value [§5.3.1]
        var H = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
    
        // PREPROCESSING 
     
        msg += String.fromCharCode(0x80);  // add trailing '1' bit (+ 0's padding) to string [§5.1.1]
    
        // convert string msg into 512-bit/16-integer blocks arrays of ints [§5.2.1]
        var l = msg.length/4 + 2;  // length (in 32-bit integers) of msg + ‘1’ + appended length
        var N = Math.ceil(l/16);   // number of 16-integer-blocks required to hold 'l' ints
        var M = new Array(N);
    
        for (var i=0; i<N; i++) {
            M[i] = new Array(16);
            for (var j=0; j<16; j++) {  // encode 4 chars per integer, big-endian encoding
                M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) | 
                          (msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3));
            } // note running off the end of msg is ok 'cos bitwise ops on NaN return 0
        }
        // add length (in bits) into final pair of 32-bit integers (big-endian) [§5.1.1]
        // note: most significant word would be (len-1)*8 >>> 32, but since JS converts
        // bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
        M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14])
        M[N-1][15] = ((msg.length-1)*8) & 0xffffffff;
    
    
        // HASH COMPUTATION [§6.1.2]
    
        var W = new Array(64); var a, b, c, d, e, f, g, h;
        for (var i=0; i<N; i++) {
    
            // 1 - prepare message schedule 'W'
            for (var t=0;  t<16; t++) W[t] = M[i][t];
            for (var t=16; t<64; t++) W[t] = (Sha256.sigma1(W[t-2]) + W[t-7] + Sha256.sigma0(W[t-15]) + W[t-16]) & 0xffffffff;
    
            // 2 - initialise working variables a, b, c, d, e, f, g, h with previous hash value
            a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7];
    
            // 3 - main loop (note 'addition modulo 2^32')
            for (var t=0; t<64; t++) {
                var T1 = h + Sha256.Sigma1(e) + Sha256.Ch(e, f, g) + K[t] + W[t];
                var T2 = Sha256.Sigma0(a) + Sha256.Maj(a, b, c);
                h = g;
                g = f;
                f = e;
                e = (d + T1) & 0xffffffff;
                d = c;
                c = b;
                b = a;
                a = (T1 + T2) & 0xffffffff;
            }
             // 4 - compute the new intermediate hash value (note 'addition modulo 2^32')
            H[0] = (H[0]+a) & 0xffffffff;
            H[1] = (H[1]+b) & 0xffffffff; 
            H[2] = (H[2]+c) & 0xffffffff; 
            H[3] = (H[3]+d) & 0xffffffff; 
            H[4] = (H[4]+e) & 0xffffffff;
            H[5] = (H[5]+f) & 0xffffffff;
            H[6] = (H[6]+g) & 0xffffffff; 
            H[7] = (H[7]+h) & 0xffffffff; 
        }
    
        return Sha256.toHexStr(H[0]) + Sha256.toHexStr(H[1]) + Sha256.toHexStr(H[2]) + Sha256.toHexStr(H[3]) + 
               Sha256.toHexStr(H[4]) + Sha256.toHexStr(H[5]) + Sha256.toHexStr(H[6]) + Sha256.toHexStr(H[7]);
    }
    
    Sha256.ROTR = function(n, x) { return (x >>> n) | (x << (32-n)); }
    Sha256.Sigma0 = function(x) { return Sha256.ROTR(2,  x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); }
    Sha256.Sigma1 = function(x) { return Sha256.ROTR(6,  x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); }
    Sha256.sigma0 = function(x) { return Sha256.ROTR(7,  x) ^ Sha256.ROTR(18, x) ^ (x>>>3);  }
    Sha256.sigma1 = function(x) { return Sha256.ROTR(17, x) ^ Sha256.ROTR(19, x) ^ (x>>>10); }
    Sha256.Ch = function(x, y, z)  { return (x & y) ^ (~x & z); }
    Sha256.Maj = function(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); }
    
    //
    // hexadecimal representation of a number 
    //   (note toString(16) is implementation-dependant, and  
    //   in IE returns signed numbers when used on full words)
    //
    Sha256.toHexStr = function(n) {
      var s="", v;
      for (var i=7; i>=0; i--) { v = (n>>>(i*4)) & 0xf; s += v.toString(16); }
      return s;
    }
    
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    /*  Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple          */
    /*              single-byte character encoding (c) Chris Veness 2002-2010                         */
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    
    var Utf8 = {};  // Utf8 namespace
    
    /**
     * Encode multi-byte Unicode string into utf-8 multiple single-byte characters 
     * (BMP / basic multilingual plane only)
     *
     * Chars in range U+0080 - U+07FF are encoded in 2 chars, U+0800 - U+FFFF in 3 chars
     *
     * @param {String} strUni Unicode string to be encoded as UTF-8
     * @returns {String} encoded string
     */
    Utf8.encode = function(strUni) {
      // use regular expressions & String.replace callback function for better efficiency 
      // than procedural approaches
      var strUtf = strUni.replace(
          /[\u0080-\u07ff]/g,  // U+0080 - U+07FF => 2 bytes 110yyyyy, 10zzzzzz
          function(c) { 
            var cc = c.charCodeAt(0);
            return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }
        );
      strUtf = strUtf.replace(
          /[\u0800-\uffff]/g,  // U+0800 - U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz
          function(c) { 
            var cc = c.charCodeAt(0); 
            return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }
        );
      return strUtf;
    }
    
    /**
     * Decode utf-8 encoded string back into multi-byte Unicode characters
     *
     * @param {String} strUtf UTF-8 string to be decoded back to Unicode
     * @returns {String} decoded string
     */
    Utf8.decode = function(strUtf) {
      // note: decode 3-byte chars first as decoded 2-byte strings could appear to be 3-byte char!
      var strUni = strUtf.replace(
          /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,  // 3-byte chars
          function(c) {  // (note parentheses for precence)
            var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f); 
            return String.fromCharCode(cc); }
        );
      strUni = strUni.replace(
          /[\u00c0-\u00df][\u0080-\u00bf]/g,                 // 2-byte chars
          function(c) {  // (note parentheses for precence)
            var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;
            return String.fromCharCode(cc); }
        );
      return strUni;
    }
    
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
    /*
     * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
     * in FIPS 180-1
     * Version 2.2 Copyright Paul Johnston 2000 - 2009.
     * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
     * Distributed under the BSD License
     * See http://pajhome.org.uk/crypt/md5 for details.
     */
    
    /*
     * Configurable variables. You may need to tweak these to be compatible with
     * the server-side, but the defaults work in most cases.
     */
    var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
    var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
    
    /*
     * These are the functions you'll usually want to call
     * They take string arguments and return either hex or base-64 encoded strings
     */
    function hex_sha1(s)    { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
    function b64_sha1(s)    { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
    function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
    function hex_hmac_sha1(k, d)
      { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
    function b64_hmac_sha1(k, d)
      { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
    function any_hmac_sha1(k, d, e)
      { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
    
    /*
     * Perform a simple self-test to see if the VM is working
     */
    function sha1_vm_test()
    {
      return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
    }
    
    /*
     * Calculate the SHA1 of a raw string
     */
    function rstr_sha1(s)
    {
      return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
    }
    
    /*
     * Calculate the HMAC-SHA1 of a key and some data (raw strings)
     */
    function rstr_hmac_sha1(key, data)
    {
      var bkey = rstr2binb(key);
      if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
    
      var ipad = Array(16), opad = Array(16);
      for(var i = 0; i < 16; i++)
      {
        ipad[i] = bkey[i] ^ 0x36363636;
        opad[i] = bkey[i] ^ 0x5C5C5C5C;
      }
    
      var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
      return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
    }
    
    /*
     * Convert a raw string to a hex string
     */
    function rstr2hex(input)
    {
      try { hexcase } catch(e) { hexcase=0; }
      var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
      var output = "";
      var x;
      for(var i = 0; i < input.length; i++)
      {
        x = input.charCodeAt(i);
        output += hex_tab.charAt((x >>> 4) & 0x0F)
               +  hex_tab.charAt( x        & 0x0F);
      }
      return output;
    }
    
    /*
     * Convert a raw string to a base-64 string
     */
    function rstr2b64(input)
    {
      try { b64pad } catch(e) { b64pad=''; }
      var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      var output = "";
      var len = input.length;
      for(var i = 0; i < len; i += 3)
      {
        var triplet = (input.charCodeAt(i) << 16)
                    | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
                    | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
        for(var j = 0; j < 4; j++)
        {
          if(i * 8 + j * 6 > input.length * 8) output += b64pad;
          else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
        }
      }
      return output;
    }
    
    /*
     * Convert a raw string to an arbitrary string encoding
     */
    function rstr2any(input, encoding)
    {
      var divisor = encoding.length;
      var remainders = Array();
      var i, q, x, quotient;
    
      /* Convert to an array of 16-bit big-endian values, forming the dividend */
      var dividend = Array(Math.ceil(input.length / 2));
      for(i = 0; i < dividend.length; i++)
      {
        dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
      }
    
      /*
       * Repeatedly perform a long division. The binary array forms the dividend,
       * the length of the encoding is the divisor. Once computed, the quotient
       * forms the dividend for the next step. We stop when the dividend is zero.
       * All remainders are stored for later use.
       */
      while(dividend.length > 0)
      {
        quotient = Array();
        x = 0;
        for(i = 0; i < dividend.length; i++)
        {
          x = (x << 16) + dividend[i];
          q = Math.floor(x / divisor);
          x -= q * divisor;
          if(quotient.length > 0 || q > 0)
            quotient[quotient.length] = q;
        }
        remainders[remainders.length] = x;
        dividend = quotient;
      }
    
      /* Convert the remainders to the output string */
      var output = "";
      for(i = remainders.length - 1; i >= 0; i--)
        output += encoding.charAt(remainders[i]);
    
      /* Append leading zero equivalents */
      var full_length = Math.ceil(input.length * 8 /
                                        (Math.log(encoding.length) / Math.log(2)))
      for(i = output.length; i < full_length; i++)
        output = encoding[0] + output;
    
      return output;
    }
    
    /*
     * Encode a string as utf-8.
     * For efficiency, this assumes the input is valid utf-16.
     */
    function str2rstr_utf8(input)
    {
      var output = "";
      var i = -1;
      var x, y;
    
      while(++i < input.length)
      {
        /* Decode utf-16 surrogate pairs */
        x = input.charCodeAt(i);
        y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
        if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
        {
          x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
          i++;
        }
    
        /* Encode output as utf-8 */
        if(x <= 0x7F)
          output += String.fromCharCode(x);
        else if(x <= 0x7FF)
          output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
                                        0x80 | ( x         & 0x3F));
        else if(x <= 0xFFFF)
          output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
                                        0x80 | ((x >>> 6 ) & 0x3F),
                                        0x80 | ( x         & 0x3F));
        else if(x <= 0x1FFFFF)
          output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
                                        0x80 | ((x >>> 12) & 0x3F),
                                        0x80 | ((x >>> 6 ) & 0x3F),
                                        0x80 | ( x         & 0x3F));
      }
      return output;
    }
    
    /*
     * Encode a string as utf-16
     */
    function str2rstr_utf16le(input)
    {
      var output = "";
      for(var i = 0; i < input.length; i++)
        output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
                                      (input.charCodeAt(i) >>> 8) & 0xFF);
      return output;
    }
    
    function str2rstr_utf16be(input)
    {
      var output = "";
      for(var i = 0; i < input.length; i++)
        output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
                                       input.charCodeAt(i)        & 0xFF);
      return output;
    }
    
    /*
     * Convert a raw string to an array of big-endian words
     * Characters >255 have their high-byte silently ignored.
     */
    function rstr2binb(input)
    {
      var output = Array(input.length >> 2);
      for(var i = 0; i < output.length; i++)
        output[i] = 0;
      for(var i = 0; i < input.length * 8; i += 8)
        output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
      return output;
    }
    
    /*
     * Convert an array of big-endian words to a string
     */
    function binb2rstr(input)
    {
      var output = "";
      for(var i = 0; i < input.length * 32; i += 8)
        output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
      return output;
    }
    
    /*
     * Calculate the SHA-1 of an array of big-endian words, and a bit length
     */
    function binb_sha1(x, len)
    {
      /* append padding */
      x[len >> 5] |= 0x80 << (24 - len % 32);
      x[((len + 64 >> 9) << 4) + 15] = len;
    
      var w = Array(80);
      var a =  1732584193;
      var b = -271733879;
      var c = -1732584194;
      var d =  271733878;
      var e = -1009589776;
    
      for(var i = 0; i < x.length; i += 16)
      {
        var olda = a;
        var oldb = b;
        var oldc = c;
        var oldd = d;
        var olde = e;
    
        for(var j = 0; j < 80; j++)
        {
          if(j < 16) w[j] = x[i + j];
          else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
          var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
                           safe_add(safe_add(e, w[j]), sha1_kt(j)));
          e = d;
          d = c;
          c = bit_rol(b, 30);
          b = a;
          a = t;
        }
    
        a = safe_add(a, olda);
        b = safe_add(b, oldb);
        c = safe_add(c, oldc);
        d = safe_add(d, oldd);
        e = safe_add(e, olde);
      }
      return Array(a, b, c, d, e);
    
    }
    
    /*
     * Perform the appropriate triplet combination function for the current
     * iteration
     */
    function sha1_ft(t, b, c, d)
    {
      if(t < 20) return (b & c) | ((~b) & d);
      if(t < 40) return b ^ c ^ d;
      if(t < 60) return (b & c) | (b & d) | (c & d);
      return b ^ c ^ d;
    }
    
    /*
     * Determine the appropriate additive constant for the current iteration
     */
    function sha1_kt(t)
    {
      return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
             (t < 60) ? -1894007588 : -899497514;
    }
    
    /*
     * Add integers, wrapping at 2^32. This uses 16-bit operations internally
     * to work around bugs in some JS interpreters.
     */
    function safe_add(x, y)
    {
      var lsw = (x & 0xFFFF) + (y & 0xFFFF);
      var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
      return (msw << 16) | (lsw & 0xFFFF);
    }
    
    /*
     * Bitwise rotate a 32-bit number to the left.
     */
    function bit_rol(num, cnt)
    {
      return (num << cnt) | (num >>> (32 - cnt));
    }
    
    /*
     * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
     * in FIPS 180-2
     * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
     * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
     * Distributed under the BSD License
     * See http://pajhome.org.uk/crypt/md5 for details.
     * Also http://anmar.eu.org/projects/jssha2/
     */
    
    /*
     * Configurable variables. You may need to tweak these to be compatible with
     * the server-side, but the defaults work in most cases.
     */
    var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
    var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
    
    /*
     * These are the functions you'll usually want to call
     * They take string arguments and return either hex or base-64 encoded strings
     */
    function hex_sha256(s)    { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); }
    function b64_sha256(s)    { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); }
    function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); }
    function hex_hmac_sha256(k, d)
      { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
    function b64_hmac_sha256(k, d)
      { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
    function any_hmac_sha256(k, d, e)
      { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
    
    /*
     * Perform a simple self-test to see if the VM is working
     */
    function sha256_vm_test()
    {
      return hex_sha256("abc").toLowerCase() ==
                "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
    }
    
    /*
     * Calculate the sha256 of a raw string
     */
    function rstr_sha256(s)
    {
      return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
    }
    
    /*
     * Calculate the HMAC-sha256 of a key and some data (raw strings)
     */
    function rstr_hmac_sha256(key, data)
    {
      var bkey = rstr2binb(key);
      if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8);
    
      var ipad = Array(16), opad = Array(16);
      for(var i = 0; i < 16; i++)
      {
        ipad[i] = bkey[i] ^ 0x36363636;
        opad[i] = bkey[i] ^ 0x5C5C5C5C;
      }
    
      var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
      return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256));
    }
    
    /*
     * Convert a raw string to a hex string
     */
    function rstr2hex(input)
    {
      try { hexcase } catch(e) { hexcase=0; }
      var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
      var output = "";
      var x;
      for(var i = 0; i < input.length; i++)
      {
        x = input.charCodeAt(i);
        output += hex_tab.charAt((x >>> 4) & 0x0F)
               +  hex_tab.charAt( x        & 0x0F);
      }
      return output;
    }
    
    /*
     * Convert a raw string to a base-64 string
     */
    function rstr2b64(input)
    {
      try { b64pad } catch(e) { b64pad=''; }
      var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      var output = "";
      var len = input.length;
      for(var i = 0; i < len; i += 3)
      {
        var triplet = (input.charCodeAt(i) << 16)
                    | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
                    | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
        for(var j = 0; j < 4; j++)
        {
          if(i * 8 + j * 6 > input.length * 8) output += b64pad;
          else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
        }
      }
      return output;
    }
    
    /*
     * Convert a raw string to an arbitrary string encoding
     */
    function rstr2any(input, encoding)
    {
      var divisor = encoding.length;
      var remainders = Array();
      var i, q, x, quotient;
    
      /* Convert to an array of 16-bit big-endian values, forming the dividend */
      var dividend = Array(Math.ceil(input.length / 2));
      for(i = 0; i < dividend.length; i++)
      {
        dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
      }
    
      /*
       * Repeatedly perform a long division. The binary array forms the dividend,
       * the length of the encoding is the divisor. Once computed, the quotient
       * forms the dividend for the next step. We stop when the dividend is zero.
       * All remainders are stored for later use.
       */
      while(dividend.length > 0)
      {
        quotient = Array();
        x = 0;
        for(i = 0; i < dividend.length; i++)
        {
          x = (x << 16) + dividend[i];
          q = Math.floor(x / divisor);
          x -= q * divisor;
          if(quotient.length > 0 || q > 0)
            quotient[quotient.length] = q;
        }
        remainders[remainders.length] = x;
        dividend = quotient;
      }
    
      /* Convert the remainders to the output string */
      var output = "";
      for(i = remainders.length - 1; i >= 0; i--)
        output += encoding.charAt(remainders[i]);
    
      /* Append leading zero equivalents */
      var full_length = Math.ceil(input.length * 8 /
                                        (Math.log(encoding.length) / Math.log(2)))
      for(i = output.length; i < full_length; i++)
        output = encoding[0] + output;
    
      return output;
    }
    
    /*
     * Encode a string as utf-8.
     * For efficiency, this assumes the input is valid utf-16.
     */
    function str2rstr_utf8(input)
    {
      var output = "";
      var i = -1;
      var x, y;
    
      while(++i < input.length)
      {
        /* Decode utf-16 surrogate pairs */
        x = input.charCodeAt(i);
        y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
        if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
        {
          x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
          i++;
        }
    
        /* Encode output as utf-8 */
        if(x <= 0x7F)
          output += String.fromCharCode(x);
        else if(x <= 0x7FF)
          output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
                                        0x80 | ( x         & 0x3F));
        else if(x <= 0xFFFF)
          output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
                                        0x80 | ((x >>> 6 ) & 0x3F),
                                        0x80 | ( x         & 0x3F));
        else if(x <= 0x1FFFFF)
          output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
                                        0x80 | ((x >>> 12) & 0x3F),
                                        0x80 | ((x >>> 6 ) & 0x3F),
                                        0x80 | ( x         & 0x3F));
      }
      return output;
    }
    
    /*
     * Encode a string as utf-16
     */
    function str2rstr_utf16le(input)
    {
      var output = "";
      for(var i = 0; i < input.length; i++)
        output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
                                      (input.charCodeAt(i) >>> 8) & 0xFF);
      return output;
    }
    
    function str2rstr_utf16be(input)
    {
      var output = "";
      for(var i = 0; i < input.length; i++)
        output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
                                       input.charCodeAt(i)        & 0xFF);
      return output;
    }
    
    /*
     * Convert a raw string to an array of big-endian words
     * Characters >255 have their high-byte silently ignored.
     */
    function rstr2binb(input)
    {
      var output = Array(input.length >> 2);
      for(var i = 0; i < output.length; i++)
        output[i] = 0;
      for(var i = 0; i < input.length * 8; i += 8)
        output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
      return output;
    }
    
    /*
     * Convert an array of big-endian words to a string
     */
    function binb2rstr(input)
    {
      var output = "";
      for(var i = 0; i < input.length * 32; i += 8)
        output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
      return output;
    }
    
    /*
     * Main sha256 function, with its support functions
     */
    function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));}
    function sha256_R (X, n) {return ( X >>> n );}
    function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
    function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
    function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
    function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
    function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
    function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
    function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
    function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
    function sha256_Gamma0512(x) {return (sha256_S(x, 1)  ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
    function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
    
    var sha256_K = new Array
    (
      1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
      -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
      1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
      264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
      -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
      113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
      1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
      -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
      430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
      1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
      -1866530822, -1538233109, -1090935817, -965641998
    );
    
    function binb_sha256(m, l)
    {
      var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534,
                           1359893119, -1694144372, 528734635, 1541459225);
      var W = new Array(64);
      var a, b, c, d, e, f, g, h;
      var i, j, T1, T2;
    
      /* append padding */
      m[l >> 5] |= 0x80 << (24 - l % 32);
      m[((l + 64 >> 9) << 4) + 15] = l;
    
      for(i = 0; i < m.length; i += 16)
      {
        a = HASH[0];
        b = HASH[1];
        c = HASH[2];
        d = HASH[3];
        e = HASH[4];
        f = HASH[5];
        g = HASH[6];
        h = HASH[7];
    
        for(j = 0; j < 64; j++)
        {
          if (j < 16) W[j] = m[j + i];
          else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
                                                sha256_Gamma0256(W[j - 15])), W[j - 16]);
    
          T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
                                                              sha256_K[j]), W[j]);
          T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
          h = g;
          g = f;
          f = e;
          e = safe_add(d, T1);
          d = c;
          c = b;
          b = a;
          a = safe_add(T1, T2);
        }
    
        HASH[0] = safe_add(a, HASH[0]);
        HASH[1] = safe_add(b, HASH[1]);
        HASH[2] = safe_add(c, HASH[2]);
        HASH[3] = safe_add(d, HASH[3]);
        HASH[4] = safe_add(e, HASH[4]);
        HASH[5] = safe_add(f, HASH[5]);
        HASH[6] = safe_add(g, HASH[6]);
        HASH[7] = safe_add(h, HASH[7]);
      }
      return HASH;
    }
    
    function safe_add (x, y)
    {
      var lsw = (x & 0xFFFF) + (y & 0xFFFF);
      var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
      return (msw << 16) | (lsw & 0xFFFF);
    }
    
    var nacl = require('js-nacl');

Test runner

Ready to run.

Testing in
TestOps/sec
sha1: Movable Type
var hash = Sha1.hash(ipsum);
ready
sha1: pajhome.org.uk/crypt/md5
var hash = hex_sha1(ipsum)
ready
sha1: CryptoJS
var hash = CryptoJS.SHA1(ipsum);
ready
sha256: sjcl
var bitArray = sjcl.hash.sha256.hash(ipsum);  
var hash = sjcl.codec.hex.fromBits(bitArray);  
ready
sha256: pajhome.org.uk/crypt/md5
var hash = hex_sha256(ipsum);
ready
sha256: CryptoJS
var hash = CryptoJS.SHA256(ipsum);
ready
sha256: Movable Type
var hash = Sha256.hash(ipsum);
ready
sha256: js-nacl
var ipsumUint8Array = nacl.encode_utf8(ipsum);
hashTmp = nacl.crypto_hash_sha256(ipsumUint8Array);
hash = nacl.to_hex(hashTmp);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.