* Add bower package.

* Fixed JSHint warnings.
* Add travis.
* Add coveralls.
pull/1/merge
Chen Yi-Cyuan 11 years ago
parent 7a5649ff78
commit 629a972486

@ -0,0 +1 @@
/tests/

@ -0,0 +1,12 @@
language: node_js
node_js:
- "0.11"
- "0.10"
- "0.8"
install:
- npm install mocha -g
- npm install coveralls -g
- npm install mocha-lcov-reporter -g
- npm install
script:
- npm run-script coveralls

@ -1,3 +1,10 @@
# v0.1.2 / 2015-01-07
* Add bower package.
* Fixed JSHint warnings.
* Add travis.
* Add coveralls.
# v0.1.1 / 2014-07-27 # v0.1.1 / 2014-07-27
Fixed accents bug Fixed accents bug

@ -1,4 +1,4 @@
Copyright 2014 emn178@gmail.com Copyright 2014-2015 emn178@gmail.com
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

@ -1,20 +1,49 @@
# js-md2 # js-md2
[![Build Status](https://api.travis-ci.org/emn178/js-md5.png)](https://travis-ci.org/emn178/js-md5)
[![Build Status](https://coveralls.io/repos/emn178/js-md5/badge.png?branch=master)](https://coveralls.io/r/emn178/js-md5?branch=master)
[![NPM](https://nodei.co/npm/js-md5.png?stars&downloads)](https://nodei.co/npm/js-md5/)
A simple MD2 hash function for JavaScript supports UTF-8 encoding. A simple MD2 hash function for JavaScript supports UTF-8 encoding.
## Install ## Demo
[MD2 Online](http://emn178.github.io/online-tools/md2.html)
## Download
[Compress](https://raw.github.com/emn178/js-md2/master/build/md2.min.js)
[Uncompress](https://raw.github.com/emn178/js-md2/master/src/md2.js)
## Installation
You can also install js-md2 by using Bower.
bower install js-md2
For node.js, you can use this command to install: For node.js, you can use this command to install:
npm install js-md2 npm install js-md2
## Usage ## Usage
If you use node.js, you should require the module first: You could use like this:
```JavaScript ```JavaScript
md2 = require('js-md2'); md2('Message to hash');
``` ```
And you could use like this: If you use node.js, you should require the module first:
```JavaScript ```JavaScript
md2('Message to hash'); md2 = require('js-md2');
``` ```
### Methods
#### md2(str, asciiOnly)
Hash string to md2, 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 ## Example
Code Code
```JavaScript ```JavaScript
@ -38,15 +67,6 @@ Output
7af93c270b0ec392ca2f0d90a927cf8a 7af93c270b0ec392ca2f0d90a927cf8a
## Tests
You can open `tests/index.html` in browser or use node.js to run test
node tests/node-test.js
or
npm test
## Extensions ## Extensions
### jQuery ### jQuery
If you prefer jQuery style, you can add following code to add a jQuery extension. If you prefer jQuery style, you can add following code to add a jQuery extension.

@ -0,0 +1,9 @@
{
"name": "js-md2",
"version": "0.1.2",
"main": ["build/md2.min.js"],
"ignore": [
"samples",
"tests"
]
}

8
build/md2.min.js vendored

@ -1,4 +1,4 @@
(function(h,n){var k={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},l=[41,46,67,201,162,216,124,1,61,54,84,161,236,240,6,19,98,167,5,243,192,199,115,140,152,147,43,217,188,76,130,202,30,155,87,60,253,212,224,22,103,66,111,24,138,23,229,18,190,78,196,214,218,158,222,73,160,251,245,142,187,47,238,122,169,104,121,145,21,178,7,63,148,194,16,137,11,34,95,33,128,127,93,154,90,144,50,39,53,62,204,231,191,247,151,3,255,25,48,179,72,165,181,209,215,94, (function(l,q){var m="0123456789abcdef".split(""),n=[41,46,67,201,162,216,124,1,61,54,84,161,236,240,6,19,98,167,5,243,192,199,115,140,152,147,43,217,188,76,130,202,30,155,87,60,253,212,224,22,103,66,111,24,138,23,229,18,190,78,196,214,218,158,222,73,160,251,245,142,187,47,238,122,169,104,121,145,21,178,7,63,148,194,16,137,11,34,95,33,128,127,93,154,90,144,50,39,53,62,204,231,191,247,151,3,255,25,48,179,72,165,181,209,215,94,146,42,172,86,170,198,79,184,56,210,150,164,125,182,118,252,107,226,156,
146,42,172,86,170,198,79,184,56,210,150,164,125,182,118,252,107,226,156,116,4,241,69,157,112,89,100,113,135,32,134,91,207,101,230,45,168,2,27,96,37,173,174,176,185,246,28,70,97,105,52,64,126,15,85,71,163,35,221,81,175,58,195,92,249,206,186,197,234,38,44,83,13,110,133,40,132,9,211,223,205,244,65,129,77,82,106,220,55,200,108,193,171,250,36,225,123,8,12,189,177,74,120,136,149,139,227,99,232,109,233,203,213,254,59,0,29,57,242,239,183,14,102,88,208,228,166,119,114,248,235,117,75,10,49,68,80,180,143,237, 116,4,241,69,157,112,89,100,113,135,32,134,91,207,101,230,45,168,2,27,96,37,173,174,176,185,246,28,70,97,105,52,64,126,15,85,71,163,35,221,81,175,58,195,92,249,206,186,197,234,38,44,83,13,110,133,40,132,9,211,223,205,244,65,129,77,82,106,220,55,200,108,193,171,250,36,225,123,8,12,189,177,74,120,136,149,139,227,99,232,109,233,203,213,254,59,0,29,57,242,239,183,14,102,88,208,228,166,119,114,248,235,117,75,10,49,68,80,180,143,237,31,26,219,153,141,51,159,17,131,20],p=function(k,l){var d,h=[],b,a;if(!l&&
31,26,219,153,141,51,159,17,131,20],m=function(d){var a;a:{for(a=d.length;a--;)if(127<d.charCodeAt(a)){a=!0;break a}a=!1}if(a){var e=encodeURIComponent(d);d=[];for(var c=a=0,b=e.length;a<b;++a){var f=e.charCodeAt(a);d[c]=37==f?k[e.charAt(++a)]<<4|k[e.charAt(++a)]:f;++c}e=(c>>4)+1<<4;b=16-(c&15);for(a=c;a<e;++a)d[a]=b}else{b=d.length;a=(b>>4)+1<<4;c=[];for(e=0;e<b;++e)c[e]=d.charCodeAt(e);for(d=16-(b&15);e<a;++e)c[e]=d;d=c}a=[];c=0;e=d.length>>4;for(b=0;b<e;++b)for(f=0;16>f;++f)a[f]^=l[d[(b<<4)+f]^ /[^\x00-\x7F]/.test(k)){d=[];for(a=b=0;a<k.length;a++){var c=k.charCodeAt(a);128>c?d[b++]=c:(2048>c?d[b++]=192|c>>6:(55296>c||57344<=c?d[b++]=224|c>>12:(c=65536+((c&1023)<<10|k.charCodeAt(++a)&1023),d[b++]=240|c>>18,d[b++]=128|c>>12&63),d[b++]=128|c>>6&63),d[b++]=128|c&63)}var f=d.length;b=(f>>4)+1<<4;a=[];for(c=0;c<f;++c)a[c]=d[c];for(d=16-(f&15);c<b;++c)a[c]=d;d=a}else{c=k.length;d=(c>>4)+1<<4;b=[];for(a=0;a<c;++a)b[a]=k.charCodeAt(a);for(c=16-(c&15);a<d;++a)b[a]=c;d=b}b=d;a=[];var c=0,f=b.length>>
c],c=a[f];e=d.length;for(b=0;16>b;++b)d[e+b]=a[b];a=[];for(c=0;48>c;++c)a[c]=0;e=d.length>>4;for(c=0;c<e;++c){for(b=0;16>b;++b)a[16+b]=d[(c<<4)+b],a[32+b]=a[16+b]^a[b];for(b=f=0;18>b;++b){for(var g=0;48>g;++g)a[g]=f=a[g]^l[f];f=f+b&255}}d="";for(c=0;16>c;++c)d+="0123456789abcdef".charAt(a[c]>>4&15)+"0123456789abcdef".charAt(a[c]&15);return d};"undefined"!=typeof module?module.exports=m:h&&(h.md2=m)})(this); 4,e;for(e=0;e<f;++e)for(var g=0;16>g;++g)a[g]^=n[b[(e<<4)+g]^c],c=a[g];f=b.length;for(e=0;16>e;++e)b[f+e]=a[e];for(b=0;48>b;++b)h[b]=0;c=d.length>>4;f="";for(b=0;b<c;++b){for(a=0;16>a;++a)h[16+a]=d[(b<<4)+a],h[32+a]=h[16+a]^h[a];for(a=e=0;18>a;++a){for(g=0;48>g;++g)h[g]=e=h[g]^n[e];e=e+a&255}}for(b=0;16>b;++b)f+=m[h[b]>>4&15]+m[h[b]&15];return f};"undefined"!=typeof module?module.exports=p:l&&(l.md2=p)})(this);

@ -1,10 +1,15 @@
{ {
"name": "js-md2", "name": "js-md2",
"version": "0.1.1", "version": "0.1.2",
"description": "A simple MD2 hash function for JavaScript supports UTF-8 encoding.", "description": "A simple MD2 hash function for JavaScript supports UTF-8 encoding.",
"main": "src/md2.js", "main": "src/md2.js",
"devDependencies": {
"expect.js": "~0.3.1",
"jscoverage": "~0.5.9"
},
"scripts": { "scripts": {
"test": "node tests/node-test.js" "test": "mocha tests/node-test.js -r jscoverage",
"coveralls": "mocha tests/node-test.js -R mocha-lcov-reporter -r jscoverage | coveralls"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

@ -1,22 +1,16 @@
/* /*
* js-md5 v0.1.1 * js-md5 v0.1.2
* https://github.com/emn178/js-md2 * https://github.com/emn178/js-md2
* *
* Copyright 2014, emn178@gmail.com * Copyright 2014-2015, emn178@gmail.com
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * http://www.opensource.org/licenses/MIT
*/ */
;(function(root, undefined) {
;(function(root, undefined){
'use strict'; 'use strict';
var HEX_CHARS = "0123456789abcdef"; var HEX_CHARS = '0123456789abcdef'.split('');
var HEX_TABLE = {
'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
};
var S = [ 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, var S = [ 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
@ -35,99 +29,114 @@
0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14]; 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14];
var md2 = function(message) { var md2 = function(message, asciiOnly) {
var M = hasUTF8(message) ? UTF8toBlocks(message) : ASCIItoBlocks(message); var M, X = [], i, j;
if(!asciiOnly && /[^\x00-\x7F]/.test(message)) {
M = getBlocksFromUtf8(message);
} else {
M = getBlocksFromAscii(message);
}
appendChecksum(M); appendChecksum(M);
var X = []; for(i = 0;i < 48;++i) {
for(var i = 0;i < 48;++i)
X[i] = 0; X[i] = 0;
var length = M.length >> 4; }
for(var i = 0;i < length;++i) var length = M.length >> 4, hex = '';
{ for(i = 0;i < length;++i) {
for(var j = 0;j < 16;++j) for(j = 0;j < 16;++j) {
{
X[16 + j] = M[(i << 4) + j]; X[16 + j] = M[(i << 4) + j];
X[32 + j] = X[16 + j] ^ X[j]; X[32 + j] = X[16 + j] ^ X[j];
} }
var t = 0; var t = 0;
for(var j = 0;j < 18;++j) for(j = 0;j < 18;++j) {
{ for(var k = 0;k < 48;++k) {
for(var k = 0;k < 48;++k)
X[k] = t = X[k] ^ S[t]; X[k] = t = X[k] ^ S[t];
}
t = (t + j) & 0xFF; t = (t + j) & 0xFF;
} }
} }
var hex = ''; for(i = 0;i < 16;++i) {
for(var i = 0;i < 16;++i) hex += HEX_CHARS[(X[i] >> 4) & 0x0F] + HEX_CHARS[X[i] & 0x0F];
hex += HEX_CHARS.charAt((X[i] >> 4) & 0x0F) + HEX_CHARS.charAt(X[i] & 0x0F); }
return hex; return hex;
}; };
var hasUTF8 = function(message) { var getBytesFromUtf8 = function(str) {
for(var i = message.length;i--;) var bytes = [], index = 0;
if(message.charCodeAt(i) > 127) for (var i = 0;i < str.length; i++) {
return true; var c = str.charCodeAt(i);
return false; 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 ASCIItoBlocks = function(message) { var getBlocksFromAscii = function(message) {
// a block is 8 bits(1 bytes), a chunk is 128 bits(16 bytes) // a block is 8 bits(1 bytes), a chunk is 128 bits(16 bytes)
var length = message.length; var length = message.length;
var chunkCount = (length >> 4) + 1; var chunkCount = (length >> 4) + 1;
var blockCount = chunkCount << 4; // chunkCount * 16 var blockCount = chunkCount << 4; // chunkCount * 16
var blocks = []; var blocks = [], i;
var i; for(i = 0;i < length;++i) {
for(i = 0;i < length;++i)
blocks[i] = message.charCodeAt(i); blocks[i] = message.charCodeAt(i);
}
var ibit = 16 - (length & 15); var ibit = 16 - (length & 15);
for(;i < blockCount;++i) for(;i < blockCount;++i) {
blocks[i] = ibit; blocks[i] = ibit;
}
return blocks; return blocks;
}; };
var UTF8toBlocks = function(message) { var getBlocksFromUtf8 = function(message) {
var uri = encodeURIComponent(message); // a block is 8 bits(1 bytes), a chunk is 128 bits(16 bytes)
var blocks = []; var bytes = getBytesFromUtf8(message);
for(var i = 0, bytes = 0, length = uri.length;i < length;++i) var length = bytes.length;
{ var chunkCount = (length >> 4) + 1;
var c = uri.charCodeAt(i); var blockCount = chunkCount << 4; // chunkCount * 16
if(c == 37) // % var blocks = [], i;
blocks[bytes] = (HEX_TABLE[uri.charAt(++i)] << 4) | HEX_TABLE[uri.charAt(++i)]; for(i = 0;i < length;++i) {
else blocks[i] = bytes[i];
blocks[bytes] = c;
++bytes;
} }
var chunkCount = (bytes >> 4) + 1; var ibit = 16 - (length & 15);
var blockCount = chunkCount << 4; // chunkCount * 4 for(;i < blockCount;++i) {
var ibit = 16 - (bytes & 15);
for(var i = bytes;i < blockCount;++i)
blocks[i] = ibit; blocks[i] = ibit;
}
return blocks; return blocks;
}; };
var appendChecksum = function(M) { var appendChecksum = function(M) {
var checksum = []; var checksum = [], L = 0, length = M.length >> 4, i;
var L = 0; for(i = 0;i < length;++i) {
var length = M.length >> 4; for(var j = 0;j < 16;++j) {
for(var i = 0;i < length;++i)
{
for(var j = 0;j < 16;++j)
{
var c = M[(i << 4) + j]; var c = M[(i << 4) + j];
checksum[j] ^= S[c ^ L]; checksum[j] ^= S[c ^ L];
L = checksum[j]; L = checksum[j];
} }
} }
length = M.length; length = M.length;
for(var i = 0;i < 16;++i) for(i = 0;i < 16;++i) {
M[length + i] = checksum[i]; M[length + i] = checksum[i];
}
}; };
if(typeof(module) != 'undefined') if(typeof(module) != 'undefined') {
module.exports = md2; module.exports = md2;
else if(root) } else if(root) {
root.md2 = md2; root.md2 = md2;
}
}(this)); }(this));

@ -1,12 +0,0 @@
(function(root) {
var assert = function (title, expect, actual) {
if(expect == actual)
console.log(title + ': true');
else
console.log(title + ': false', 'Except:' + expect, 'Actual: ' + actual);
};
if(typeof(module) != 'undefined')
global.assert = assert;
else if(root)
root.assert = assert;
})(this);

@ -3,10 +3,20 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>MD2</title> <title>MD2</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
<script src="../src/md2.js"></script> <script src="../src/md2.js"></script>
<script src="debug.js"></script>
<script src="test.js"></script>
</head> </head>
<body> <body>
<div id="mocha"></div>
<script>
mocha.setup('bdd');
</script>
<script src="test.js"></script>
<script>
mocha.checkLeaks();
mocha.run();
</script>
</body> </body>
</html> </html>

@ -1,3 +1,3 @@
md2 = require('../src/md2.js'); md2 = require('../src/md2.js');
require('./debug.js'); expect = require('expect.js');
require('./test.js'); require('./test.js');

@ -1,5 +1,30 @@
assert('md2 1', '8350e5a3e24c153df2275c9f80692773', md2('')); describe('ascii', function() {
assert('md2 2', '03d85a0d629d2c442e987525319fc471', md2('The quick brown fox jumps over the lazy dog')); describe('less than 64 bytes', function() {
assert('md2 3', '71eaa7e440b611e41a6f0d97384b342a', md2('The quick brown fox jumps over the lazy dog.')); it('should be successful', function() {
assert('md2 4', '7af93c270b0ec392ca2f0d90a927cf8a', md2('中文')); expect(md2('')).to.be('8350e5a3e24c153df2275c9f80692773');
assert('md2 5', '628657f2dbd637b6b13500e8567a1c83', md2('aécio')); expect(md2('The quick brown fox jumps over the lazy dog')).to.be('03d85a0d629d2c442e987525319fc471');
expect(md2('The quick brown fox jumps over the lazy dog.')).to.be('71eaa7e440b611e41a6f0d97384b342a');
});
});
describe('more than 64 bytes', function() {
it('should be successful', function() {
expect(md2('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('3658f72434eecc8bdb99047f9710c263');
});
});
});
describe('UTF8', function() {
describe('less than 64 bytes', function() {
it('should be successful', function() {
expect(md2('中文')).to.be('7af93c270b0ec392ca2f0d90a927cf8a');
expect(md2('aécio')).to.be('628657f2dbd637b6b13500e8567a1c83');
});
});
describe('more than 64 bytes', function() {
it('should be successful', function() {
expect(md2('訊息摘要演算法第五版英語Message-Digest Algorithm 5縮寫為MD5是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一又譯雜湊演算法、摘要演算法等主流程式語言普遍已有MD5的實作。')).to.be('4a0cf02bb374a56e9a9a17e426dee995');
});
});
});

Loading…
Cancel
Save