From bae387d0b2534ea186eaf4c323baa4e98698c59b Mon Sep 17 00:00:00 2001 From: "Chen, Yi-Cyuan" Date: Tue, 24 Jan 2017 13:47:26 +0800 Subject: [PATCH] Added streaming support #6 --- .npmignore | 1 - CHANGELOG.md | 4 + README.md | 79 ++++---- bower.json | 2 +- build/sha256.min.js | 4 +- package.json | 2 +- src/sha256.js | 454 +++++++++++++++++++++++++++++--------------- tests/test.js | 322 +++++++++++++++++++++---------- 8 files changed, 567 insertions(+), 301 deletions(-) delete mode 100644 .npmignore diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 073109d..0000000 --- a/.npmignore +++ /dev/null @@ -1 +0,0 @@ -covreporter diff --git a/CHANGELOG.md b/CHANGELOG.md index 49e8168..2cb7a63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## v0.5.0 / 2017-01-24 +### Added +- Streaming support #6 + ## v0.4.0 / 2017-01-23 ### Added - AMD support. diff --git a/README.md b/README.md index 24119fa..5bc1d32 100644 --- a/README.md +++ b/README.md @@ -27,59 +27,54 @@ You could use like this: ```JavaScript sha256('Message to hash'); sha224('Message to hash'); + +var hash = sha256.create(); +hash.update('Message to hash'); +hash.hex(); + +var hash2 = sha256.update('Message to hash'); +hash2.update('Message2 to hash'); +hash2.array(); ``` If you use node.js, you should require the module first: ```JavaScript -sha256 = require('js-sha256'); +var sha256 = require('js-sha256'); ``` or ```JavaScript -sha256 = require('js-sha256').sha256; -sha224 = require('js-sha256').sha224; +var sha256 = require('js-sha256').sha256; +var sha224 = require('js-sha256').sha224; ``` - -## Example -Code -```JavaScript -sha256(''); -sha256('The quick brown fox jumps over the lazy dog'); -sha256('The quick brown fox jumps over the lazy dog.'); -sha224(''); -sha224('The quick brown fox jumps over the lazy dog'); -sha224('The quick brown fox jumps over the lazy dog.'); -``` -Output - - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592 - ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c - d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f - 730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525 - 619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c - -It also supports UTF-8 encoding: - -Code +It supports AMD: ```JavaScript -sha256('中文'); -sha224('中文'); +require(['your/path/sha256.js'], function(sha256) { +// ... +}); ``` -Output - - 72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21 - dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4 - -It also supports byte `Array`, `Uint8Array`, `ArrayBuffer` input: - -Code +## Example ```JavaScript -sha256([]); -sha256(new Uint8Array([211, 212])); +sha256(''); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256('The quick brown fox jumps over the lazy dog'); // d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592 +sha256('The quick brown fox jumps over the lazy dog.'); // ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c +sha224(''); // d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f +sha224('The quick brown fox jumps over the lazy dog'); // 730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525 +sha224('The quick brown fox jumps over the lazy dog.'); // 619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c + +// It also supports UTF-8 encoding +sha256('中文'); // 72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21 +sha224('中文'); // dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4 + +// It also supports byte `Array`, `Uint8Array`, `ArrayBuffer` input +sha256([]); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256(new Uint8Array([211, 212])); // 182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f + +// Different output +sha256(''); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256.hex(''); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +sha256.array(''); // [227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85] +sha256.digest(''); // [227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85] +sha256.arrayBuffer(''); // ArrayBuffer ``` -Output - - e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - 182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f ## License The project is released under the [MIT license](http://www.opensource.org/licenses/MIT). diff --git a/bower.json b/bower.json index ee0c43a..c205b1e 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "js-sha256", - "version": "0.4.0", + "version": "0.5.0", "main": ["src/sha256.js"], "ignore": [ "samples", diff --git a/build/sha256.min.js b/build/sha256.min.js index 4163e8b..d217181 100644 --- a/build/sha256.min.js +++ b/build/sha256.min.js @@ -1,9 +1,9 @@ /** * [js-sha256]{@link https://github.com/emn178/js-sha256} * - * @version 0.4.0 + * @version 0.5.0 * @author Chen, Yi-Cyuan [emn178@gmail.com] * @copyright Chen, Yi-Cyuan 2014-2017 * @license MIT */ -!function(){"use strict";var e="object"==typeof window?window:{},o=!e.JS_SHA256_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;o&&(e=global);var r=!e.JS_SHA256_NO_COMMON_JS&&"object"==typeof module&&module.exports,t="function"==typeof define&&define.amd,n="0123456789abcdef".split(""),s=[-2147483648,8388608,32768,128],f=[24,16,8,0],i=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],a=[],c=function(e){return d(e,!0)},d=function(o,r){var t="string"!=typeof o;t&&o.constructor==e.ArrayBuffer&&(o=new Uint8Array(o));var c,d,u,p,l,h,v,_,y,w,A,S,b,O,m,J,N,g,j,C,x,H,M=!0,B=!1,D=0,E=0,U=0,k=o.length;r?(c=3238371032,d=914150663,u=812702999,p=4144912697,l=4290775857,h=1750603025,v=1694076839,_=3204075428):(c=1779033703,d=3144134277,u=1013904242,p=2773480762,l=1359893119,h=2600822924,v=528734635,_=1541459225),y=0;do{if(a[0]=y,a[16]=a[1]=a[2]=a[3]=a[4]=a[5]=a[6]=a[7]=a[8]=a[9]=a[10]=a[11]=a[12]=a[13]=a[14]=a[15]=0,t)for(A=E;k>D&&64>A;++D)a[A>>2]|=o[D]<D&&64>A;++D)w=o.charCodeAt(D),128>w?a[A>>2]|=w<w?(a[A>>2]|=(192|w>>6)<>2]|=(128|63&w)<w||w>=57344?(a[A>>2]|=(224|w>>12)<>2]|=(128|w>>6&63)<>2]|=(128|63&w)<>2]|=(240|w>>18)<>2]|=(128|w>>12&63)<>2]|=(128|w>>6&63)<>2]|=(128|63&w)<>2]|=s[3&A],++D),y=a[16],D>k&&56>A&&(a[15]=U<<3,B=!0);var q=c,z=d,F=u,G=p,I=l,K=h,L=v,P=_;for(S=16;64>S;++S)J=a[S-15],b=(J>>>7|J<<25)^(J>>>18|J<<14)^J>>>3,J=a[S-2],O=(J>>>17|J<<15)^(J>>>19|J<<13)^J>>>10,a[S]=a[S-16]+b+a[S-7]+O<<0;for(H=z&F,S=0;64>S;S+=4)M?(r?(j=300032,J=a[0]-1413257819,P=J-150054599<<0,G=J+24177077<<0):(j=704751109,J=a[0]-210244248,P=J-1521486534<<0,G=J+143694565<<0),M=!1):(b=(q>>>2|q<<30)^(q>>>13|q<<19)^(q>>>22|q<<10),O=(I>>>6|I<<26)^(I>>>11|I<<21)^(I>>>25|I<<7),j=q&z,m=j^q&F^H,g=I&K^~I&L,J=P+O+g+i[S]+a[S],N=b+m,P=G+J<<0,G=J+N<<0),b=(G>>>2|G<<30)^(G>>>13|G<<19)^(G>>>22|G<<10),O=(P>>>6|P<<26)^(P>>>11|P<<21)^(P>>>25|P<<7),C=G&q,m=C^G&z^j,g=P&I^~P&K,J=L+O+g+i[S+1]+a[S+1],N=b+m,L=F+J<<0,F=J+N<<0,b=(F>>>2|F<<30)^(F>>>13|F<<19)^(F>>>22|F<<10),O=(L>>>6|L<<26)^(L>>>11|L<<21)^(L>>>25|L<<7),x=F&G,m=x^F&q^C,g=L&P^~L&I,J=K+O+g+i[S+2]+a[S+2],N=b+m,K=z+J<<0,z=J+N<<0,b=(z>>>2|z<<30)^(z>>>13|z<<19)^(z>>>22|z<<10),O=(K>>>6|K<<26)^(K>>>11|K<<21)^(K>>>25|K<<7),H=z&F,m=H^z&G^x,g=K&L^~K&P,J=I+O+g+i[S+3]+a[S+3],N=b+m,I=q+J<<0,q=J+N<<0;c=c+q<<0,d=d+z<<0,u=u+F<<0,p=p+G<<0,l=l+I<<0,h=h+K<<0,v=v+L<<0,_=_+P<<0}while(!B);var Q=n[c>>28&15]+n[c>>24&15]+n[c>>20&15]+n[c>>16&15]+n[c>>12&15]+n[c>>8&15]+n[c>>4&15]+n[15&c]+n[d>>28&15]+n[d>>24&15]+n[d>>20&15]+n[d>>16&15]+n[d>>12&15]+n[d>>8&15]+n[d>>4&15]+n[15&d]+n[u>>28&15]+n[u>>24&15]+n[u>>20&15]+n[u>>16&15]+n[u>>12&15]+n[u>>8&15]+n[u>>4&15]+n[15&u]+n[p>>28&15]+n[p>>24&15]+n[p>>20&15]+n[p>>16&15]+n[p>>12&15]+n[p>>8&15]+n[p>>4&15]+n[15&p]+n[l>>28&15]+n[l>>24&15]+n[l>>20&15]+n[l>>16&15]+n[l>>12&15]+n[l>>8&15]+n[l>>4&15]+n[15&l]+n[h>>28&15]+n[h>>24&15]+n[h>>20&15]+n[h>>16&15]+n[h>>12&15]+n[h>>8&15]+n[h>>4&15]+n[15&h]+n[v>>28&15]+n[v>>24&15]+n[v>>20&15]+n[v>>16&15]+n[v>>12&15]+n[v>>8&15]+n[v>>4&15]+n[15&v];return r||(Q+=n[_>>28&15]+n[_>>24&15]+n[_>>20&15]+n[_>>16&15]+n[_>>12&15]+n[_>>8&15]+n[_>>4&15]+n[15&_]),Q},u=d;u.sha256=d,u.sha224=c,r?module.exports=u:(e.sha256=d,e.sha224=c,t&&define(function(){return u}))}(); \ No newline at end of file +!function(){"use strict";function t(t,h){h?(c[0]=c[16]=c[1]=c[2]=c[3]=c[4]=c[5]=c[6]=c[7]=c[8]=c[9]=c[10]=c[11]=c[12]=c[13]=c[14]=c[15]=0,this.blocks=c):this.blocks=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],t?(this.h0=3238371032,this.h1=914150663,this.h2=812702999,this.h3=4144912697,this.h4=4290775857,this.h5=1750603025,this.h6=1694076839,this.h7=3204075428):(this.h0=1779033703,this.h1=3144134277,this.h2=1013904242,this.h3=2773480762,this.h4=1359893119,this.h5=2600822924,this.h6=528734635,this.h7=1541459225),this.block=this.start=this.bytes=0,this.finalized=this.hashed=!1,this.first=!0,this.is224=t}var h="object"==typeof window?window:{},i=!h.JS_SHA256_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;i&&(h=global);var s=!h.JS_SHA256_NO_COMMON_JS&&"object"==typeof module&&module.exports,e="function"==typeof define&&define.amd,r="undefined"!=typeof ArrayBuffer,n="0123456789abcdef".split(""),o=[-2147483648,8388608,32768,128],a=[24,16,8,0],f=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],u=["hex","array","digest","arrayBuffer"],c=[],p=function(h,i){return function(s){return new t(i,!0).update(s)[h]()}},d=function(h){var s=p("hex",h);i&&(s=y(s,h)),s.create=function(){return new t(h)},s.update=function(t){return s.create().update(t)};for(var e=0;en;){if(this.hashed&&(this.hashed=!1,f[0]=this.block,f[16]=f[1]=f[2]=f[3]=f[4]=f[5]=f[6]=f[7]=f[8]=f[9]=f[10]=f[11]=f[12]=f[13]=f[14]=f[15]=0),i)for(e=this.start;o>n&&64>e;++n)f[e>>2]|=t[n]<n&&64>e;++n)s=t.charCodeAt(n),128>s?f[e>>2]|=s<s?(f[e>>2]|=(192|s>>6)<>2]|=(128|63&s)<s||s>=57344?(f[e>>2]|=(224|s>>12)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<>2]|=(240|s>>18)<>2]|=(128|s>>12&63)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<=64?(this.block=f[16],this.start=e-64,this.hash(),this.hashed=!0):this.start=e}return this}},t.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var t=this.blocks,h=this.lastByteIndex;t[16]=this.block,t[h>>2]|=o[3&h],this.block=t[16],h>=56&&(this.hashed||this.hash(),t[0]=this.block,t[16]=t[1]=t[2]=t[3]=t[4]=t[5]=t[6]=t[7]=t[8]=t[9]=t[10]=t[11]=t[12]=t[13]=t[14]=t[15]=0),t[15]=this.bytes<<3,this.hash()}},t.prototype.hash=function(){var t,h,i,s,e,r,n,o,a,u,c,p=this.h0,d=this.h1,y=this.h2,l=this.h3,b=this.h4,v=this.h5,g=this.h6,w=this.h7,k=this.blocks;for(t=16;64>t;++t)e=k[t-15],h=(e>>>7|e<<25)^(e>>>18|e<<14)^e>>>3,e=k[t-2],i=(e>>>17|e<<15)^(e>>>19|e<<13)^e>>>10,k[t]=k[t-16]+h+k[t-7]+i<<0;for(c=d&y,t=0;64>t;t+=4)this.first?(this.is224?(o=300032,e=k[0]-1413257819,w=e-150054599<<0,l=e+24177077<<0):(o=704751109,e=k[0]-210244248,w=e-1521486534<<0,l=e+143694565<<0),this.first=!1):(h=(p>>>2|p<<30)^(p>>>13|p<<19)^(p>>>22|p<<10),i=(b>>>6|b<<26)^(b>>>11|b<<21)^(b>>>25|b<<7),o=p&d,s=o^p&y^c,n=b&v^~b&g,e=w+i+n+f[t]+k[t],r=h+s,w=l+e<<0,l=e+r<<0),h=(l>>>2|l<<30)^(l>>>13|l<<19)^(l>>>22|l<<10),i=(w>>>6|w<<26)^(w>>>11|w<<21)^(w>>>25|w<<7),a=l&p,s=a^l&d^o,n=w&b^~w&v,e=g+i+n+f[t+1]+k[t+1],r=h+s,g=y+e<<0,y=e+r<<0,h=(y>>>2|y<<30)^(y>>>13|y<<19)^(y>>>22|y<<10),i=(g>>>6|g<<26)^(g>>>11|g<<21)^(g>>>25|g<<7),u=y&l,s=u^y&p^a,n=g&w^~g&b,e=v+i+n+f[t+2]+k[t+2],r=h+s,v=d+e<<0,d=e+r<<0,h=(d>>>2|d<<30)^(d>>>13|d<<19)^(d>>>22|d<<10),i=(v>>>6|v<<26)^(v>>>11|v<<21)^(v>>>25|v<<7),c=d&y,s=c^d&l^u,n=v&g^~v&w,e=b+i+n+f[t+3]+k[t+3],r=h+s,b=p+e<<0,p=e+r<<0;this.h0=this.h0+p<<0,this.h1=this.h1+d<<0,this.h2=this.h2+y<<0,this.h3=this.h3+l<<0,this.h4=this.h4+b<<0,this.h5=this.h5+v<<0,this.h6=this.h6+g<<0,this.h7=this.h7+w<<0},t.prototype.hex=function(){this.finalize();var t=this.h0,h=this.h1,i=this.h2,s=this.h3,e=this.h4,r=this.h5,o=this.h6,a=this.h7,f=n[t>>28&15]+n[t>>24&15]+n[t>>20&15]+n[t>>16&15]+n[t>>12&15]+n[t>>8&15]+n[t>>4&15]+n[15&t]+n[h>>28&15]+n[h>>24&15]+n[h>>20&15]+n[h>>16&15]+n[h>>12&15]+n[h>>8&15]+n[h>>4&15]+n[15&h]+n[i>>28&15]+n[i>>24&15]+n[i>>20&15]+n[i>>16&15]+n[i>>12&15]+n[i>>8&15]+n[i>>4&15]+n[15&i]+n[s>>28&15]+n[s>>24&15]+n[s>>20&15]+n[s>>16&15]+n[s>>12&15]+n[s>>8&15]+n[s>>4&15]+n[15&s]+n[e>>28&15]+n[e>>24&15]+n[e>>20&15]+n[e>>16&15]+n[e>>12&15]+n[e>>8&15]+n[e>>4&15]+n[15&e]+n[r>>28&15]+n[r>>24&15]+n[r>>20&15]+n[r>>16&15]+n[r>>12&15]+n[r>>8&15]+n[r>>4&15]+n[15&r]+n[o>>28&15]+n[o>>24&15]+n[o>>20&15]+n[o>>16&15]+n[o>>12&15]+n[o>>8&15]+n[o>>4&15]+n[15&o];return this.is224||(f+=n[a>>28&15]+n[a>>24&15]+n[a>>20&15]+n[a>>16&15]+n[a>>12&15]+n[a>>8&15]+n[a>>4&15]+n[15&a]),f},t.prototype.toString=t.prototype.hex,t.prototype.digest=function(){this.finalize();var t=this.h0,h=this.h1,i=this.h2,s=this.h3,e=this.h4,r=this.h5,n=this.h6,o=this.h7,a=[t>>24&255,t>>16&255,t>>8&255,255&t,h>>24&255,h>>16&255,h>>8&255,255&h,i>>24&255,i>>16&255,i>>8&255,255&i,s>>24&255,s>>16&255,s>>8&255,255&s,e>>24&255,e>>16&255,e>>8&255,255&e,r>>24&255,r>>16&255,r>>8&255,255&r,n>>24&255,n>>16&255,n>>8&255,255&n];return this.is224||a.push(o>>24&255,o>>16&255,o>>8&255,255&o),a},t.prototype.array=t.prototype.digest,t.prototype.arrayBuffer=function(){this.finalize();var t=new ArrayBuffer(this.is224?28:32),h=new DataView(t);return h.setUint32(0,this.h0),h.setUint32(4,this.h1),h.setUint32(8,this.h2),h.setUint32(12,this.h3),h.setUint32(16,this.h4),h.setUint32(20,this.h5),h.setUint32(24,this.h6),this.is224||h.setUint32(28,this.h7),t};var l=d();l.sha256=l,l.sha224=d(!0),s?module.exports=l:(h.sha256=l.sha256,h.sha224=l.sha224,e&&define(function(){return l}))}(); \ No newline at end of file diff --git a/package.json b/package.json index b25550b..0a1f7a2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "js-sha256", - "version": "0.4.0", + "version": "0.5.0", "description": "A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.", "main": "src/sha256.js", "devDependencies": { diff --git a/src/sha256.js b/src/sha256.js index 6d0ac14..d64b001 100644 --- a/src/sha256.js +++ b/src/sha256.js @@ -1,7 +1,7 @@ /** * [js-sha256]{@link https://github.com/emn178/js-sha256} * - * @version 0.4.0 + * @version 0.5.0 * @author Chen, Yi-Cyuan [emn178@gmail.com] * @copyright Chen, Yi-Cyuan 2014-2017 * @license MIT @@ -17,66 +17,128 @@ } var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports; var AMD = typeof define === 'function' && define.amd; + var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined'; var HEX_CHARS = '0123456789abcdef'.split(''); var EXTRA = [-2147483648, 8388608, 32768, 128]; var SHIFT = [24, 16, 8, 0]; - 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]; + 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 + ]; + var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer']; var blocks = []; - var sha224 = function (message) { - return sha256(message, true); + var createOutputMethod = function (outputType, is224) { + return function (message) { + return new Sha256(is224, true).update(message)[outputType](); + }; }; - var sha256 = function (message, is224) { - var notString = typeof message != 'string'; - if (notString && message.constructor == root.ArrayBuffer) { - message = new Uint8Array(message); + var createMethod = function (is224) { + var method = createOutputMethod('hex', is224); + if (NODE_JS) { + method = nodeWrap(method, is224); + } + method.create = function () { + return new Sha256(is224); + }; + method.update = function (message) { + return method.create().update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(type, is224); } + return method; + }; - var h0, h1, h2, h3, h4, h5, h6, h7, block, code, first = true, end = false, - i, j, index = 0, start = 0, bytes = 0, length = message.length, - s0, s1, maj, t1, t2, ch, ab, da, cd, bc; + var nodeWrap = function (method, is224) { + var crypto = require('crypto'); + var Buffer = require('buffer').Buffer; + var algorithm = is224 ? 'sha224' : 'sha256'; + var nodeMethod = function (message) { + if (typeof message === 'string') { + return crypto.createHash(algorithm).update(message, 'utf8').digest('hex'); + } else if (ARRAY_BUFFER && message instanceof ArrayBuffer) { + message = new Uint8Array(message); + } else if (message.length === undefined) { + return method(message); + } + return crypto.createHash(algorithm).update(new Buffer(message)).digest('hex'); + }; + return nodeMethod; + }; - if (is224) { - h0 = 0xc1059ed8; - h1 = 0x367cd507; - h2 = 0x3070dd17; - h3 = 0xf70e5939; - h4 = 0xffc00b31; - h5 = 0x68581511; - h6 = 0x64f98fa7; - h7 = 0xbefa4fa4; - } else { // 256 - h0 = 0x6a09e667; - h1 = 0xbb67ae85; - h2 = 0x3c6ef372; - h3 = 0xa54ff53a; - h4 = 0x510e527f; - h5 = 0x9b05688c; - h6 = 0x1f83d9ab; - h7 = 0x5be0cd19; - } - block = 0; - do { - blocks[0] = block; - blocks[16] = blocks[1] = blocks[2] = blocks[3] = + function Sha256(is224, sharedMemory) { + if (sharedMemory) { + blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - if (notString) { - for (i = start; index < length && i < 64; ++index) { + this.blocks = blocks; + } else { + this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + if (is224) { + this.h0 = 0xc1059ed8; + this.h1 = 0x367cd507; + this.h2 = 0x3070dd17; + this.h3 = 0xf70e5939; + this.h4 = 0xffc00b31; + this.h5 = 0x68581511; + this.h6 = 0x64f98fa7; + this.h7 = 0xbefa4fa4; + } else { // 256 + this.h0 = 0x6a09e667; + this.h1 = 0xbb67ae85; + this.h2 = 0x3c6ef372; + this.h3 = 0xa54ff53a; + this.h4 = 0x510e527f; + this.h5 = 0x9b05688c; + this.h6 = 0x1f83d9ab; + this.h7 = 0x5be0cd19; + } + + this.block = this.start = this.bytes = 0; + this.finalized = this.hashed = false; + this.first = true; + this.is224 = is224; + } + + Sha256.prototype.update = function (message) { + if (this.finalized) { + return; + } + var notString = typeof(message) !== 'string'; + if (notString && ARRAY_BUFFER && message instanceof root.ArrayBuffer) { + message = new Uint8Array(message); + } + var code, index = 0, i, length = message.length || 0, blocks = this.blocks; + + while (index < length) { + if (this.hashed) { + this.hashed = false; + blocks[0] = this.block; + blocks[16] = blocks[1] = blocks[2] = blocks[3] = + blocks[4] = blocks[5] = blocks[6] = blocks[7] = + blocks[8] = blocks[9] = blocks[10] = blocks[11] = + blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + } + + if(notString) { + for (i = this.start; index < length && i < 64; ++index) { blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; } } else { - for (i = start; index < length && i < 64; ++index) { + for (i = this.start; index < length && i < 64; ++index) { code = message.charCodeAt(index); if (code < 0x80) { blocks[i >> 2] |= code << SHIFT[i++ & 3]; @@ -96,139 +158,217 @@ } } } - bytes += i - start; - start = i - 64; - if (index == length) { - blocks[i >> 2] |= EXTRA[i & 3]; - ++index; - } - block = blocks[16]; - if (index > length && i < 56) { - blocks[15] = bytes << 3; - end = true; + + this.lastByteIndex = i; + this.bytes += i - this.start; + if (i >= 64) { + this.block = blocks[16]; + this.start = i - 64; + this.hash(); + this.hashed = true; + } else { + this.start = i; } + } + return this; + }; - var a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7; - for (j = 16; j < 64; ++j) { - // rightrotate - t1 = blocks[j - 15]; - s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3); - t1 = blocks[j - 2]; - s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10); - blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0; + Sha256.prototype.finalize = function () { + if (this.finalized) { + return; + } + this.finalized = true; + var blocks = this.blocks, i = this.lastByteIndex; + blocks[16] = this.block; + blocks[i >> 2] |= EXTRA[i & 3]; + this.block = blocks[16]; + if (i >= 56) { + if (!this.hashed) { + this.hash(); } + blocks[0] = this.block; + blocks[16] = blocks[1] = blocks[2] = blocks[3] = + blocks[4] = blocks[5] = blocks[6] = blocks[7] = + blocks[8] = blocks[9] = blocks[10] = blocks[11] = + blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + } + blocks[15] = this.bytes << 3; + this.hash(); + }; - bc = b & c; - for (j = 0; j < 64; j += 4) { - if (first) { - if (is224) { - ab = 300032; - t1 = blocks[0] - 1413257819; - h = t1 - 150054599 << 0; - d = t1 + 24177077 << 0; - } else { - ab = 704751109; - t1 = blocks[0] - 210244248; - h = t1 - 1521486534 << 0; - d = t1 + 143694565 << 0; - } - first = false; + Sha256.prototype.hash = function () { + var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6, + h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc; + + for (j = 16; j < 64; ++j) { + // rightrotate + t1 = blocks[j - 15]; + s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3); + t1 = blocks[j - 2]; + s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10); + blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0; + } + + bc = b & c; + for (j = 0; j < 64; j += 4) { + if (this.first) { + if (this.is224) { + ab = 300032; + t1 = blocks[0] - 1413257819; + h = t1 - 150054599 << 0; + d = t1 + 24177077 << 0; } else { - s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10)); - s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7)); - ab = a & b; - maj = ab ^ (a & c) ^ bc; - ch = (e & f) ^ (~e & g); - t1 = h + s1 + ch + K[j] + blocks[j]; - t2 = s0 + maj; - h = d + t1 << 0; - d = t1 + t2 << 0; + ab = 704751109; + t1 = blocks[0] - 210244248; + h = t1 - 1521486534 << 0; + d = t1 + 143694565 << 0; } - s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10)); - s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7)); - da = d & a; - maj = da ^ (d & b) ^ ab; - ch = (h & e) ^ (~h & f); - t1 = g + s1 + ch + K[j + 1] + blocks[j + 1]; - t2 = s0 + maj; - g = c + t1 << 0; - c = t1 + t2 << 0; - s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10)); - s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7)); - cd = c & d; - maj = cd ^ (c & a) ^ da; - ch = (g & h) ^ (~g & e); - t1 = f + s1 + ch + K[j + 2] + blocks[j + 2]; - t2 = s0 + maj; - f = b + t1 << 0; - b = t1 + t2 << 0; - s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10)); - s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7)); - bc = b & c; - maj = bc ^ (b & d) ^ cd; - ch = (f & g) ^ (~f & h); - t1 = e + s1 + ch + K[j + 3] + blocks[j + 3]; + this.first = false; + } else { + s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10)); + s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7)); + ab = a & b; + maj = ab ^ (a & c) ^ bc; + ch = (e & f) ^ (~e & g); + t1 = h + s1 + ch + K[j] + blocks[j]; t2 = s0 + maj; - e = a + t1 << 0; - a = t1 + t2 << 0; + h = d + t1 << 0; + d = t1 + t2 << 0; } + s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10)); + s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7)); + da = d & a; + maj = da ^ (d & b) ^ ab; + ch = (h & e) ^ (~h & f); + t1 = g + s1 + ch + K[j + 1] + blocks[j + 1]; + t2 = s0 + maj; + g = c + t1 << 0; + c = t1 + t2 << 0; + s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10)); + s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7)); + cd = c & d; + maj = cd ^ (c & a) ^ da; + ch = (g & h) ^ (~g & e); + t1 = f + s1 + ch + K[j + 2] + blocks[j + 2]; + t2 = s0 + maj; + f = b + t1 << 0; + b = t1 + t2 << 0; + s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10)); + s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7)); + bc = b & c; + maj = bc ^ (b & d) ^ cd; + ch = (f & g) ^ (~f & h); + t1 = e + s1 + ch + K[j + 3] + blocks[j + 3]; + t2 = s0 + maj; + e = a + t1 << 0; + a = t1 + t2 << 0; + } + + this.h0 = this.h0 + a << 0; + this.h1 = this.h1 + b << 0; + this.h2 = this.h2 + c << 0; + this.h3 = this.h3 + d << 0; + this.h4 = this.h4 + e << 0; + this.h5 = this.h5 + f << 0; + this.h6 = this.h6 + g << 0; + this.h7 = this.h7 + h << 0; + }; + + Sha256.prototype.hex = function () { + this.finalize(); - h0 = h0 + a << 0; - h1 = h1 + b << 0; - h2 = h2 + c << 0; - h3 = h3 + d << 0; - h4 = h4 + e << 0; - h5 = h5 + f << 0; - h6 = h6 + g << 0; - h7 = h7 + h << 0; - } while (!end); + var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, + h6 = this.h6, h7 = this.h7; var hex = HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] + - HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] + - HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] + - HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] + - HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] + - HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] + - HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] + - HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] + - HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] + - HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] + - HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] + - HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] + - HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] + - HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] + - HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] + - HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] + - HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] + - HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] + - HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] + - HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] + - HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] + - HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] + - HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] + - HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] + - HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] + - HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] + - HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] + - HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F]; - if (!is224) { + HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] + + HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] + + HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] + + HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] + + HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] + + HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] + + HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] + + HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] + + HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] + + HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] + + HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] + + HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] + + HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] + + HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] + + HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] + + HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] + + HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] + + HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] + + HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] + + HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] + + HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] + + HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] + + HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] + + HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] + + HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] + + HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] + + HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F]; + if (!this.is224) { hex += HEX_CHARS[(h7 >> 28) & 0x0F] + HEX_CHARS[(h7 >> 24) & 0x0F] + - HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] + - HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] + - HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F]; + HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] + + HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] + + HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F]; } return hex; }; - var exports = sha256; - exports.sha256 = sha256; - exports.sha224 = sha224; + Sha256.prototype.toString = Sha256.prototype.hex; + + Sha256.prototype.digest = function () { + this.finalize(); + + var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, + h6 = this.h6, h7 = this.h7; + + var arr = [ + (h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF, + (h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF, + (h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF, + (h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF, + (h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF, + (h5 >> 24) & 0xFF, (h5 >> 16) & 0xFF, (h5 >> 8) & 0xFF, h5 & 0xFF, + (h6 >> 24) & 0xFF, (h6 >> 16) & 0xFF, (h6 >> 8) & 0xFF, h6 & 0xFF + ]; + if (!this.is224) { + arr.push((h7 >> 24) & 0xFF, (h7 >> 16) & 0xFF, (h7 >> 8) & 0xFF, h7 & 0xFF); + } + return arr; + }; + + Sha256.prototype.array = Sha256.prototype.digest; + + Sha256.prototype.arrayBuffer = function () { + this.finalize(); + + var buffer = new ArrayBuffer(this.is224 ? 28 : 32); + var dataView = new DataView(buffer); + dataView.setUint32(0, this.h0); + dataView.setUint32(4, this.h1); + dataView.setUint32(8, this.h2); + dataView.setUint32(12, this.h3); + dataView.setUint32(16, this.h4); + dataView.setUint32(20, this.h5); + dataView.setUint32(24, this.h6); + if (!this.is224) { + dataView.setUint32(28, this.h7); + } + return buffer; + }; + + var exports = createMethod(); + exports.sha256 = exports; + exports.sha224 = createMethod(true); if (COMMON_JS) { module.exports = exports; } else { - root.sha256 = sha256; - root.sha224 = sha224; + root.sha256 = exports.sha256; + root.sha224 = exports.sha224; if (AMD) { define(function () { return exports; diff --git a/tests/test.js b/tests/test.js index 91ca581..45e6d3c 100644 --- a/tests/test.js +++ b/tests/test.js @@ -1,113 +1,241 @@ (function (sha256, sha224) { - describe('sha256', function () { - context('when ascii', function () { - context('and less than 64 bytes', function () { - it('should be equal', function () { - expect(sha256('')).to.be('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'); - expect(sha256('The quick brown fox jumps over the lazy dog')).to.be('d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592'); - expect(sha256('The quick brown fox jumps over the lazy dog.')).to.be('ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c'); - }); - }); + Array.prototype.toHexString = ArrayBuffer.prototype.toHexString = function () { + var array = new Uint8Array(this); + var hex = ''; + for (var i = 0; i < array.length; ++i) { + var c = array[i].toString('16'); + hex += c.length === 1 ? '0' + c : c; + } + return hex; + }; - context('and more than 64 bytes', function () { - it('should be equal', function () { - expect(sha256('The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity.')).to.be('54e73d89e1924fdcd056390266a983924b6d6d461e9470b6cd50bbaf69b5c54c'); - }); - }); - }); + var testCases = { + sha256: { + 'ascii': { + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': '', + 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': 'The quick brown fox jumps over the lazy dog', + 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c': 'The quick brown fox jumps over the lazy dog.' + }, + 'ascii more than 64 bytes': { + '54e73d89e1924fdcd056390266a983924b6d6d461e9470b6cd50bbaf69b5c54c': 'The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity.' + }, + 'UTF8': { + '72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21': '中文', + '53196d1acfce0c4b264e01e8018c989d571351f59e33f055f76ff15b4f0516c6': 'aécio', + '8d10a48685dbc34484696de7ea7434d80a54c1d60100530faccf697463ef19c9': '𠜎' + }, + 'UTF8 more than 64 bytes': { + 'd691014feebf35b3500ef6f6738d0094cac63628a7a018a980a40292a77703d1': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一', + '81a1472ebdeb09406a783d607ff49ee2fde3e9f44ac1cd158ad8d6ad3c4e69fa': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。' + }, + 'special length': { + '5e6b963e2b6444dab8544beab8532850cef2a9d143872a6a5384abe37e61b3db': '0123456780123456780123456780123456780123456780123456780', + '85d240a4a03a0710423fc4f701da51e8785c9eaa96d718ab1c7991d6afd60d62': '01234567801234567801234567801234567801234567801234567801', + 'c3ee464d5620eb2dde3dfda4c7955dbd9e9e2e9b113c13983fc67b0dfd892a53': '0123456780123456780123456780123456780123456780123456780123456780', + '74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841': '01234567801234567801234567801234567801234567801234567801234567801234567', + '6fba9e623ae6abf028a1b195748814aa95eebfb22e3ec5e15d2444cd6c48186a': '012345678012345678012345678012345678012345678012345678012345678012345678' + }, + 'Array': { + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': [], + '182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': [211, 212], + 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], + '74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841': [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] + }, - context('when UTF8', function () { - context('and less than 64 bytes', function () { - it('should be equal', function () { - expect(sha256('中文')).to.be('72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21'); - expect(sha256('aécio')).to.be('53196d1acfce0c4b264e01e8018c989d571351f59e33f055f76ff15b4f0516c6'); - expect(sha256('𠜎')).to.be('8d10a48685dbc34484696de7ea7434d80a54c1d60100530faccf697463ef19c9'); - }); - }); + 'Uint8Array': { + '182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': new Uint8Array([211, 212]), + 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) + }, + 'Int8Array': { + 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) + }, + 'ArrayBuffer': { + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': new ArrayBuffer(0), + '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d': new ArrayBuffer(1), + }, + 'Object': { + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': {what: 'ever'} + } + }, + sha224: { + 'ascii': { + 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': '', + '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': 'The quick brown fox jumps over the lazy dog', + '619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c': 'The quick brown fox jumps over the lazy dog.' + }, + 'ascii more than 64 bytes': { + '4d97e15967391d2e846ea7d21bb480efadbae5868b731e7cc6267006': 'The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity.' + }, + 'UTF8': { + 'dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4': '中文', + 'd12841cafd89c534924a839e62bf35a2b5f3717b7802eb19bd8d8e15': 'aécio', + 'eaa0129b5509f5701db218fb7076b282e4409da52d06363aa3bdd63d': '𠜎' + }, + 'UTF8 more than 64 bytes': { + '0dda421f3f81272418e1313673e9d74b7f2d04efc9c52c69458e12c3': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一', + 'a8cb74a54e6dc6ab6110db3915ba08ffe5e1abafaea78538fa12a626': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。' + }, + 'special length': { + 'bc4a354d66f3cff4bc6dd6a88fbb0435cede7fd5fe94da0760cb1924': '0123456780123456780123456780123456780123456780123456780', + '2f148f757d1295784a7c69bf328b8bf827a536669e132234cd6f50e7': '01234567801234567801234567801234567801234567801234567801', + '496275a96bf41aa27ce89c3ae0fc63c3a3eab063887a8ea075bd091b': '0123456780123456780123456780123456780123456780123456780123456780', + '16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8': '01234567801234567801234567801234567801234567801234567801234567801234567', + '04c7a30079c640e440d884cdf0d7ab04fd05501d4498cb21be29ca1f': '012345678012345678012345678012345678012345678012345678012345678012345678' + }, + 'Array': { + 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': [], + '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], + '16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8': [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] + }, + 'Uint8Array': { + 'e17541396a3ecd1cd5a2b968b84e597e8eae3b0ea3127963bf48dd3b': new Uint8Array([211, 212]), + '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) + }, + 'Int8Array': { + '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) + }, + 'ArrayBuffer': { + 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': new ArrayBuffer(0), + 'fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073': new ArrayBuffer(1), + }, + 'Object': { + 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': {what: 'ever'} + } + } + }; - context('and more than 64 bytes', function () { - it('should be equal', function () { - expect(sha256('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一')).to.be('d691014feebf35b3500ef6f6738d0094cac63628a7a018a980a40292a77703d1'); - expect(sha256('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。')).to.be('81a1472ebdeb09406a783d607ff49ee2fde3e9f44ac1cd158ad8d6ad3c4e69fa'); - }); - }); - }); - - context('when special length', function () { - it('should be equal', function () { - expect(sha256('0123456780123456780123456780123456780123456780123456780')).to.be('5e6b963e2b6444dab8544beab8532850cef2a9d143872a6a5384abe37e61b3db'); - expect(sha256('01234567801234567801234567801234567801234567801234567801')).to.be('85d240a4a03a0710423fc4f701da51e8785c9eaa96d718ab1c7991d6afd60d62'); - expect(sha256('0123456780123456780123456780123456780123456780123456780123456780')).to.be('c3ee464d5620eb2dde3dfda4c7955dbd9e9e2e9b113c13983fc67b0dfd892a53'); - expect(sha256('01234567801234567801234567801234567801234567801234567801234567801234567')).to.be('74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841'); - expect(sha256('012345678012345678012345678012345678012345678012345678012345678012345678')).to.be('6fba9e623ae6abf028a1b195748814aa95eebfb22e3ec5e15d2444cd6c48186a'); - }); - }); + if (typeof process == 'object') { + testCases.sha256['Buffer'] = { + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': new Buffer(0), + 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Buffer(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])) + }; + testCases.sha224['Buffer'] = { + 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': new Buffer(0), + '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Buffer(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])) + }; + } - context('when Array', function () { - it('should be equal', function () { - expect(sha256([])).to.be('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'); - expect(sha256([211, 212])).to.be('182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f'); - expect(sha256([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])).to.be('d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592'); - expect(sha256([48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55])).to.be('74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841'); - }); - }); + function runTestCases(name, algorithm) { + var methods = [ + { + name: name, + call: algorithm, + }, + { + name: name + '.hex', + call: algorithm.hex + }, + { + name: name + '.array', + call: function (message) { + return algorithm.array(message).toHexString(); + } + }, + { + name: name + '.digest', + call: function (message) { + return algorithm.digest(message).toHexString(); + } + }, + { + name: name + '.arrayBuffer', + call: function (message) { + return algorithm.arrayBuffer(message).toHexString(); + } + } + ]; - context('when Uint8Array', function () { - it('should be equal', function () { - expect(sha256(new Uint8Array([]))).to.be('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'); - expect(sha256(new Uint8Array([211, 212]))).to.be('182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f'); - }); - }); + var classMethods = [ + { + name: 'create', + call: function (message) { + return algorithm.create().update(message).toString(); + } + }, + { + name: 'update', + call: function (message) { + return algorithm.update(message).toString(); + } + }, + { + name: 'hex', + call: function (message) { + return algorithm.update(message).hex(); + } + }, + { + name: 'array', + call: function (message) { + return algorithm.update(message).array().toHexString(); + } + }, + { + name: 'digest', + call: function (message) { + return algorithm.update(message).digest().toHexString(); + } + }, + { + name: 'arrayBuffer', + call: function (message) { + return algorithm.update(message).arrayBuffer().toHexString(); + } + }, + { + name: 'finalize', + call: function (message) { + var hash = algorithm.update(message); + hash.hex(); + hash.update(message); + return hash.hex(); + } + } + ]; - context('when ArrayBuffer', function () { - it('should be equal', function () { - expect(sha256(new ArrayBuffer(0))).to.be('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'); - }); - }); - }); + var subTestCases = testCases[name]; - describe('sha224', function () { - context('when ascii', function () { - context('and less than 64 bytes', function () { - it('should be equal', function () { - expect(sha224('')).to.be('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f'); - expect(sha224('The quick brown fox jumps over the lazy dog')).to.be('730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525'); - expect(sha224('The quick brown fox jumps over the lazy dog.')).to.be('619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c'); + describe(name, function () { + methods.forEach(function (method) { + describe('#' + method.name, function () { + for (var testCaseName in subTestCases) { + (function (testCaseName) { + var testCase = subTestCases[testCaseName]; + context('when ' + testCaseName, function () { + for (var hash in testCase) { + (function (message, hash) { + it('should be equal', function () { + expect(method.call(message)).to.be(hash); + }); + })(testCase[hash], hash); + } + }); + })(testCaseName); + } }); }); - context('and more than 64 bytes', function () { - it('should be equal', function () { - expect(sha224('The MD5 message-digest algorithm is a widely used cryptographic hash function producing a 128-bit (16-byte) hash value, typically expressed in text format as a 32 digit hexadecimal number. MD5 has been utilized in a wide variety of cryptographic applications, and is also commonly used to verify data integrity.')).to.be('4d97e15967391d2e846ea7d21bb480efadbae5868b731e7cc6267006'); + classMethods.forEach(function (method) { + describe('#' + method.name, function () { + for (var testCaseName in subTestCases) { + (function (testCaseName) { + var testCase = subTestCases[testCaseName]; + context('when ' + testCaseName, function () { + for (var hash in testCase) { + (function (message, hash) { + it('should be equal', function () { + expect(method.call(message)).to.be(hash); + }); + })(testCase[hash], hash); + } + }); + })(testCaseName); + } }); }); }); + } - context('when UTF8', function () { - context('and less than 64 bytes', function () { - it('should be equal', function () { - expect(sha224('中文')).to.be('dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4'); - expect(sha224('aécio')).to.be('d12841cafd89c534924a839e62bf35a2b5f3717b7802eb19bd8d8e15'); - expect(sha224('𠜎')).to.be('eaa0129b5509f5701db218fb7076b282e4409da52d06363aa3bdd63d'); - }); - }); - - context('and more than 64 bytes', function () { - it('should be equal', function () { - expect(sha224('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一')).to.be('0dda421f3f81272418e1313673e9d74b7f2d04efc9c52c69458e12c3'); - expect(sha224('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。')).to.be('a8cb74a54e6dc6ab6110db3915ba08ffe5e1abafaea78538fa12a626'); - }); - }); - }); - - context('when special length', function () { - it('should be equal', function () { - expect(sha224('0123456780123456780123456780123456780123456780123456780')).to.be('bc4a354d66f3cff4bc6dd6a88fbb0435cede7fd5fe94da0760cb1924'); - expect(sha224('01234567801234567801234567801234567801234567801234567801')).to.be('2f148f757d1295784a7c69bf328b8bf827a536669e132234cd6f50e7'); - expect(sha224('0123456780123456780123456780123456780123456780123456780123456780')).to.be('496275a96bf41aa27ce89c3ae0fc63c3a3eab063887a8ea075bd091b'); - expect(sha224('01234567801234567801234567801234567801234567801234567801234567801234567')).to.be('16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8'); - expect(sha224('012345678012345678012345678012345678012345678012345678012345678012345678')).to.be('04c7a30079c640e440d884cdf0d7ab04fd05501d4498cb21be29ca1f'); - }); - }); - }); + runTestCases('sha256', sha256); + runTestCases('sha224', sha224); })(sha256, sha224);