diff --git a/.travis.yml b/.travis.yml index f5cd45c..aabe614 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,11 @@ node_js: - "0.11" - "0.10" - "0.8" -install: +before_install: - npm install mocha -g - npm install coveralls -g - npm install mocha-lcov-reporter -g - - npm install -script: - - npm run-script coveralls +script: npm run-script coveralls +branches: + only: + - master diff --git a/CHANGELOG.md b/CHANGELOG.md index 8afb8d3..bf66ce4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v0.2.0 / 2015-02-16 + +* Support byte array input. +* Remove ascii parameter. +* Improve performance. +* Add test cases. + # v0.1.3 / 2015-01-07 * Add bower package. diff --git a/README.md b/README.md index df290ee..5da35c8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # js-sha1 -[![Build Status](https://api.travis-ci.org/emn178/js-sha1.png)](https://travis-ci.org/emn178/js-sha1) -[![Build Status](https://coveralls.io/repos/emn178/js-sha1/badge.png?branch=master)](https://coveralls.io/r/emn178/js-sha1?branch=master) +[![Build Status](https://travis-ci.org/emn178/js-sha1.svg?branch=master)](https://travis-ci.org/emn178/js-sha1) +[![Coverage Status](https://coveralls.io/repos/emn178/js-sha1/badge.svg?branch=master)](https://coveralls.io/r/emn178/js-sha1?branch=master) [![NPM](https://nodei.co/npm/js-sha1.png?stars&downloads)](https://nodei.co/npm/js-sha1/) A simple SHA1 hash function for JavaScript supports UTF-8 encoding. @@ -30,20 +30,6 @@ If you use node.js, you should require the module first: sha1 = require('js-sha1'); ``` -### Methods - -#### sha1(str, asciiOnly) - -Hash string to sha1, set asciiOnly to true for better performace if you ensure input is ascii. - -##### *str: `String`* - -String to hash. - -##### *asciiOnly: `Boolean` (default: `false`)* - -Specify the string encoding is ASCII. - ## Example Code ```JavaScript @@ -67,13 +53,25 @@ Output 7be2d2d20c106eee0836c9bc2b939890a78e8fb3 +It also supports byte Array or Uint8Array input: + +Code +```JavaScript +sha1([]); +sha1(new Uint8Array([])); +``` +Output + + da39a3ee5e6b4b0d3255bfef95601890afd80709 + da39a3ee5e6b4b0d3255bfef95601890afd80709 + ## Extensions ### jQuery If you prefer jQuery style, you can add following code to add a jQuery extension. Code ```JavaScript -jQuery.sha1 = sha1 +jQuery.sha1 = sha1; ``` And then you could use like this: ```JavaScript diff --git a/bower.json b/bower.json index 92d5c5a..403d6d4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "js-sha1", - "version": "0.1.3", + "version": "0.2.0", "main": ["build/sha1.min.js"], "ignore": [ "samples", diff --git a/build/sha1.min.js b/build/sha1.min.js index fcfe920..eca2be5 100644 --- a/build/sha1.min.js +++ b/build/sha1.min.js @@ -1,3 +1,6 @@ -(function(t,y){var v="0123456789abcdef".split(""),w={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,b:11,c:12,d:13,e:14,f:15,A:10,B:11,C:12,D:13,E:14,F:15},x=function(e){var a;a:{for(a=e.length;a--;)if(127>2]=37==r?e[a>>2]|(w[c.charAt(++d)]<<4|w[c.charAt(++d)])<<(3-a%4<<3):e[a>>2]|r<<(3-a%4<<3);++a}c=(a+8>>6)+1<<4;d=a>>2;e[d]|=128<<(3-a%4<<3);for(d+=1;d>6)+1<<4;c=[];for(f=0;f>2]|=e.charCodeAt(f)<<(3-f%4<<3);c[f>>2]|=128<<(3-f%4<<3);c[d-1]=a<<3;e=c}a=1732584193;for(var d=4023233417,c=2562383102,f=271733878,r=3285377520,u=0,t=e.length;ub;++b)n[b]=e[u+b];for(b=16;80>b;++b)n[b]=p(n[b-3]^n[b-8]^n[b-14]^n[b-16],1);for(var m=a,h=d,k=c,l=f,q=r,g,b=0;20>b;++b)g=h&k|~h&l,g=p(m,5)+g+q+1518500249+n[b],q=l,l=k,k=p(h,30),h=m,m=g;for(;40>b;++b)g=h^k^l,g=p(m,5)+ -g+q+1859775393+n[b],q=l,l=k,k=p(h,30),h=m,m=g;for(;60>b;++b)g=h&k|h&l|k&l,g=p(m,5)+g+q+2400959708+n[b],q=l,l=k,k=p(h,30),h=m,m=g;for(;80>b;++b)g=h^k^l,g=p(m,5)+g+q+3395469782+n[b],q=l,l=k,k=p(h,30),h=m,m=g;a+=m;d+=h;c+=k;f+=l;r+=q}return s(a)+s(d)+s(c)+s(f)+s(r)},p=function(e,a){return e<>>32-a},s=function(e){for(var a="",c=0;4>c;c++)var d=3-c<<3,a=a+(v[e>>d+4&15]+v[e>>d&15]);return a};"undefined"!=typeof module?module.exports=x:t&&(t.sha1=x)})(this); +(function(x,C){"undefined"!=typeof module&&(x=global);var v="undefined"!=typeof Uint8Array,k="0123456789abcdef".split(""),B=[-2147483648,8388608,32768,128],w=[24,16,8,0],b=[];Array.prototype.__ARRAY__=!0;v&&(Uint8Array.prototype.__ARRAY__=!0);v=function(y){var n,p,q,r,t,m=0,x=!1,a,l,h,u=0,v=0,A=0,z=y.length;n=1732584193;p=4023233417;q=2562383102;r=271733878;t=3285377520;do{b[0]=m;b[16]=b[1]=b[2]=b[3]=b[4]=b[5]=b[6]=b[7]=b[8]=b[9]=b[10]=b[11]=b[12]=b[13]=b[14]=b[15]=0;if(y.__ARRAY__)for(a=v;u +a;++u)b[a>>2]|=y[u]<a;++u)m=y.charCodeAt(u),128>m?b[a>>2]|=m<m?b[a>>2]|=(192|m>>6)<m||57344<=m?b[a>>2]|=(224|m>>12)<>2]|=(240|m>>18)<>2]|=(128|m>>12&63)<>2]|=(128|m>>6&63)<>2]|=(128|m&63)<>2]|=B[a&3],++u);m=b[16];u>z&&56>a&&(b[15]=A<<3,x=!0);for(h=16;80>h;++h)a=b[h-3]^b[h-8]^b[h-14]^b[h-16],b[h]= +a<<1|a>>>31;var c=n,d=p,e=q,f=r,g=t;for(h=0;20>h;h+=5)l=d&e|~d&f,a=c<<5|c>>>27,g=a+l+g+1518500249+b[h]<<0,d=d<<30|d>>>2,l=c&d|~c&e,a=g<<5|g>>>27,f=a+l+f+1518500249+b[h+1]<<0,c=c<<30|c>>>2,l=g&c|~g&d,a=f<<5|f>>>27,e=a+l+e+1518500249+b[h+2]<<0,g=g<<30|g>>>2,l=f&g|~f&c,a=e<<5|e>>>27,d=a+l+d+1518500249+b[h+3]<<0,f=f<<30|f>>>2,l=e&f|~e&g,a=d<<5|d>>>27,c=a+l+c+1518500249+b[h+4]<<0,e=e<<30|e>>>2;for(;40>h;h+=5)l=d^e^f,a=c<<5|c>>>27,g=a+l+g+1859775393+b[h]<<0,d=d<<30|d>>>2,l=c^d^e,a=g<<5|g>>>27,f=a+l+f+1859775393+ +b[h+1]<<0,c=c<<30|c>>>2,l=g^c^d,a=f<<5|f>>>27,e=a+l+e+1859775393+b[h+2]<<0,g=g<<30|g>>>2,l=f^g^c,a=e<<5|e>>>27,d=a+l+d+1859775393+b[h+3]<<0,f=f<<30|f>>>2,l=e^f^g,a=d<<5|d>>>27,c=a+l+c+1859775393+b[h+4]<<0,e=e<<30|e>>>2;for(;60>h;h+=5)l=d&e|d&f|e&f,a=c<<5|c>>>27,g=a+l+g-1894007588+b[h]<<0,d=d<<30|d>>>2,l=c&d|c&e|d&e,a=g<<5|g>>>27,f=a+l+f-1894007588+b[h+1]<<0,c=c<<30|c>>>2,l=g&c|g&d|c&d,a=f<<5|f>>>27,e=a+l+e-1894007588+b[h+2]<<0,g=g<<30|g>>>2,l=f&g|f&c|g&c,a=e<<5|e>>>27,d=a+l+d-1894007588+b[h+3]<<0, +f=f<<30|f>>>2,l=e&f|e&g|f&g,a=d<<5|d>>>27,c=a+l+c-1894007588+b[h+4]<<0,e=e<<30|e>>>2;for(;80>h;h+=5)l=d^e^f,a=c<<5|c>>>27,g=a+l+g-899497514+b[h]<<0,d=d<<30|d>>>2,l=c^d^e,a=g<<5|g>>>27,f=a+l+f-899497514+b[h+1]<<0,c=c<<30|c>>>2,l=g^c^d,a=f<<5|f>>>27,e=a+l+e-899497514+b[h+2]<<0,g=g<<30|g>>>2,l=f^g^c,a=e<<5|e>>>27,d=a+l+d-899497514+b[h+3]<<0,f=f<<30|f>>>2,l=e^f^g,a=d<<5|d>>>27,c=a+l+c-899497514+b[h+4]<<0,e=e<<30|e>>>2;n=n+c<<0;p=p+d<<0;q=q+e<<0;r=r+f<<0;t=t+g<<0}while(!x);return k[n>>28&15]+k[n>>24&15]+ +k[n>>20&15]+k[n>>16&15]+k[n>>12&15]+k[n>>8&15]+k[n>>4&15]+k[n&15]+k[p>>28&15]+k[p>>24&15]+k[p>>20&15]+k[p>>16&15]+k[p>>12&15]+k[p>>8&15]+k[p>>4&15]+k[p&15]+k[q>>28&15]+k[q>>24&15]+k[q>>20&15]+k[q>>16&15]+k[q>>12&15]+k[q>>8&15]+k[q>>4&15]+k[q&15]+k[r>>28&15]+k[r>>24&15]+k[r>>20&15]+k[r>>16&15]+k[r>>12&15]+k[r>>8&15]+k[r>>4&15]+k[r&15]+k[t>>28&15]+k[t>>24&15]+k[t>>20&15]+k[t>>16&15]+k[t>>12&15]+k[t>>8&15]+k[t>>4&15]+k[t&15]};x.JS_SHA1_TEST||"undefined"==typeof module?x&&(x.sha1=v):module.exports=v})(this); diff --git a/package.json b/package.json index 3566fad..abdfde4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "js-sha1", - "version": "0.1.3", + "version": "0.2.0", "description": "A simple SHA1 hash function for JavaScript supports UTF-8 encoding.", "main": "src/sha1.js", "devDependencies": { diff --git a/src/sha1.js b/src/sha1.js index c594935..6c33be8 100644 --- a/src/sha1.js +++ b/src/sha1.js @@ -1,5 +1,5 @@ /* - * js-sha1 v0.1.3 + * js-sha1 v0.2.0 * https://github.com/emn178/js-sha1 * * Copyright 2014-2015, emn178@gmail.com @@ -10,161 +10,219 @@ ;(function(root, undefined){ 'use strict'; + var NODE_JS = typeof(module) != 'undefined'; + 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]; + + var blocks = []; + + Array.prototype.__ARRAY__ = true; + if(TYPED_ARRAY) { + Uint8Array.prototype.__ARRAY__ = true; + } + + var sha1 = function(message) { + var h0, h1, h2, h3, h4, block = 0, code, end = false, t, f, + i, j, index = 0, start = 0, bytes = 0, length = message.length; - var sha1 = function(message, asciiOnly) { - var blocks, h0, h1, h2, h3, h4; - if(!asciiOnly && /[^\x00-\x7F]/.test(message)) { - blocks = getBlocksFromUtf8(message); - } else { - blocks = getBlocksFromAscii(message); - } h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476; h4 = 0xC3D2E1F0; - for(var i = 0, length = blocks.length;i < length;i += 16) { - var w = [], j; - for(j = 0;j < 16;++j) { - w[j] = blocks[i + j]; + do { + blocks[0] = 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(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]; + } + } } - for(j = 16;j < 80;++j) { - var x = w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16]; - w[j] = leftrotate(x, 1); + 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; } - var a = h0; - var b = h1; - var c = h2; - var d = h3; - var e = h4; - var f, tmp; + for(j = 16;j < 80;++j) { + t = blocks[j - 3] ^ blocks[j - 8] ^ blocks[j - 14] ^ blocks[j - 16]; + blocks[j] = (t << 1) | (t >>> 31); + } - for(j = 0;j < 20;++j) { + var a = h0, b = h1, c = h2, d = h3, e = h4; + for(j = 0;j < 20;j += 5) { f = (b & c) | ((~b) & d); - tmp = leftrotate(a, 5) + f + e + 0x5A827999 + w[j]; - e = d; - d = c; - c = leftrotate(b, 30); - b = a; - a = tmp; + t = (a << 5) | (a >>> 27); + e = t + f + e + 1518500249 + blocks[j] << 0; + b = (b << 30) | (b >>> 2); + + f = (a & b) | ((~a) & c); + t = (e << 5) | (e >>> 27); + d = t + f + d + 1518500249 + blocks[j + 1] << 0; + a = (a << 30) | (a >>> 2); + + f = (e & a) | ((~e) & b); + t = (d << 5) | (d >>> 27); + c = t + f + c + 1518500249 + blocks[j + 2] << 0; + e = (e << 30) | (e >>> 2); + + f = (d & e) | ((~d) & a); + t = (c << 5) | (c >>> 27); + b = t + f + b + 1518500249 + blocks[j + 3] << 0; + d = (d << 30) | (d >>> 2); + + f = (c & d) | ((~c) & e); + t = (b << 5) | (b >>> 27); + a = t + f + a + 1518500249 + blocks[j + 4] << 0; + c = (c << 30) | (c >>> 2); } - for(;j < 40;++j) { + for(;j < 40;j += 5) { f = b ^ c ^ d; - tmp = leftrotate(a, 5) + f + e + 0x6ED9EBA1 + w[j]; - e = d; - d = c; - c = leftrotate(b, 30); - b = a; - a = tmp; + t = (a << 5) | (a >>> 27); + e = t + f + e + 1859775393 + blocks[j] << 0; + b = (b << 30) | (b >>> 2); + + f = a ^ b ^ c; + t = (e << 5) | (e >>> 27); + d = t + f + d + 1859775393 + blocks[j + 1] << 0; + a = (a << 30) | (a >>> 2); + + f = e ^ a ^ b; + t = (d << 5) | (d >>> 27); + c = t + f + c + 1859775393 + blocks[j + 2] << 0; + e = (e << 30) | (e >>> 2); + + f = d ^ e ^ a; + t = (c << 5) | (c >>> 27); + b = t + f + b + 1859775393 + blocks[j + 3] << 0; + d = (d << 30) | (d >>> 2); + + f = c ^ d ^ e; + t = (b << 5) | (b >>> 27); + a = t + f + a + 1859775393 + blocks[j + 4] << 0; + c = (c << 30) | (c >>> 2); } - // k = 0x8F1BBCDC; - for(;j < 60;++j) { + for(;j < 60;j += 5) { f = (b & c) | (b & d) | (c & d); - tmp = leftrotate(a, 5) + f + e + 0x8F1BBCDC + w[j]; - e = d; - d = c; - c = leftrotate(b, 30); - b = a; - a = tmp; + t = (a << 5) | (a >>> 27); + e = t + f + e - 1894007588 + blocks[j] << 0; + b = (b << 30) | (b >>> 2); + + f = (a & b) | (a & c) | (b & c); + t = (e << 5) | (e >>> 27); + d = t + f + d - 1894007588 + blocks[j + 1] << 0; + a = (a << 30) | (a >>> 2); + + f = (e & a) | (e & b) | (a & b); + t = (d << 5) | (d >>> 27); + c = t + f + c - 1894007588 + blocks[j + 2] << 0; + e = (e << 30) | (e >>> 2); + + f = (d & e) | (d & a) | (e & a); + t = (c << 5) | (c >>> 27); + b = t + f + b - 1894007588 + blocks[j + 3] << 0; + d = (d << 30) | (d >>> 2); + + f = (c & d) | (c & e) | (d & e); + t = (b << 5) | (b >>> 27); + a = t + f + a - 1894007588 + blocks[j + 4] << 0; + c = (c << 30) | (c >>> 2); } - for(;j < 80;++j) { + for(;j < 80;j += 5) { f = b ^ c ^ d; - tmp = leftrotate(a, 5) + f + e + 0xCA62C1D6 + w[j]; - e = d; - d = c; - c = leftrotate(b, 30); - b = a; - a = tmp; + t = (a << 5) | (a >>> 27); + e = t + f + e - 899497514 + blocks[j] << 0; + b = (b << 30) | (b >>> 2); + + f = a ^ b ^ c; + t = (e << 5) | (e >>> 27); + d = t + f + d - 899497514 + blocks[j + 1] << 0; + a = (a << 30) | (a >>> 2); + + f = e ^ a ^ b; + t = (d << 5) | (d >>> 27); + c = t + f + c - 899497514 + blocks[j + 2] << 0; + e = (e << 30) | (e >>> 2); + + f = d ^ e ^ a; + t = (c << 5) | (c >>> 27); + b = t + f + b - 899497514 + blocks[j + 3] << 0; + d = (d << 30) | (d >>> 2); + + f = c ^ d ^ e; + t = (b << 5) | (b >>> 27); + a = t + f + a - 899497514 + blocks[j + 4] << 0; + c = (c << 30) | (c >>> 2); } - h0 += a; - h1 += b; - h2 += c; - h3 += d; - h4 += e; - } - - return toHexString(h0) + toHexString(h1)+ toHexString(h2) + toHexString(h3) + toHexString(h4); - }; - - var leftrotate = function(x, c) { - return (x << c) | (x >>> (32 - c)); - }; - - var toHexString = function(num) { - var hex = ''; - for(var i = 0; i < 4; i++) { - var offset = 3 - i << 3; - hex += HEX_CHARS[(num >> (offset + 4)) & 0x0F] + HEX_CHARS[(num >> offset) & 0x0F]; - } - return hex; - }; - - var getBytesFromUtf8 = function(str) { - var bytes = [], index = 0; - for (var i = 0;i < str.length; i++) { - var c = str.charCodeAt(i); - if (c < 0x80) { - bytes[index++] = c; - } else if (c < 0x800) { - bytes[index++] = 0xc0 | (c >> 6); - bytes[index++] = 0x80 | (c & 0x3f); - } else if (c < 0xd800 || c >= 0xe000) { - bytes[index++] = 0xe0 | (c >> 12); - bytes[index++] = 0x80 | ((c >> 6) & 0x3f); - bytes[index++] = 0x80 | (c & 0x3f); - } else { - c = 0x10000 + (((c & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff)); - bytes[index++] = 0xf0 | (c >> 18); - bytes[index++] = 0x80 | ((c >> 12) & 0x3f); - bytes[index++] = 0x80 | ((c >> 6) & 0x3f); - bytes[index++] = 0x80 | (c & 0x3f); - } - } - return bytes; - }; - - var getBlocksFromAscii = function(message) { - // a block is 32 bits(4 bytes), a chunk is 512 bits(64 bytes) - var length = message.length; - var chunkCount = ((length + 8) >> 6) + 1; - var blockCount = chunkCount << 4; // chunkCount * 16 - var blocks = [], i; - for(i = 0;i < blockCount;++i) { - blocks[i] = 0; - } - for(i = 0;i < length;++i) { - blocks[i >> 2] |= message.charCodeAt(i) << (3 - (i & 3) << 3); - } - blocks[i >> 2] |= 0x80 << (3 - (i & 3) << 3); - blocks[blockCount - 1] = length << 3; // length * 8 - return blocks; - }; - - var getBlocksFromUtf8 = function(message) { - var bytes = getBytesFromUtf8(message); - var length = bytes.length; - var chunkCount = ((length + 8) >> 6) + 1; - var blockCount = chunkCount << 4; // chunkCount * 16 - var blocks = [], i; - for(i = 0;i < blockCount;++i) { - blocks[i] = 0; - } - for(i = 0;i < length;++i) { - blocks[i >> 2] |= bytes[i] << (3 - (i & 3) << 3); - } - blocks[i >> 2] |= 0x80 << (3 - (i & 3) << 3); - blocks[blockCount - 1] = length << 3; // length * 8 - return blocks; + h0 = h0 + a << 0; + h1 = h1 + b << 0; + h2 = h2 + c << 0; + h3 = h3 + d << 0; + h4 = h4 + e << 0; + } while(!end); + + return 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]; }; - if(typeof(module) != 'undefined') { + if(!root.JS_SHA1_TEST && typeof(module) != 'undefined') { module.exports = sha1; } else if(root) { diff --git a/tests/node-test.js b/tests/node-test.js index d0c0fa7..d8a2426 100644 --- a/tests/node-test.js +++ b/tests/node-test.js @@ -1,3 +1,11 @@ sha1 = require('../src/sha1.js'); expect = require('expect.js'); require('./test.js'); + +delete require.cache[require.resolve('../src/sha1.js')] +delete require.cache[require.resolve('./test.js')] +sha1 = null; + +JS_SHA1_TEST = true; +require('../src/sha1.js'); +require('./test.js'); diff --git a/tests/test.js b/tests/test.js index d40a3d2..94e4dd4 100644 --- a/tests/test.js +++ b/tests/test.js @@ -1,30 +1,60 @@ -describe('ascii', function() { - describe('less than 64 bytes', function() { - it('should be successful', function() { - expect(sha1('')).to.be('da39a3ee5e6b4b0d3255bfef95601890afd80709'); - expect(sha1('The quick brown fox jumps over the lazy dog')).to.be('2fd4e1c67a2d28fced849ee1bb76e7391b93eb12'); - expect(sha1('The quick brown fox jumps over the lazy dog.', true)).to.be('408d94384216f890ff7a0c3528e8bed1e0b01621'); +(function(sha1) { + describe('ascii', function() { + describe('less than 64 bytes', function() { + it('should be successful', function() { + expect(sha1('')).to.be('da39a3ee5e6b4b0d3255bfef95601890afd80709'); + expect(sha1('The quick brown fox jumps over the lazy dog')).to.be('2fd4e1c67a2d28fced849ee1bb76e7391b93eb12'); + expect(sha1('The quick brown fox jumps over the lazy dog.')).to.be('408d94384216f890ff7a0c3528e8bed1e0b01621'); + }); + }); + + describe('more than 64 bytes', function() { + it('should be successful', function() { + expect(sha1('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('8690faab7755408a03875895176fac318f14a699'); + }); }); }); - describe('more than 64 bytes', function() { - it('should be successful', function() { - expect(sha1('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('8690faab7755408a03875895176fac318f14a699'); + describe('UTF8', function() { + describe('less than 64 bytes', function() { + it('should be successful', function() { + expect(sha1('中文')).to.be('7be2d2d20c106eee0836c9bc2b939890a78e8fb3'); + expect(sha1('aécio')).to.be('9e4e5d978deced901d621475b03f1ded19e945bf'); + expect(sha1('𠜎')).to.be('4667688a63420661469c8dbc0f871770349bab08'); + }); + }); + + describe('more than 64 bytes', function() { + it('should be successful', function() { + expect(sha1('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一')).to.be('ad8aae581c915fe01c4964a5e8b322cae74ee5c5'); + expect(sha1('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。')).to.be('3a15ad3ce9efdd4bf982eaaaecdeda36a887a3f9'); + }); }); }); -}); -describe('UTF8', function() { - describe('less than 64 bytes', function() { + describe('special length', function() { it('should be successful', function() { - expect(sha1('中文')).to.be('7be2d2d20c106eee0836c9bc2b939890a78e8fb3'); - expect(sha1('aécio')).to.be('9e4e5d978deced901d621475b03f1ded19e945bf'); + expect(sha1('0123456780123456780123456780123456780123456780123456780')).to.be('4cdeae78e8b7285aef73e0a15eec7d5b30f3f3e3'); + expect(sha1('01234567801234567801234567801234567801234567801234567801')).to.be('e657e6bb6b5d0c2bf7e929451c14a5302589a60b'); + expect(sha1('0123456780123456780123456780123456780123456780123456780123456780')).to.be('e7ad97591c1a99d54d80751d341899769884c75a'); + expect(sha1('01234567801234567801234567801234567801234567801234567801234567801234567')).to.be('55a13698cdc010c0d16dab2f7dc10f43a713f12f'); + expect(sha1('012345678012345678012345678012345678012345678012345678012345678012345678')).to.be('006575418c27b0158e55a6d261c46f86b33a496a'); }); }); - describe('more than 64 bytes', function() { - it('should be successful', function() { - expect(sha1('訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一(又譯雜湊演算法、摘要演算法等),主流程式語言普遍已有MD5的實作。')).to.be('3a15ad3ce9efdd4bf982eaaaecdeda36a887a3f9'); + describe('Array', function() { + describe('Array', function() { + it('should be successful', function() { + expect(sha1([])).to.be('da39a3ee5e6b4b0d3255bfef95601890afd80709'); + expect(sha1([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('2fd4e1c67a2d28fced849ee1bb76e7391b93eb12'); + expect(sha1([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('55a13698cdc010c0d16dab2f7dc10f43a713f12f'); + }); + }); + + describe('Uint8Array', function() { + it('should be successful', function() { + expect(sha1(new Uint8Array([]))).to.be('da39a3ee5e6b4b0d3255bfef95601890afd80709'); + }); }); }); -}); +})(sha1);