Skip to content

Commit 1034e9d

Browse files
committed
create project
0 parents  commit 1034e9d

File tree

8 files changed

+349
-0
lines changed

8 files changed

+349
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# v0.1.0 / 2014-01-05
2+
3+
Initial release

README.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# js-sha256
2+
This is a simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.
3+
4+
## Install
5+
For node.js, you can use this command to install:
6+
7+
npm install js-sha256
8+
9+
## Usage
10+
If you use node.js, you should require the module first:
11+
```JavaScript
12+
sha256 = require('js-sha256');
13+
```
14+
or
15+
```JavaScript
16+
sha256 = require('js-sha256').sha256;
17+
sha224 = require('js-sha256').sha224;
18+
```
19+
And you could use like this:
20+
```JavaScript
21+
sha256('Message to hash');
22+
sha224('Message to hash');
23+
```
24+
## Example
25+
Code
26+
```JavaScript
27+
sha256('');
28+
sha256('The quick brown fox jumps over the lazy dog');
29+
sha256('The quick brown fox jumps over the lazy dog.');
30+
sha224('');
31+
sha224('The quick brown fox jumps over the lazy dog');
32+
sha224('The quick brown fox jumps over the lazy dog.');
33+
```
34+
Output
35+
36+
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
37+
d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
38+
ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c
39+
d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
40+
730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525
41+
619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c
42+
43+
It also support UTF-8 encoding:
44+
45+
Code
46+
```JavaScript
47+
sha256('中文');
48+
sha224('中文');
49+
```
50+
Output
51+
52+
72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21
53+
dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4
54+
55+
## Tests
56+
You can open `tests/index.html` in browser or use node.js to run test
57+
58+
node tests/node-test.js
59+
60+
or
61+
62+
npm test
63+
64+
## Extensions
65+
### jQuery
66+
If you prefer jQuery style, you can add following code to add a jQuery extension.
67+
68+
Code
69+
```JavaScript
70+
jQuery.sha256 = sha256
71+
jQuery.sha224 = sha224
72+
```
73+
And then you could use like this:
74+
```JavaScript
75+
$.sha256('message');
76+
$.sha224('message');
77+
```
78+
### Prototype
79+
If you prefer prototype style, you can add following code to add a prototype extension.
80+
81+
Code
82+
```JavaScript
83+
String.prototype.sha256 = function() {
84+
return sha256(this);
85+
};
86+
String.prototype.sha224 = function() {
87+
return sha224(this);
88+
};
89+
```
90+
And then you could use like this:
91+
```JavaScript
92+
'message'.sha256();
93+
'message'.sha224();
94+
```
95+
## Contact
96+
The project's website is located at https://github.com/emn178/js-sha256
97+

package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "js-sha256",
3+
"version": "0.1.0",
4+
"description": "A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.",
5+
"main": "src/sha256.js",
6+
"scripts": {
7+
"test": "node tests/node-test.js"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "https://github.com/emn178/js-sha256.git"
12+
},
13+
"keywords": [
14+
"sha",
15+
"sha2",
16+
"sha224",
17+
"sha256",
18+
"hash",
19+
"encryption",
20+
"cryptography",
21+
"HMAC"
22+
],
23+
"author": "emn178 <[email protected]>",
24+
"homepage": "https://github.com/emn178/js-sha256",
25+
"bugs": {
26+
"url": "https://github.com/emn178/js-sha256/issues"
27+
}
28+
}

src/sha256.js

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
(function(root, undefined){
2+
'use strict';
3+
4+
var HEX_CHARS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
5+
var HEX_TABLE = {
6+
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
7+
'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15,
8+
'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15
9+
};
10+
11+
var K =[0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
12+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
13+
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
14+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
15+
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
16+
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
17+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
18+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
19+
20+
var sha256 = function(message) {
21+
return sha2(message, true);
22+
};
23+
24+
var sha224 = function(message) {
25+
return sha2(message, false);
26+
};
27+
28+
var sha2 = function(message, is256) {
29+
if(is256 === undefined)
30+
is256 = true;
31+
32+
var blocks = hasUTF8(message) ? UTF8toBlocks(message) : ASCIItoBlocks(message);
33+
if(is256)
34+
{
35+
var h0 = 0x6a09e667;
36+
var h1 = 0xbb67ae85;
37+
var h2 = 0x3c6ef372;
38+
var h3 = 0xa54ff53a;
39+
var h4 = 0x510e527f;
40+
var h5 = 0x9b05688c;
41+
var h6 = 0x1f83d9ab;
42+
var h7 = 0x5be0cd19;
43+
}
44+
else // 224
45+
{
46+
var h0 = 0xc1059ed8;
47+
var h1 = 0x367cd507;
48+
var h2 = 0x3070dd17;
49+
var h3 = 0xf70e5939;
50+
var h4 = 0xffc00b31;
51+
var h5 = 0x68581511;
52+
var h6 = 0x64f98fa7;
53+
var h7 = 0xbefa4fa4;
54+
}
55+
56+
for(var i = 0, length = blocks.length;i < length;i += 16)
57+
{
58+
var w = [], s0, s1;
59+
for(var j = 0;j < 16;++j)
60+
w[j] = blocks[i + j];
61+
for(var j = 16;j < 64;++j)
62+
{
63+
s0 = rightrotate(w[j - 15], 7) ^ rightrotate(w[j - 15], 18) ^ (w[j - 15] >>> 3);
64+
s1 = rightrotate(w[j - 2], 17) ^ rightrotate(w[j - 2], 19) ^ (w[j - 2] >>> 10);
65+
w[j] = w[j - 16] + s0 + w[j - 7] + s1;
66+
}
67+
68+
var a = h0;
69+
var b = h1;
70+
var c = h2;
71+
var d = h3;
72+
var e = h4;
73+
var f = h5;
74+
var g = h6;
75+
var h = h7;
76+
var maj, t1, t2, ch;
77+
78+
for(var j = 0;j < 64;++j)
79+
{
80+
s0 = rightrotate(a, 2) ^ rightrotate(a, 13) ^ rightrotate(a, 22);
81+
maj = (a & b) ^ (a & c) ^ (b & c);
82+
t2 = s0 + maj;
83+
s1 = rightrotate(e, 6) ^ rightrotate(e, 11) ^ rightrotate(e, 25);
84+
ch = (e & f) ^ ((~ e) & g);
85+
t1 = (h + s1 + ch + K[j] + w[j]) & 0xffffffff;
86+
87+
h = g;
88+
g = f;
89+
f = e;
90+
e = d + t1;
91+
d = c;
92+
c = b;
93+
b = a;
94+
a = t1 + t2;
95+
}
96+
97+
h0 += a;
98+
h1 += b;
99+
h2 += c;
100+
h3 += d;
101+
h4 += e;
102+
h5 += f;
103+
h6 += g;
104+
h7 += h;
105+
}
106+
107+
var hex = toHexString(h0) + toHexString(h1)+ toHexString(h2) + toHexString(h3) + toHexString(h4) + toHexString(h5) + toHexString(h6);
108+
if(is256)
109+
hex += toHexString(h7);
110+
return hex;
111+
};
112+
113+
var rightrotate = function(x, c) {
114+
return (x >>> c) | (x << (32 - c));
115+
};
116+
117+
var toHexString = function(num) {
118+
var hex = "";
119+
for(var i = 0; i < 4; i++)
120+
{
121+
var offset = 3 - i << 3;
122+
hex += HEX_CHARS[(num >> (offset + 4)) & 0x0F] + HEX_CHARS[(num >> offset) & 0x0F];
123+
}
124+
return hex;
125+
};
126+
127+
var hasUTF8 = function(message) {
128+
var i = message.length;
129+
while(i--)
130+
if(message.charCodeAt(i) > 255)
131+
return true;
132+
return false;
133+
};
134+
135+
var ASCIItoBlocks = function(message) {
136+
// a block is 32 bits(4 bytes), a chunk is 512 bits(64 bytes)
137+
var length = message.length;
138+
var chunkCount = ((length + 8) >> 6) + 1;
139+
var blockCount = chunkCount << 4; // chunkCount * 16
140+
var blocks = [];
141+
var i;
142+
for(i = 0;i < blockCount;++i)
143+
blocks[i] = 0;
144+
for(i = 0;i < length;++i)
145+
blocks[i >> 2] |= message.charCodeAt(i) << (3 - (i % 4) << 3);
146+
blocks[i >> 2] |= 0x80 << (3 - (i % 4) << 3);
147+
blocks[blockCount - 1] = length << 3; // length * 8
148+
return blocks;
149+
};
150+
151+
var UTF8toBlocks = function(message) {
152+
var uri = encodeURIComponent(message);
153+
var blocks = [];
154+
for(var i = 0, bytes = 0, length = uri.length;i < length;++i)
155+
{
156+
var c = uri.charCodeAt(i);
157+
if(c == 37) // %
158+
blocks[bytes >> 2] |= ((HEX_TABLE[uri.charAt(++i)] << 4) | HEX_TABLE[uri.charAt(++i)]) << (3 - (bytes % 4) << 3);
159+
else
160+
blocks[bytes >> 2] |= c << (3 - (bytes % 4) << 3);
161+
++bytes;
162+
}
163+
var chunkCount = ((bytes + 8) >> 6) + 1;
164+
var blockCount = chunkCount << 4; // chunkCount * 16
165+
var index = bytes >> 2;
166+
blocks[index] |= 0x80 << (3 - (bytes % 4) << 3);
167+
for(var i = index + 1;i < blockCount;++i)
168+
blocks[i] = 0;
169+
blocks[blockCount - 1] = bytes << 3; // bytes * 8
170+
return blocks;
171+
};
172+
173+
if(typeof(module) != 'undefined')
174+
{
175+
sha256.sha256 = sha256;
176+
sha256.sha224 = sha224;
177+
module.exports = sha256;
178+
}
179+
else if(root)
180+
{
181+
root.sha256 = sha256;
182+
root.sha224 = sha224;
183+
}
184+
}(this));

tests/debug.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(function(root) {
2+
var assert = function (title, expect, actual) {
3+
if(expect == actual)
4+
console.log(title + ': true');
5+
else
6+
console.log(title + ': false', 'Except:' + expect, 'Actual: ' + actual);
7+
};
8+
if(typeof(module) != 'undefined')
9+
global.assert = assert;
10+
else if(root)
11+
root.assert = assert;
12+
})(this);

tests/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>SHA256</title>
6+
<script src="../src/sha256.js"></script>
7+
<script src="debug.js"></script>
8+
<script src="test.js"></script>
9+
</head>
10+
<body>
11+
</body>
12+
</html>

tests/node-test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// this also works:
2+
// sha256 = require('../src/sha256.js');
3+
4+
sha256 = require('../src/sha256.js').sha256;
5+
sha224 = require('../src/sha256.js').sha224;
6+
require('./debug.js');
7+
require('./test.js');

tests/test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
assert('sha256 1', 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', sha256(''));
2+
assert('sha256 2', 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592', sha256('The quick brown fox jumps over the lazy dog'));
3+
assert('sha256 3', 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c', sha256('The quick brown fox jumps over the lazy dog.'));
4+
assert('sha224 1', 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f', sha224(''));
5+
assert('sha224 2', '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525', sha224('The quick brown fox jumps over the lazy dog'));
6+
assert('sha224 3', '619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c', sha224('The quick brown fox jumps over the lazy dog.'));

0 commit comments

Comments
 (0)