├── .gitignore ├── .github ├── FUNDING.yml └── workflows │ └── test.yml ├── bin └── sync-vendor-libs.sh ├── test ├── index.html ├── test.js └── vendor │ └── mocha.css ├── LICENSE.txt ├── package.json ├── index.html ├── css └── demo.css ├── js ├── md5.min.js ├── md5.min.js.map └── md5.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [blueimp] 2 | -------------------------------------------------------------------------------- /bin/sync-vendor-libs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd "$(dirname "$0")/.." 3 | cp node_modules/chai/chai.js test/vendor/ 4 | cp node_modules/mocha/mocha.js test/vendor/ 5 | cp node_modules/mocha/mocha.css test/vendor/ 6 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | node-version: [14, 16] 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: actions/setup-node@v2 14 | with: 15 | node-version: ${{ matrix.node-version }} 16 | - run: npm install 17 | - run: npm run build --if-present 18 | - run: npm run test 19 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 19 | 20 | JavaScript MD5 Test 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 31 | 32 | 33 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright © 2011 Sebastian Tschan, https://blueimp.net 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blueimp-md5", 3 | "version": "2.19.0", 4 | "title": "JavaScript MD5", 5 | "description": "JavaScript MD5 implementation. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.", 6 | "keywords": [ 7 | "javascript", 8 | "md5" 9 | ], 10 | "homepage": "https://github.com/blueimp/JavaScript-MD5", 11 | "author": { 12 | "name": "Sebastian Tschan", 13 | "url": "https://blueimp.net" 14 | }, 15 | "contributors": [ 16 | { 17 | "name": "Paul Johnston", 18 | "url": "http://pajhome.org.uk/crypt/md5" 19 | } 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "git://github.com/blueimp/JavaScript-MD5.git" 24 | }, 25 | "license": "MIT", 26 | "devDependencies": { 27 | "chai": "4", 28 | "eslint": "7", 29 | "eslint-config-blueimp": "2", 30 | "eslint-config-prettier": "8", 31 | "eslint-plugin-jsdoc": "36", 32 | "eslint-plugin-prettier": "4", 33 | "mocha": "9", 34 | "prettier": "2", 35 | "uglify-js": "3" 36 | }, 37 | "eslintConfig": { 38 | "extends": [ 39 | "blueimp", 40 | "plugin:jsdoc/recommended", 41 | "plugin:prettier/recommended" 42 | ], 43 | "env": { 44 | "browser": true, 45 | "node": true 46 | } 47 | }, 48 | "eslintIgnore": [ 49 | "js/*.min.js", 50 | "test/vendor" 51 | ], 52 | "prettier": { 53 | "arrowParens": "avoid", 54 | "proseWrap": "always", 55 | "semi": false, 56 | "singleQuote": true, 57 | "trailingComma": "none" 58 | }, 59 | "scripts": { 60 | "lint": "eslint .", 61 | "unit": "mocha", 62 | "test": "npm run lint && npm run unit", 63 | "prebuild": "bin/sync-vendor-libs.sh", 64 | "build": "cd js && uglifyjs md5.js -c -m -o md5.min.js --source-map url=md5.min.js.map", 65 | "preversion": "npm test", 66 | "version": "npm run build && git add -A js", 67 | "postversion": "git push --tags origin master master:gh-pages && npm publish" 68 | }, 69 | "files": [ 70 | "js/*.js", 71 | "js/*.js.map" 72 | ], 73 | "main": "js/md5.js" 74 | } 75 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * JavaScript MD5 Test 3 | * https://github.com/blueimp/JavaScript-MD5 4 | * 5 | * Copyright 2011, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * https://opensource.org/licenses/MIT 10 | */ 11 | 12 | /* global describe, it */ 13 | 14 | /* eslint-disable strict */ 15 | 16 | ;(function (expect, md5) { 17 | 'use strict' 18 | 19 | describe('MD5 Hex-encoding', function () { 20 | it('should create a hex-encoded MD5 hash of an ASCII value', function () { 21 | expect(md5('value')).to.equal('2063c1608d6e0baf80249c42e2be5804') 22 | }) 23 | 24 | it('should create a hex-encoded MD5 hash of an UTF-8 value', function () { 25 | expect(md5('日本')).to.equal('4dbed2e657457884e67137d3514119b3') 26 | }) 27 | }) 28 | 29 | describe('HMAC-MD5 Hex-encoding', function () { 30 | it('should create a hex-encoded HMAC-MD5 hash of an ASCII value and key', function () { 31 | expect(md5('value', 'key')).to.equal('01433efd5f16327ea4b31144572c67f6') 32 | }) 33 | 34 | it('should create a hex-encoded HMAC-MD5 hash of an UTF-8 value and key', function () { 35 | expect(md5('日本', '日本')).to.equal('c78b8c7357926981cc04740bd3e9d015') 36 | }) 37 | }) 38 | 39 | describe('MD5 raw encoding', function () { 40 | it('should create a raw MD5 hash of an ASCII value', function () { 41 | expect(md5('value', null, true)).to.equal( 42 | ' c\xc1`\x8dn\x0b\xaf\x80$\x9cB\xe2\xbeX\x04' 43 | ) 44 | }) 45 | 46 | it('should create a raw MD5 hash of an UTF-8 value', function () { 47 | expect(md5('日本', null, true)).to.equal( 48 | 'M\xbe\xd2\xe6WEx\x84\xe6q7\xd3QA\x19\xb3' 49 | ) 50 | }) 51 | }) 52 | 53 | describe('HMAC-MD5 raw encoding', function () { 54 | it('should create a raw HMAC-MD5 hash of an ASCII value and key', function () { 55 | expect(md5('value', 'key', true)).to.equal( 56 | '\x01C>\xfd_\x162~\xa4\xb3\x11DW,g\xf6' 57 | ) 58 | }) 59 | 60 | it('should create a raw HMAC-MD5 hash of an UTF-8 value and key', function () { 61 | expect(md5('日本', '日本', true)).to.equal( 62 | '\xc7\x8b\x8csW\x92i\x81\xcc\x04t\x0b\xd3\xe9\xd0\x15' 63 | ) 64 | }) 65 | }) 66 | })((this.chai || require('chai')).expect, this.md5 || require('../js/md5')) 67 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 19 | 20 | JavaScript MD5 Demo 21 | 25 | 26 | 27 | 28 | 29 |

JavaScript MD5 Demo

30 |

31 | JavaScript 32 | MD5 implementation.
33 | Compatible with server-side environments like 34 | Node.js, module loaders like 35 | RequireJS or 36 | webpack and all web browsers. 37 |

38 | 56 | 57 |
58 |

59 | 60 | 61 |

62 |

63 | 70 | 71 |

72 |

73 | 74 | 75 |

76 |
77 | 78 | 79 | -------------------------------------------------------------------------------- /css/demo.css: -------------------------------------------------------------------------------- 1 | /* 2 | * JavaScript MD5 Demo CSS 3 | * https://github.com/blueimp/JavaScript-MD5 4 | * 5 | * Copyright 2013, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * https://opensource.org/licenses/MIT 10 | */ 11 | 12 | body { 13 | max-width: 990px; 14 | margin: 0 auto; 15 | padding: 1em; 16 | font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', 17 | Arial, sans-serif; 18 | -webkit-text-size-adjust: 100%; 19 | line-height: 1.4; 20 | background: #212121; 21 | color: #dedede; 22 | } 23 | a { 24 | color: #61afef; 25 | text-decoration: none; 26 | } 27 | a:visited { 28 | color: #56b6c2; 29 | } 30 | a:hover { 31 | color: #98c379; 32 | } 33 | h1 { 34 | margin-top: 0.5em; 35 | margin-bottom: 0.5em; 36 | } 37 | label { 38 | display: inline-block; 39 | margin-bottom: 0.25em; 40 | } 41 | button, 42 | input, 43 | textarea { 44 | -webkit-appearance: none; 45 | box-sizing: border-box; 46 | margin: 0; 47 | padding: 0.5em 0.75em; 48 | font-family: inherit; 49 | font-size: 100%; 50 | line-height: 1.4; 51 | background: #414141; 52 | color: #dedede; 53 | border: 1px solid #363636; 54 | border-radius: 5px; 55 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.07); 56 | } 57 | input, 58 | textarea { 59 | display: block; 60 | width: 100%; 61 | box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.07); 62 | } 63 | textarea { 64 | display: block; 65 | overflow: auto; 66 | } 67 | button { 68 | background: #3c76a7; 69 | background: linear-gradient(180deg, #3c76a7, #225c8d); 70 | border-color: #225c8d; 71 | color: #fff; 72 | } 73 | button[type='submit'] { 74 | background: #6fa349; 75 | background: linear-gradient(180deg, #6fa349, #568a30); 76 | border-color: #568a30; 77 | } 78 | button[type='reset'] { 79 | background: #d79435; 80 | background: linear-gradient(180deg, #d79435, #be7b1c); 81 | border-color: #be7b1c; 82 | } 83 | button:active { 84 | box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.5); 85 | } 86 | 87 | @media (prefers-color-scheme: light) { 88 | body { 89 | background: #ececec; 90 | color: #212121; 91 | } 92 | a { 93 | color: #225c8d; 94 | } 95 | a:visited { 96 | color: #378f9a; 97 | } 98 | a:hover { 99 | color: #6fa349; 100 | } 101 | input, 102 | textarea { 103 | background: #fff; 104 | border-color: #d1d1d1; 105 | color: #212121; 106 | } 107 | } 108 | 109 | @media (min-width: 540px) { 110 | #navigation { 111 | list-style: none; 112 | padding: 0; 113 | } 114 | #navigation li { 115 | display: inline-block; 116 | } 117 | #navigation li:not(:first-child)::before { 118 | content: ' | '; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /js/md5.min.js: -------------------------------------------------------------------------------- 1 | !function(n){"use strict";function d(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function f(n,t,r,e,o,u){return d((u=d(d(t,n),d(e,u)))<>>32-o,r)}function l(n,t,r,e,o,u,c){return f(t&r|~t&e,n,t,o,u,c)}function g(n,t,r,e,o,u,c){return f(t&e|r&~e,n,t,o,u,c)}function v(n,t,r,e,o,u,c){return f(t^r^e,n,t,o,u,c)}function m(n,t,r,e,o,u,c){return f(r^(t|~e),n,t,o,u,c)}function c(n,t){var r,e,o,u;n[t>>5]|=128<>>9<<4)]=t;for(var c=1732584193,f=-271733879,i=-1732584194,a=271733878,h=0;h>5]>>>e%32&255);return t}function a(n){var t=[];for(t[(n.length>>2)-1]=void 0,e=0;e>5]|=(255&n.charCodeAt(e/8))<>>4&15)+r.charAt(15&t);return e}function r(n){return unescape(encodeURIComponent(n))}function o(n){return i(c(a(n=r(n)),8*n.length))}function u(n,t){return function(n,t){var r,e=a(n),o=[],u=[];for(o[15]=u[15]=void 0,16 37 | ``` 38 | 39 | In your application code, calculate the 40 | ([hex](https://en.wikipedia.org/wiki/Hexadecimal)-encoded) 41 | [MD5](https://en.wikipedia.org/wiki/MD5) hash of a string by calling the **md5** 42 | method with the string as argument: 43 | 44 | ```js 45 | var hash = md5('value') // "2063c1608d6e0baf80249c42e2be5804" 46 | ``` 47 | 48 | ### Server-side 49 | 50 | The following is an example how to use the JavaScript MD5 module on the 51 | server-side with [Node.js](https://nodejs.org/). 52 | 53 | Install the **blueimp-md5** package with [NPM](https://www.npmjs.org/): 54 | 55 | ```sh 56 | npm install blueimp-md5 57 | ``` 58 | 59 | Add a file **server.js** with the following content: 60 | 61 | ```js 62 | require('http') 63 | .createServer(function (req, res) { 64 | // The md5 module exports the md5() function: 65 | var md5 = require('./md5'), 66 | // Use the following version if you installed the package with npm: 67 | // var md5 = require("blueimp-md5"), 68 | url = require('url'), 69 | query = url.parse(req.url).query 70 | res.writeHead(200, { 'Content-Type': 'text/plain' }) 71 | // Calculate and print the MD5 hash of the url query: 72 | res.end(md5(query)) 73 | }) 74 | .listen(8080, 'localhost') 75 | console.log('Server running at http://localhost:8080/') 76 | ``` 77 | 78 | Run the application with the following command: 79 | 80 | ```sh 81 | node server.js 82 | ``` 83 | 84 | ## Requirements 85 | 86 | The JavaScript MD5 script has zero dependencies. 87 | 88 | ## API 89 | 90 | Calculate the ([hex](https://en.wikipedia.org/wiki/Hexadecimal)-encoded) 91 | [MD5](https://en.wikipedia.org/wiki/MD5) hash of a given string value: 92 | 93 | ```js 94 | var hash = md5('value') // "2063c1608d6e0baf80249c42e2be5804" 95 | ``` 96 | 97 | Calculate the ([hex](https://en.wikipedia.org/wiki/Hexadecimal)-encoded) 98 | [HMAC](https://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given string value and 99 | key: 100 | 101 | ```js 102 | var hash = md5('value', 'key') // "01433efd5f16327ea4b31144572c67f6" 103 | ``` 104 | 105 | Calculate the raw [MD5](https://en.wikipedia.org/wiki/MD5) hash of a given 106 | string value: 107 | 108 | ```js 109 | var hash = md5('value', null, true) 110 | ``` 111 | 112 | Calculate the raw [HMAC](https://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given 113 | string value and key: 114 | 115 | ```js 116 | var hash = md5('value', 'key', true) 117 | ``` 118 | 119 | ## Tests 120 | 121 | The JavaScript MD5 project comes with 122 | [Unit Tests](https://en.wikipedia.org/wiki/Unit_testing). 123 | There are two different ways to run the tests: 124 | 125 | - Open test/index.html in your browser or 126 | - run `npm test` in the Terminal in the root path of the repository package. 127 | 128 | The first one tests the browser integration, the second one the 129 | [Node.js](https://nodejs.org/) integration. 130 | 131 | ## License 132 | 133 | The JavaScript MD5 script is released under the 134 | [MIT license](https://opensource.org/licenses/MIT). 135 | -------------------------------------------------------------------------------- /js/md5.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["md5.js"],"names":["$","safeAdd","x","y","lsw","md5cmn","q","a","b","s","t","num","md5ff","c","d","md5gg","md5hh","md5ii","binlMD5","len","olda","oldb","oldc","oldd","i","length","binl2rstr","input","output","length32","String","fromCharCode","rstr2binl","undefined","length8","charCodeAt","rstr2hex","hexTab","charAt","str2rstrUTF8","unescape","encodeURIComponent","rawMD5","rawHMACMD5","k","key","data","bkey","ipad","opad","hash","concat","rstrHMACMD5","md5","string","raw","define","amd","module","exports","this"],"mappings":"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"} -------------------------------------------------------------------------------- /test/vendor/mocha.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | body { 4 | margin:0; 5 | } 6 | 7 | #mocha { 8 | font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif; 9 | margin: 60px 50px; 10 | } 11 | 12 | #mocha ul, 13 | #mocha li { 14 | margin: 0; 15 | padding: 0; 16 | } 17 | 18 | #mocha ul { 19 | list-style: none; 20 | } 21 | 22 | #mocha h1, 23 | #mocha h2 { 24 | margin: 0; 25 | } 26 | 27 | #mocha h1 { 28 | margin-top: 15px; 29 | font-size: 1em; 30 | font-weight: 200; 31 | } 32 | 33 | #mocha h1 a { 34 | text-decoration: none; 35 | color: inherit; 36 | } 37 | 38 | #mocha h1 a:hover { 39 | text-decoration: underline; 40 | } 41 | 42 | #mocha .suite .suite h1 { 43 | margin-top: 0; 44 | font-size: .8em; 45 | } 46 | 47 | #mocha .hidden { 48 | display: none; 49 | } 50 | 51 | #mocha h2 { 52 | font-size: 12px; 53 | font-weight: normal; 54 | cursor: pointer; 55 | } 56 | 57 | #mocha .suite { 58 | margin-left: 15px; 59 | } 60 | 61 | #mocha .test { 62 | margin-left: 15px; 63 | overflow: hidden; 64 | } 65 | 66 | #mocha .test.pending:hover h2::after { 67 | content: '(pending)'; 68 | font-family: arial, sans-serif; 69 | } 70 | 71 | #mocha .test.pass.medium .duration { 72 | background: #c09853; 73 | } 74 | 75 | #mocha .test.pass.slow .duration { 76 | background: #b94a48; 77 | } 78 | 79 | #mocha .test.pass::before { 80 | content: '✓'; 81 | font-size: 12px; 82 | display: block; 83 | float: left; 84 | margin-right: 5px; 85 | color: #00d6b2; 86 | } 87 | 88 | #mocha .test.pass .duration { 89 | font-size: 9px; 90 | margin-left: 5px; 91 | padding: 2px 5px; 92 | color: #fff; 93 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); 94 | -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); 95 | box-shadow: inset 0 1px 1px rgba(0,0,0,.2); 96 | -webkit-border-radius: 5px; 97 | -moz-border-radius: 5px; 98 | -ms-border-radius: 5px; 99 | -o-border-radius: 5px; 100 | border-radius: 5px; 101 | } 102 | 103 | #mocha .test.pass.fast .duration { 104 | display: none; 105 | } 106 | 107 | #mocha .test.pending { 108 | color: #0b97c4; 109 | } 110 | 111 | #mocha .test.pending::before { 112 | content: '◦'; 113 | color: #0b97c4; 114 | } 115 | 116 | #mocha .test.fail { 117 | color: #c00; 118 | } 119 | 120 | #mocha .test.fail pre { 121 | color: black; 122 | } 123 | 124 | #mocha .test.fail::before { 125 | content: '✖'; 126 | font-size: 12px; 127 | display: block; 128 | float: left; 129 | margin-right: 5px; 130 | color: #c00; 131 | } 132 | 133 | #mocha .test pre.error { 134 | color: #c00; 135 | max-height: 300px; 136 | overflow: auto; 137 | } 138 | 139 | #mocha .test .html-error { 140 | overflow: auto; 141 | color: black; 142 | display: block; 143 | float: left; 144 | clear: left; 145 | font: 12px/1.5 monaco, monospace; 146 | margin: 5px; 147 | padding: 15px; 148 | border: 1px solid #eee; 149 | max-width: 85%; /*(1)*/ 150 | max-width: -webkit-calc(100% - 42px); 151 | max-width: -moz-calc(100% - 42px); 152 | max-width: calc(100% - 42px); /*(2)*/ 153 | max-height: 300px; 154 | word-wrap: break-word; 155 | border-bottom-color: #ddd; 156 | -webkit-box-shadow: 0 1px 3px #eee; 157 | -moz-box-shadow: 0 1px 3px #eee; 158 | box-shadow: 0 1px 3px #eee; 159 | -webkit-border-radius: 3px; 160 | -moz-border-radius: 3px; 161 | border-radius: 3px; 162 | } 163 | 164 | #mocha .test .html-error pre.error { 165 | border: none; 166 | -webkit-border-radius: 0; 167 | -moz-border-radius: 0; 168 | border-radius: 0; 169 | -webkit-box-shadow: 0; 170 | -moz-box-shadow: 0; 171 | box-shadow: 0; 172 | padding: 0; 173 | margin: 0; 174 | margin-top: 18px; 175 | max-height: none; 176 | } 177 | 178 | /** 179 | * (1): approximate for browsers not supporting calc 180 | * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border) 181 | * ^^ seriously 182 | */ 183 | #mocha .test pre { 184 | display: block; 185 | float: left; 186 | clear: left; 187 | font: 12px/1.5 monaco, monospace; 188 | margin: 5px; 189 | padding: 15px; 190 | border: 1px solid #eee; 191 | max-width: 85%; /*(1)*/ 192 | max-width: -webkit-calc(100% - 42px); 193 | max-width: -moz-calc(100% - 42px); 194 | max-width: calc(100% - 42px); /*(2)*/ 195 | word-wrap: break-word; 196 | border-bottom-color: #ddd; 197 | -webkit-box-shadow: 0 1px 3px #eee; 198 | -moz-box-shadow: 0 1px 3px #eee; 199 | box-shadow: 0 1px 3px #eee; 200 | -webkit-border-radius: 3px; 201 | -moz-border-radius: 3px; 202 | border-radius: 3px; 203 | } 204 | 205 | #mocha .test h2 { 206 | position: relative; 207 | } 208 | 209 | #mocha .test a.replay { 210 | position: absolute; 211 | top: 3px; 212 | right: 0; 213 | text-decoration: none; 214 | vertical-align: middle; 215 | display: block; 216 | width: 15px; 217 | height: 15px; 218 | line-height: 15px; 219 | text-align: center; 220 | background: #eee; 221 | font-size: 15px; 222 | -webkit-border-radius: 15px; 223 | -moz-border-radius: 15px; 224 | border-radius: 15px; 225 | -webkit-transition:opacity 200ms; 226 | -moz-transition:opacity 200ms; 227 | -o-transition:opacity 200ms; 228 | transition: opacity 200ms; 229 | opacity: 0.3; 230 | color: #888; 231 | } 232 | 233 | #mocha .test:hover a.replay { 234 | opacity: 1; 235 | } 236 | 237 | #mocha-report.pass .test.fail { 238 | display: none; 239 | } 240 | 241 | #mocha-report.fail .test.pass { 242 | display: none; 243 | } 244 | 245 | #mocha-report.pending .test.pass, 246 | #mocha-report.pending .test.fail { 247 | display: none; 248 | } 249 | #mocha-report.pending .test.pass.pending { 250 | display: block; 251 | } 252 | 253 | #mocha-error { 254 | color: #c00; 255 | font-size: 1.5em; 256 | font-weight: 100; 257 | letter-spacing: 1px; 258 | } 259 | 260 | #mocha-stats { 261 | position: fixed; 262 | top: 15px; 263 | right: 10px; 264 | font-size: 12px; 265 | margin: 0; 266 | color: #888; 267 | z-index: 1; 268 | } 269 | 270 | #mocha-stats .progress { 271 | float: right; 272 | padding-top: 0; 273 | 274 | /** 275 | * Set safe initial values, so mochas .progress does not inherit these 276 | * properties from Bootstrap .progress (which causes .progress height to 277 | * equal line height set in Bootstrap). 278 | */ 279 | height: auto; 280 | -webkit-box-shadow: none; 281 | -moz-box-shadow: none; 282 | box-shadow: none; 283 | background-color: initial; 284 | } 285 | 286 | #mocha-stats em { 287 | color: black; 288 | } 289 | 290 | #mocha-stats a { 291 | text-decoration: none; 292 | color: inherit; 293 | } 294 | 295 | #mocha-stats a:hover { 296 | border-bottom: 1px solid #eee; 297 | } 298 | 299 | #mocha-stats li { 300 | display: inline-block; 301 | margin: 0 5px; 302 | list-style: none; 303 | padding-top: 11px; 304 | } 305 | 306 | #mocha-stats canvas { 307 | width: 40px; 308 | height: 40px; 309 | } 310 | 311 | #mocha code .comment { color: #ddd; } 312 | #mocha code .init { color: #2f6fad; } 313 | #mocha code .string { color: #5890ad; } 314 | #mocha code .keyword { color: #8a6343; } 315 | #mocha code .number { color: #2f6fad; } 316 | 317 | @media screen and (max-device-width: 480px) { 318 | #mocha { 319 | margin: 60px 0px; 320 | } 321 | 322 | #mocha #stats { 323 | position: absolute; 324 | } 325 | } 326 | -------------------------------------------------------------------------------- /js/md5.js: -------------------------------------------------------------------------------- 1 | /* 2 | * JavaScript MD5 3 | * https://github.com/blueimp/JavaScript-MD5 4 | * 5 | * Copyright 2011, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * https://opensource.org/licenses/MIT 10 | * 11 | * Based on 12 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message 13 | * Digest Algorithm, as defined in RFC 1321. 14 | * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 15 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 16 | * Distributed under the BSD License 17 | * See http://pajhome.org.uk/crypt/md5 for more info. 18 | */ 19 | 20 | /* global define */ 21 | 22 | /* eslint-disable strict */ 23 | 24 | ;(function ($) { 25 | 'use strict' 26 | 27 | /** 28 | * Add integers, wrapping at 2^32. 29 | * This uses 16-bit operations internally to work around bugs in interpreters. 30 | * 31 | * @param {number} x First integer 32 | * @param {number} y Second integer 33 | * @returns {number} Sum 34 | */ 35 | function safeAdd(x, y) { 36 | var lsw = (x & 0xffff) + (y & 0xffff) 37 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16) 38 | return (msw << 16) | (lsw & 0xffff) 39 | } 40 | 41 | /** 42 | * Bitwise rotate a 32-bit number to the left. 43 | * 44 | * @param {number} num 32-bit number 45 | * @param {number} cnt Rotation count 46 | * @returns {number} Rotated number 47 | */ 48 | function bitRotateLeft(num, cnt) { 49 | return (num << cnt) | (num >>> (32 - cnt)) 50 | } 51 | 52 | /** 53 | * Basic operation the algorithm uses. 54 | * 55 | * @param {number} q q 56 | * @param {number} a a 57 | * @param {number} b b 58 | * @param {number} x x 59 | * @param {number} s s 60 | * @param {number} t t 61 | * @returns {number} Result 62 | */ 63 | function md5cmn(q, a, b, x, s, t) { 64 | return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b) 65 | } 66 | /** 67 | * Basic operation the algorithm uses. 68 | * 69 | * @param {number} a a 70 | * @param {number} b b 71 | * @param {number} c c 72 | * @param {number} d d 73 | * @param {number} x x 74 | * @param {number} s s 75 | * @param {number} t t 76 | * @returns {number} Result 77 | */ 78 | function md5ff(a, b, c, d, x, s, t) { 79 | return md5cmn((b & c) | (~b & d), a, b, x, s, t) 80 | } 81 | /** 82 | * Basic operation the algorithm uses. 83 | * 84 | * @param {number} a a 85 | * @param {number} b b 86 | * @param {number} c c 87 | * @param {number} d d 88 | * @param {number} x x 89 | * @param {number} s s 90 | * @param {number} t t 91 | * @returns {number} Result 92 | */ 93 | function md5gg(a, b, c, d, x, s, t) { 94 | return md5cmn((b & d) | (c & ~d), a, b, x, s, t) 95 | } 96 | /** 97 | * Basic operation the algorithm uses. 98 | * 99 | * @param {number} a a 100 | * @param {number} b b 101 | * @param {number} c c 102 | * @param {number} d d 103 | * @param {number} x x 104 | * @param {number} s s 105 | * @param {number} t t 106 | * @returns {number} Result 107 | */ 108 | function md5hh(a, b, c, d, x, s, t) { 109 | return md5cmn(b ^ c ^ d, a, b, x, s, t) 110 | } 111 | /** 112 | * Basic operation the algorithm uses. 113 | * 114 | * @param {number} a a 115 | * @param {number} b b 116 | * @param {number} c c 117 | * @param {number} d d 118 | * @param {number} x x 119 | * @param {number} s s 120 | * @param {number} t t 121 | * @returns {number} Result 122 | */ 123 | function md5ii(a, b, c, d, x, s, t) { 124 | return md5cmn(c ^ (b | ~d), a, b, x, s, t) 125 | } 126 | 127 | /** 128 | * Calculate the MD5 of an array of little-endian words, and a bit length. 129 | * 130 | * @param {Array} x Array of little-endian words 131 | * @param {number} len Bit length 132 | * @returns {Array} MD5 Array 133 | */ 134 | function binlMD5(x, len) { 135 | /* append padding */ 136 | x[len >> 5] |= 0x80 << len % 32 137 | x[(((len + 64) >>> 9) << 4) + 14] = len 138 | 139 | var i 140 | var olda 141 | var oldb 142 | var oldc 143 | var oldd 144 | var a = 1732584193 145 | var b = -271733879 146 | var c = -1732584194 147 | var d = 271733878 148 | 149 | for (i = 0; i < x.length; i += 16) { 150 | olda = a 151 | oldb = b 152 | oldc = c 153 | oldd = d 154 | 155 | a = md5ff(a, b, c, d, x[i], 7, -680876936) 156 | d = md5ff(d, a, b, c, x[i + 1], 12, -389564586) 157 | c = md5ff(c, d, a, b, x[i + 2], 17, 606105819) 158 | b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330) 159 | a = md5ff(a, b, c, d, x[i + 4], 7, -176418897) 160 | d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426) 161 | c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341) 162 | b = md5ff(b, c, d, a, x[i + 7], 22, -45705983) 163 | a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416) 164 | d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417) 165 | c = md5ff(c, d, a, b, x[i + 10], 17, -42063) 166 | b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162) 167 | a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682) 168 | d = md5ff(d, a, b, c, x[i + 13], 12, -40341101) 169 | c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290) 170 | b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329) 171 | 172 | a = md5gg(a, b, c, d, x[i + 1], 5, -165796510) 173 | d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632) 174 | c = md5gg(c, d, a, b, x[i + 11], 14, 643717713) 175 | b = md5gg(b, c, d, a, x[i], 20, -373897302) 176 | a = md5gg(a, b, c, d, x[i + 5], 5, -701558691) 177 | d = md5gg(d, a, b, c, x[i + 10], 9, 38016083) 178 | c = md5gg(c, d, a, b, x[i + 15], 14, -660478335) 179 | b = md5gg(b, c, d, a, x[i + 4], 20, -405537848) 180 | a = md5gg(a, b, c, d, x[i + 9], 5, 568446438) 181 | d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690) 182 | c = md5gg(c, d, a, b, x[i + 3], 14, -187363961) 183 | b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501) 184 | a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467) 185 | d = md5gg(d, a, b, c, x[i + 2], 9, -51403784) 186 | c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473) 187 | b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734) 188 | 189 | a = md5hh(a, b, c, d, x[i + 5], 4, -378558) 190 | d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463) 191 | c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562) 192 | b = md5hh(b, c, d, a, x[i + 14], 23, -35309556) 193 | a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060) 194 | d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353) 195 | c = md5hh(c, d, a, b, x[i + 7], 16, -155497632) 196 | b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640) 197 | a = md5hh(a, b, c, d, x[i + 13], 4, 681279174) 198 | d = md5hh(d, a, b, c, x[i], 11, -358537222) 199 | c = md5hh(c, d, a, b, x[i + 3], 16, -722521979) 200 | b = md5hh(b, c, d, a, x[i + 6], 23, 76029189) 201 | a = md5hh(a, b, c, d, x[i + 9], 4, -640364487) 202 | d = md5hh(d, a, b, c, x[i + 12], 11, -421815835) 203 | c = md5hh(c, d, a, b, x[i + 15], 16, 530742520) 204 | b = md5hh(b, c, d, a, x[i + 2], 23, -995338651) 205 | 206 | a = md5ii(a, b, c, d, x[i], 6, -198630844) 207 | d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415) 208 | c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905) 209 | b = md5ii(b, c, d, a, x[i + 5], 21, -57434055) 210 | a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571) 211 | d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606) 212 | c = md5ii(c, d, a, b, x[i + 10], 15, -1051523) 213 | b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799) 214 | a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359) 215 | d = md5ii(d, a, b, c, x[i + 15], 10, -30611744) 216 | c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380) 217 | b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649) 218 | a = md5ii(a, b, c, d, x[i + 4], 6, -145523070) 219 | d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379) 220 | c = md5ii(c, d, a, b, x[i + 2], 15, 718787259) 221 | b = md5ii(b, c, d, a, x[i + 9], 21, -343485551) 222 | 223 | a = safeAdd(a, olda) 224 | b = safeAdd(b, oldb) 225 | c = safeAdd(c, oldc) 226 | d = safeAdd(d, oldd) 227 | } 228 | return [a, b, c, d] 229 | } 230 | 231 | /** 232 | * Convert an array of little-endian words to a string 233 | * 234 | * @param {Array} input MD5 Array 235 | * @returns {string} MD5 string 236 | */ 237 | function binl2rstr(input) { 238 | var i 239 | var output = '' 240 | var length32 = input.length * 32 241 | for (i = 0; i < length32; i += 8) { 242 | output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff) 243 | } 244 | return output 245 | } 246 | 247 | /** 248 | * Convert a raw string to an array of little-endian words 249 | * Characters >255 have their high-byte silently ignored. 250 | * 251 | * @param {string} input Raw input string 252 | * @returns {Array} Array of little-endian words 253 | */ 254 | function rstr2binl(input) { 255 | var i 256 | var output = [] 257 | output[(input.length >> 2) - 1] = undefined 258 | for (i = 0; i < output.length; i += 1) { 259 | output[i] = 0 260 | } 261 | var length8 = input.length * 8 262 | for (i = 0; i < length8; i += 8) { 263 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32 264 | } 265 | return output 266 | } 267 | 268 | /** 269 | * Calculate the MD5 of a raw string 270 | * 271 | * @param {string} s Input string 272 | * @returns {string} Raw MD5 string 273 | */ 274 | function rstrMD5(s) { 275 | return binl2rstr(binlMD5(rstr2binl(s), s.length * 8)) 276 | } 277 | 278 | /** 279 | * Calculates the HMAC-MD5 of a key and some data (raw strings) 280 | * 281 | * @param {string} key HMAC key 282 | * @param {string} data Raw input string 283 | * @returns {string} Raw MD5 string 284 | */ 285 | function rstrHMACMD5(key, data) { 286 | var i 287 | var bkey = rstr2binl(key) 288 | var ipad = [] 289 | var opad = [] 290 | var hash 291 | ipad[15] = opad[15] = undefined 292 | if (bkey.length > 16) { 293 | bkey = binlMD5(bkey, key.length * 8) 294 | } 295 | for (i = 0; i < 16; i += 1) { 296 | ipad[i] = bkey[i] ^ 0x36363636 297 | opad[i] = bkey[i] ^ 0x5c5c5c5c 298 | } 299 | hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8) 300 | return binl2rstr(binlMD5(opad.concat(hash), 512 + 128)) 301 | } 302 | 303 | /** 304 | * Convert a raw string to a hex string 305 | * 306 | * @param {string} input Raw input string 307 | * @returns {string} Hex encoded string 308 | */ 309 | function rstr2hex(input) { 310 | var hexTab = '0123456789abcdef' 311 | var output = '' 312 | var x 313 | var i 314 | for (i = 0; i < input.length; i += 1) { 315 | x = input.charCodeAt(i) 316 | output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f) 317 | } 318 | return output 319 | } 320 | 321 | /** 322 | * Encode a string as UTF-8 323 | * 324 | * @param {string} input Input string 325 | * @returns {string} UTF8 string 326 | */ 327 | function str2rstrUTF8(input) { 328 | return unescape(encodeURIComponent(input)) 329 | } 330 | 331 | /** 332 | * Encodes input string as raw MD5 string 333 | * 334 | * @param {string} s Input string 335 | * @returns {string} Raw MD5 string 336 | */ 337 | function rawMD5(s) { 338 | return rstrMD5(str2rstrUTF8(s)) 339 | } 340 | /** 341 | * Encodes input string as Hex encoded string 342 | * 343 | * @param {string} s Input string 344 | * @returns {string} Hex encoded string 345 | */ 346 | function hexMD5(s) { 347 | return rstr2hex(rawMD5(s)) 348 | } 349 | /** 350 | * Calculates the raw HMAC-MD5 for the given key and data 351 | * 352 | * @param {string} k HMAC key 353 | * @param {string} d Input string 354 | * @returns {string} Raw MD5 string 355 | */ 356 | function rawHMACMD5(k, d) { 357 | return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d)) 358 | } 359 | /** 360 | * Calculates the Hex encoded HMAC-MD5 for the given key and data 361 | * 362 | * @param {string} k HMAC key 363 | * @param {string} d Input string 364 | * @returns {string} Raw MD5 string 365 | */ 366 | function hexHMACMD5(k, d) { 367 | return rstr2hex(rawHMACMD5(k, d)) 368 | } 369 | 370 | /** 371 | * Calculates MD5 value for a given string. 372 | * If a key is provided, calculates the HMAC-MD5 value. 373 | * Returns a Hex encoded string unless the raw argument is given. 374 | * 375 | * @param {string} string Input string 376 | * @param {string} [key] HMAC key 377 | * @param {boolean} [raw] Raw output switch 378 | * @returns {string} MD5 output 379 | */ 380 | function md5(string, key, raw) { 381 | if (!key) { 382 | if (!raw) { 383 | return hexMD5(string) 384 | } 385 | return rawMD5(string) 386 | } 387 | if (!raw) { 388 | return hexHMACMD5(key, string) 389 | } 390 | return rawHMACMD5(key, string) 391 | } 392 | 393 | if (typeof define === 'function' && define.amd) { 394 | define(function () { 395 | return md5 396 | }) 397 | } else if (typeof module === 'object' && module.exports) { 398 | module.exports = md5 399 | } else { 400 | $.md5 = md5 401 | } 402 | })(this) 403 | --------------------------------------------------------------------------------