From f73267ad1574bb6a7851ddb1da50a8c97513acb2 Mon Sep 17 00:00:00 2001 From: Chen Yi-Cyuan Date: Thu, 12 Feb 2015 21:45:00 +0800 Subject: [PATCH] Support byte array input --- CHANGELOG.md | 4 ++++ README.md | 12 ++++++++++++ bower.json | 2 +- build/sha256.min.js | 16 +++++++-------- package.json | 2 +- src/sha256.js | 48 ++++++++++++++++++++++++++++----------------- tests/test.js | 18 +++++++++++++++++ 7 files changed, 74 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9960c0..0c8aa5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v0.2.3 / 2015-02-11 + +* Support byte array input. + # v0.2.2 / 2015-02-10 * Improve performance. diff --git a/README.md b/README.md index b0d07aa..a3772e5 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,18 @@ Output 72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21 dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4 +It also supports byte Array or Uint8Array input: + +Code +```JavaScript +sha256([]); +sha256(new Uint8Array([211, 212])); +``` +Output + + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + 182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f + ## Benchmark [UTF8](http://jsperf.com/sha256/66) [ASCII](http://jsperf.com/sha256/65) diff --git a/bower.json b/bower.json index 8d2a6d9..cfae4ef 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "js-sha256", - "version": "0.2.2", + "version": "0.2.3", "main": ["build/sha256.min.js"], "ignore": [ "samples", diff --git a/build/sha256.min.js b/build/sha256.min.js index c19ce61..249eb49 100644 --- a/build/sha256.min.js +++ b/build/sha256.min.js @@ -1,8 +1,8 @@ -(function(B,P){var I="undefined"!=typeof module;I&&(B=global);var a="0123456789abcdef".split(""),O=[-2147483648,8388608,32768,128],F=[24,16,8,0],K=[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],c=[],J=function(a){return A(a,!0)},A=function(A,B){var f,n,p,q,r,t,u,v,g,I=!0,J=!1,b,G=0,L=0,M=0,N=A.length,e,d,C,D,E,H;B?(f=3238371032,n=914150663,p=812702999,q=4144912697, -r=4290775857,t=1750603025,u=1694076839,v=3204075428):(f=1779033703,n=3144134277,p=1013904242,q=2773480762,r=1359893119,t=2600822924,u=528734635,v=1541459225);g=0;do{c[0]=g;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;for(b=L;Gb;++G)g=A.charCodeAt(G),128>g?c[b>>2]|=g<g?c[b>>2]|=(192|g>>6)<g||57344<=g?c[b>>2]|=(224|g>>12)<>2]|=(240|g>>18)<>2]|= -(128|g>>12&63)<>2]|=(128|g>>6&63)<>2]|=(128|g&63)<>2]|=O[b&3],++G);g=c[16];G>N&&56>b&&(c[15]=M<<3,J=!0);var w=f,l=n,m=p,h=q,x=r,y=t,z=u,k=v;for(b=16;64>b;++b)d=c[b-15],e=(d>>>7|d<<25)^(d>>>18|d<<14)^d>>>3,d=c[b-2],d=(d>>>17|d<<15)^(d>>>19|d<<13)^d>>>10,c[b]=c[b-16]+e+c[b-7]+d<<0;H=l&m;for(b=0;64>b;b+=4)I?(B?(E=300032,d=c[0]-1413257819,k=d-150054599<<0,h=d+24177077<<0):(E=704751109,d=c[0]-210244248,k=d-1521486534<<0,h=d+143694565<<0), -I=!1):(e=(w>>>2|w<<30)^(w>>>13|w<<19)^(w>>>22|w<<10),d=(x>>>6|x<<26)^(x>>>11|x<<21)^(x>>>25|x<<7),E=w&l,C=E^w&m^H,D=x&y^~x&z,d=k+d+D+K[b]+c[b],e+=C,k=h+d<<0,h=d+e<<0),e=(h>>>2|h<<30)^(h>>>13|h<<19)^(h>>>22|h<<10),d=(k>>>6|k<<26)^(k>>>11|k<<21)^(k>>>25|k<<7),H=h&w,C=H^h&l^E,D=k&x^~k&y,d=z+d+D+K[b+1]+c[b+1],e+=C,z=m+d<<0,m=d+e<<0,e=(m>>>2|m<<30)^(m>>>13|m<<19)^(m>>>22|m<<10),d=(z>>>6|z<<26)^(z>>>11|z<<21)^(z>>>25|z<<7),E=m&h,C=E^m&w^H,D=z&k^~z&x,d=y+d+D+K[b+2]+c[b+2],e+=C,y=l+d<<0,l=d+e<<0,e=(l>>>2| -l<<30)^(l>>>13|l<<19)^(l>>>22|l<<10),d=(y>>>6|y<<26)^(y>>>11|y<<21)^(y>>>25|y<<7),H=l&m,C=H^l&h^E,D=y&z^~y&k,d=x+d+D+K[b+3]+c[b+3],e+=C,x=w+d<<0,w=d+e<<0;f=f+w<<0;n=n+l<<0;p=p+m<<0;q=q+h<<0;r=r+x<<0;t=t+y<<0;u=u+z<<0;v=v+k<<0}while(!J);f=a[f>>28&15]+a[f>>24&15]+a[f>>20&15]+a[f>>16&15]+a[f>>12&15]+a[f>>8&15]+a[f>>4&15]+a[f&15]+a[n>>28&15]+a[n>>24&15]+a[n>>20&15]+a[n>>16&15]+a[n>>12&15]+a[n>>8&15]+a[n>>4&15]+a[n&15]+a[p>>28&15]+a[p>>24&15]+a[p>>20&15]+a[p>>16&15]+a[p>>12&15]+a[p>>8&15]+a[p>>4&15]+a[p& -15]+a[q>>28&15]+a[q>>24&15]+a[q>>20&15]+a[q>>16&15]+a[q>>12&15]+a[q>>8&15]+a[q>>4&15]+a[q&15]+a[r>>28&15]+a[r>>24&15]+a[r>>20&15]+a[r>>16&15]+a[r>>12&15]+a[r>>8&15]+a[r>>4&15]+a[r&15]+a[t>>28&15]+a[t>>24&15]+a[t>>20&15]+a[t>>16&15]+a[t>>12&15]+a[t>>8&15]+a[t>>4&15]+a[t&15]+a[u>>28&15]+a[u>>24&15]+a[u>>20&15]+a[u>>16&15]+a[u>>12&15]+a[u>>8&15]+a[u>>4&15]+a[u&15];B||(f+=a[v>>28&15]+a[v>>24&15]+a[v>>20&15]+a[v>>16&15]+a[v>>12&15]+a[v>>8&15]+a[v>>4&15]+a[v&15]);return f};!B.JS_SHA256_TEST&&I?(A.sha256= -A,A.sha224=J,module.exports=A):B&&(B.sha256=A,B.sha224=J)})(this); \ No newline at end of file +(function(C,P){var J="undefined"!=typeof module;J&&(C=global);var H="undefined"!=typeof Uint8Array,a="0123456789abcdef".split(""),O=[-2147483648,8388608,32768,128],D=[24,16,8,0],K=[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],c=[];Array.prototype.__ARRAY__=!0;H&&(Uint8Array.prototype.__ARRAY__=!0);var H=function(a){return A(a,!0)},A=function(A,C){var f,n,p,q,r, +t,u,v,g,H=!0,J=!1,b,B=0,L=0,N=0,M=A.length,e,d,E,F,G,I;C?(f=3238371032,n=914150663,p=812702999,q=4144912697,r=4290775857,t=1750603025,u=1694076839,v=3204075428):(f=1779033703,n=3144134277,p=1013904242,q=2773480762,r=1359893119,t=2600822924,u=528734635,v=1541459225);g=0;do{c[0]=g;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;if(A.__ARRAY__)for(b=L;Bb;++B)c[b>>2]|=A[B]<b;++B)g=A.charCodeAt(B),128>g?c[b>>2]|=g<g?c[b>>2]|=(192|g>>6)<g||57344<=g?c[b>>2]|=(224|g>>12)<>2]|=(240|g>>18)<>2]|=(128|g>>12&63)<>2]|=(128|g>>6&63)<>2]|=(128|g&63)<>2]|=O[b&3],++B);g=c[16];B>M&&56>b&&(c[15]=N<<3,J=!0);var w=f,l=n,m=p,h=q,x=r,y=t,z=u,k=v;for(b=16;64>b;++b)d=c[b-15],e=(d>>>7|d<<25)^(d>>>18|d<<14)^d>>>3,d=c[b-2],d=(d>>>17|d<<15)^(d>>>19|d<<13)^d>>>10,c[b]=c[b- +16]+e+c[b-7]+d<<0;I=l&m;for(b=0;64>b;b+=4)H?(C?(G=300032,d=c[0]-1413257819,k=d-150054599<<0,h=d+24177077<<0):(G=704751109,d=c[0]-210244248,k=d-1521486534<<0,h=d+143694565<<0),H=!1):(e=(w>>>2|w<<30)^(w>>>13|w<<19)^(w>>>22|w<<10),d=(x>>>6|x<<26)^(x>>>11|x<<21)^(x>>>25|x<<7),G=w&l,E=G^w&m^I,F=x&y^~x&z,d=k+d+F+K[b]+c[b],e+=E,k=h+d<<0,h=d+e<<0),e=(h>>>2|h<<30)^(h>>>13|h<<19)^(h>>>22|h<<10),d=(k>>>6|k<<26)^(k>>>11|k<<21)^(k>>>25|k<<7),I=h&w,E=I^h&l^G,F=k&x^~k&y,d=z+d+F+K[b+1]+c[b+1],e+=E,z=m+d<<0,m=d+e<< +0,e=(m>>>2|m<<30)^(m>>>13|m<<19)^(m>>>22|m<<10),d=(z>>>6|z<<26)^(z>>>11|z<<21)^(z>>>25|z<<7),G=m&h,E=G^m&w^I,F=z&k^~z&x,d=y+d+F+K[b+2]+c[b+2],e+=E,y=l+d<<0,l=d+e<<0,e=(l>>>2|l<<30)^(l>>>13|l<<19)^(l>>>22|l<<10),d=(y>>>6|y<<26)^(y>>>11|y<<21)^(y>>>25|y<<7),I=l&m,E=I^l&h^G,F=y&z^~y&k,d=x+d+F+K[b+3]+c[b+3],e+=E,x=w+d<<0,w=d+e<<0;f=f+w<<0;n=n+l<<0;p=p+m<<0;q=q+h<<0;r=r+x<<0;t=t+y<<0;u=u+z<<0;v=v+k<<0}while(!J);f=a[f>>28&15]+a[f>>24&15]+a[f>>20&15]+a[f>>16&15]+a[f>>12&15]+a[f>>8&15]+a[f>>4&15]+a[f&15]+ +a[n>>28&15]+a[n>>24&15]+a[n>>20&15]+a[n>>16&15]+a[n>>12&15]+a[n>>8&15]+a[n>>4&15]+a[n&15]+a[p>>28&15]+a[p>>24&15]+a[p>>20&15]+a[p>>16&15]+a[p>>12&15]+a[p>>8&15]+a[p>>4&15]+a[p&15]+a[q>>28&15]+a[q>>24&15]+a[q>>20&15]+a[q>>16&15]+a[q>>12&15]+a[q>>8&15]+a[q>>4&15]+a[q&15]+a[r>>28&15]+a[r>>24&15]+a[r>>20&15]+a[r>>16&15]+a[r>>12&15]+a[r>>8&15]+a[r>>4&15]+a[r&15]+a[t>>28&15]+a[t>>24&15]+a[t>>20&15]+a[t>>16&15]+a[t>>12&15]+a[t>>8&15]+a[t>>4&15]+a[t&15]+a[u>>28&15]+a[u>>24&15]+a[u>>20&15]+a[u>>16&15]+a[u>> +12&15]+a[u>>8&15]+a[u>>4&15]+a[u&15];C||(f+=a[v>>28&15]+a[v>>24&15]+a[v>>20&15]+a[v>>16&15]+a[v>>12&15]+a[v>>8&15]+a[v>>4&15]+a[v&15]);return f};!C.JS_SHA256_TEST&&J?(A.sha256=A,A.sha224=H,module.exports=A):C&&(C.sha256=A,C.sha224=H)})(this); diff --git a/package.json b/package.json index a9f58bf..7c04a83 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "js-sha256", - "version": "0.2.2", + "version": "0.2.3", "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 0e9d675..c1c92f1 100644 --- a/src/sha256.js +++ b/src/sha256.js @@ -1,5 +1,5 @@ /* - * js-sha256 v0.2.2 + * js-sha256 v0.2.3 * https://github.com/emn178/js-sha256 * * Copyright 2014-2015, emn178@gmail.com @@ -14,6 +14,7 @@ if(NODE_JS) { root = global; } + var TYPED_ARRAY = typeof(Uint8Array) != 'undefined'; var HEX_CHARS = '0123456789abcdef'.split(''); var EXTRA = [-2147483648, 8388608, 32768, 128]; var SHIFT = [24, 16, 8, 0]; @@ -28,6 +29,11 @@ var blocks = []; + Array.prototype.__ARRAY__ = true; + if(TYPED_ARRAY) { + Uint8Array.prototype.__ARRAY__ = true; + } + var sha224 = function(message) { return sha256(message, true); }; @@ -63,23 +69,29 @@ 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; - for (i = start;index < length && i < 64; ++index) { - code = message.charCodeAt(index); - if (code < 0x80) { - blocks[i >> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); - blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + if(message.__ARRAY__) { + for (i = start;index < length && i < 64; ++index) { + blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = start;index < length && i < 64; ++index) { + code = message.charCodeAt(index); + if (code < 0x80) { + blocks[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 0x800) { + blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else if (code < 0xd800 || code >= 0xe000) { + blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); + blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } } } bytes += i - start; diff --git a/tests/test.js b/tests/test.js index a66e4d8..6e418d2 100644 --- a/tests/test.js +++ b/tests/test.js @@ -41,6 +41,24 @@ describe('sha256', function() { expect(sha256('012345678012345678012345678012345678012345678012345678012345678012345678')).to.be('6fba9e623ae6abf028a1b195748814aa95eebfb22e3ec5e15d2444cd6c48186a'); }); }); + + describe('Array', function() { + describe('Array', function() { + it('should be successful', 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'); + }); + }); + + describe('Uint8Array', function() { + it('should be successful', function() { + expect(sha256(new Uint8Array([]))).to.be('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'); + expect(sha256(new Uint8Array([211, 212]))).to.be('182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f'); + }); + }); + }); }); describe('sha224', function() {