├── .editorconfig ├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── bin └── hashes ├── bower.json ├── component.json ├── examples ├── client │ ├── base64.html │ ├── benchmark.html │ ├── custom.html │ ├── hexadecimal.html │ ├── hmac.html │ ├── others.html │ └── uppercase.html └── server │ ├── base64.js │ ├── benchmark.js │ ├── custom.js │ ├── hexadecimal.js │ ├── hmac.js │ └── uppercase.js ├── hashes.d.ts ├── hashes.js ├── hashes.min.js ├── package.json └── test ├── crc32.js ├── hashes.js ├── hmac.js └── mocha.opts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [Makefile] 12 | charset = utf-8 13 | indent_style = tabs 14 | indent_size = 2 15 | end_of_line = lf 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - stable 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2017, Tomas Aparicio 2 | Copyright (c) 1999-2012, Paul Johnston, Angel Marin, Jeremy Lin 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of the nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | UGLIFYJS = ./node_modules/.bin/uglifyjs 2 | BANNER = "/*! jshashes - New BSD License - https://github.com/h2non/jshashes */" 3 | 4 | build: 5 | $(UGLIFYJS) hashes.js --mangle --preamble $(BANNER) > hashes.min.js 6 | 7 | loc: 8 | wc -l hashes.js 9 | 10 | publish: test build 11 | git push --tags origin HEAD:master 12 | npm publish 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jsHashes [![Build Status](https://travis-ci.org/h2non/jshashes.svg)](https://travis-ci.org/h2non/jshashes) [![NPM version](https://img.shields.io/npm/v/jshashes.svg)](https://www.npmjs.com/package/jshashes) [![](https://data.jsdelivr.com/v1/package/npm/jshashes/badge)](https://www.jsdelivr.com/package/npm/jshashes) 2 | 3 | `jshashes` is lightweight library implementing the most extended [cryptographic hash function](http://en.wikipedia.org/wiki/Cryptographic_hash_function) algorithms in pure JavaScript (ES5 compliant). 4 | 5 | The goal is to provide an dependency-free, fast and reliable solution for hash algorithms for both client-side and server-side JavaScript environments. 6 | The code is fully compatible with the ECMAScript 5 specification and is used in production in browsers and [node.js](http://nodejs.org)/[io.js](http://iojs.org) 7 | 8 | If you are looking for a low-level performance library for the server-side, note that node.js/io.js provides its own native module: [`crypto`](http://nodejs.org/api/crypto.html) 9 | 10 | ## Supported hash algorithms 11 | 12 | * `MD5` () 13 | * `SHA1` () 14 | * `SHA256` () 15 | * `SHA512` () 16 | * `HMAC` () 17 | * `RIPEMD-160` () 18 | 19 | **Additional functionalities** 20 | 21 | * `Base64 encoding/decoding` () 22 | * `CRC-32 calculation` 23 | * `UTF-8 encoding/decoding` 24 | 25 | ## Environments 26 | 27 | - Browsers (ES3) 28 | - node.js/io.js (all versions) 29 | - Rhino 30 | - RingoJS 31 | 32 | ## Usage 33 | 34 | Each algorithm has its respective own instantiable `object`. Here you can see an example of how to create a new instance for each one: 35 | 36 | ```javascript 37 | // new MD5 instance 38 | var MD5 = new Hashes.MD5 39 | // new SHA1 instance 40 | var SHA1 = new Hashes.SHA1 41 | // new SHA256 instance 42 | var SHA256 = new Hashes.SHA256 43 | // new SHA512 instace 44 | var SHA512 = new Hashes.SHA512 45 | // new RIPEMD-160 instace 46 | var RMD160 = new Hashes.RMD160 47 | ``` 48 | 49 | An example of how to generate an hexadecimal-based hash encoding for each algorithm: 50 | 51 | ```javascript 52 | // sample string 53 | var str = 'Sample text!' 54 | // output to console 55 | console.log('MD5: ' + MD5.hex(str)) 56 | console.log('SHA1: ' + SHA1.hex(str)) 57 | console.log('SHA256: ' + SHA256.hex(str)) 58 | console.log('SHA512: ' + SHA512.hex(str)) 59 | console.log('RIPEMD-160: ' + RMD160.hex(str)) 60 | ``` 61 | 62 | ### Browsers 63 | 64 | This is a simple implementation for a client-side environment: 65 | 66 | ```html 67 | 68 | 69 | 70 | 78 | 79 | 80 | 81 | 82 | ``` 83 | 84 | ### node.js / io.js 85 | 86 | ```javascript 87 | // require the module 88 | var Hashes = require('jshashes') 89 | // sample string 90 | var str = 'This is a sample text!' 91 | // new SHA1 instance and base64 string encoding 92 | var SHA1 = new Hashes.SHA1().b64(str) 93 | // output to console 94 | console.log('SHA1: ' + SHA1) 95 | ``` 96 | 97 | ### Command-line interface 98 | 99 | You can use the simple command-line interface to generate hashes. 100 | 101 | ```bash 102 | $ hashes sha1-hex This is a sample string 103 | > b6a8501d8a70e74e1dc12a6082102622fdc719bb 104 | 105 | # or with quotes 106 | $ hashes sha1-hex "This is a sample string" 107 | > b6a8501d8a70e74e1dc12a6082102622fdc719bb 108 | ``` 109 | 110 | For more information about the options supported, type: 111 | 112 | ```bash 113 | $ hashes -h 114 | ``` 115 | 116 | ### Installation 117 | 118 | Via [npm](https://npmjs.org) 119 | 120 | ``` 121 | $ npm install jshashes 122 | ``` 123 | 124 | Via [Bower](http://bower.io/): 125 | ``` 126 | $ bower install jshashes 127 | ``` 128 | 129 | Via [Component](https://github.com/component/component): 130 | ``` 131 | $ component install h2non/jshashes 132 | ``` 133 | 134 | Or loading the script directly: 135 | ``` 136 | http://cdn.rawgit.com/h2non/jsHashes/master/hashes.js 137 | ``` 138 | 139 | ## Public methods 140 | 141 | Each algorithm `class` provides the following public methods: 142 | 143 | * `hex(string)` - Hexadecimal hash encoding from string. 144 | * `b64(string)` - Base64 hash encoding from string. 145 | * `any(string,encoding)` - Custom hash algorithm values encoding. 146 | * `hex_hmac(key,string)` - Hexadecimal hash with HMAC salt key. 147 | * `b64_hmac(key,string)` - Base64 hash with HMAC salt key. 148 | * `any_hmac(key,string,encoding)` - Custom hash values encoding with HMAC salt key support. 149 | * `vm_test()` - Simple self-test to see is working. Returns `this` Object. 150 | * `setUpperCase(boolean)` - Enable/disable uppercase hexadecimal returned string. Returns `this` Object. 151 | * `setPad(string)` - Defines a custom base64 pad string. Default is '=' according with the RFC standard. Returns `this` Object. 152 | * `setUTF8(boolean)` - Enable/disable UTF-8 character encoding. Returns `this` Object. 153 | 154 | ## Hash encoding formats supported 155 | 156 | * Hexadecimal (most extended) 157 | * Base64 158 | * Custom hash values `any()` method 159 | 160 | ## Benchmark 161 | 162 | Node.js 0.6.18 running on a VPS Intel I7 930 with 512 MB of RAM (see `server/benchmark.js`) 163 | 164 | ```javascript 165 | Simple benchmark test generating 10000 hashes for each algorithm. 166 | String: "A0gTtNtKh3RaduBfIo59ZdfTc5pTdOQrkxdZ5EeVOIZh1cXxqPyexKZBg6VlE1KzIz6pd6r1LLIpT5B8THRfcGvbJElwhWBi9ZAE" 167 | 168 | * MD5 169 | ** Done in: 205 milliseconds 170 | * SHA1 171 | ** Done in: 277 milliseconds 172 | * SHA256 173 | ** Done in: 525 milliseconds 174 | * SHA512 175 | ** Done in: 593 milliseconds 176 | * RMD160 177 | ** Done in: 383 milliseconds 178 | ``` 179 | 180 | See `client/benchmark.html` for client-side. 181 | 182 | ## Notes 183 | 184 | * Don't support checksum hash for files on the server-side, only strings-based inputs are supported. 185 | * It has not been planned to include support for more hash algorithms. 186 | * The goal is to provide the same JavaScript code in both server and client side, so it isn't planned to improve it in other ways. 187 | * Only Node.js server-side was tested, so with minimal changes, you can setup `jsHashes` in other server-side JS environment. 188 | 189 | ## Changelog 190 | 191 | * `1.0.7` 192 | - Merge #37: fix terminator statement token. 193 | * `1.0.6` 194 | - Fix #34: options `pad` typo. 195 | * `1.0.4` 196 | - Fix CLI script call error when use it from Bash 197 | - Added CLI usage example 198 | * `1.0.3` 199 | - Important bugfixes to UTF-8 encoding (broken in 1.0.2) and the RIPEMD-160 hash (broken in 1.0.1). (gh #6) 200 | - New test suite for hashes, CRC32, and hmac; run with 'npm test' in node. 201 | - Fixed global variable leaks. (gh #13) 202 | - CRC32 will now always return positive values. (gh #11) 203 | - Added package version property to the exposed Hashes Object 204 | - Updated CLI script utility supporting all algorithms (see bin/hashes) 205 | - Fixed UTF-8 encoding/decoding error (if input parameter is undefined or invalid) 206 | * `1.0.2` 207 | - Performance improvements and minimal refactor (length property caching, literal notation) 208 | - Available from Bower package manager 209 | * `1.0.1` 210 | - Refactoring (hoisting, coercion, removed redundant functions, scoping, restructure...) 211 | - Performance improves 212 | - JSLint validation (except bitwise operators) 213 | - Now the library can be used like a AMD CommonJS module 214 | - Updated documentation 215 | - New folders structure 216 | - Added closure compiled and minimized library version 217 | - Available from Jam package manager 218 | * `0.1.5b` 219 | - Added index.js for easy call the module in Node.js 220 | - Updated documentation 221 | * `0.1.4b` 222 | - Now declaring objects using Literal Notation. 223 | - Solved syntax errors on minimized version (jshashes.min.js) 224 | - Added benchmark test and sample 225 | * `0.1.3b` 226 | - Starting non-redundancy code refactorization 227 | - Added `Helpers` Object with some global functions 228 | - Added native support for Base64 provided as `class` 229 | - Added CRC-32 calculation support 230 | - Added URL encode/decode helpers functions 231 | * `0.1.2b` 232 | - SHA1 error fixed. 233 | - General code changes (renaming classes, private methods, new methods...). 234 | - Changing library namespace to 'Hashes'. 235 | - Starting code documentation. 236 | - Added new examples of how to use. 237 | * `0.1.1b` 238 | - Minimal library improvements. 239 | - There has been added some samples, like how to use it and support for NPM package. 240 | * `0.1.0b` 241 | - First release: the code is stable, but the library is still beta and must be improved and documented. 242 | 243 | ## TODO 244 | 245 | * Performance benchmarking 246 | 247 | ## Authors 248 | 249 | ### Library author 250 | 251 | * [Tomas Aparicio](https://github.com/h2non/) 252 | 253 | ### Original algorithm authors 254 | 255 | * [Paul Johnston](http://pajhome.org.uk/crypt/md5/) 256 | * Angel Marin (SHA256) 257 | * Jeremy Lin (RIPEMD-160) 258 | 259 | ### Other contributors 260 | 261 | * [C. Scott Ananian](https://github.com/cscott) 262 | * Greg Holt 263 | * Andrew Kepert 264 | * Ydnar 265 | * Lostinet 266 | 267 | ## License 268 | 269 | jsHashes is released under `New BSD` license. See `LICENSE` file. 270 | 271 | ## Issues 272 | 273 | Feel free to report any issue you experiment via Github . 274 | -------------------------------------------------------------------------------- /bin/hashes: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var Hashes = require('../hashes'), 4 | version = require('../package.json').version; 5 | 6 | var args = process.argv, 7 | command = args[0], 8 | usage, options; 9 | 10 | usage = [ 11 | ' jshashes ' + version 12 | , ' ' 13 | , ' Usage:' 14 | , ' hashes [option] [string]' 15 | , ' ' 16 | , ' Options:' 17 | , ' md5-hex' 18 | , ' md5-b64' 19 | , ' sha1-hex' 20 | , ' sha1-b64' 21 | , ' sha256-hex' 22 | , ' sha256-b64' 23 | , ' sha512-hex' 24 | , ' sha512-b64' 25 | , ' rmd160-hex' 26 | , ' rmd160-b64' 27 | , ' b64-enc' 28 | , ' b64-dec' 29 | , ' crc32' 30 | , ' ' 31 | , ' Help:' 32 | , ' -h , --help, help' 33 | , ' ' 34 | , ' Current version:' 35 | , ' -v , --version, version' 36 | , ' ' 37 | , ' Examples:' 38 | , ' $ hashes sha1-hex "sample text!"' 39 | , ' ' 40 | ].join('\n'); 41 | 42 | options = [ 43 | 'md5-hex' 44 | ,'md5-b64' 45 | ,'sha1-hex' 46 | ,'sha1-b64' 47 | ,'sha256-hex' 48 | ,'sha256-b64' 49 | ,'sha512-hex' 50 | ,'sha512-b64' 51 | ,'rmd160-hex' 52 | ,'rmd160-b64' 53 | ,'b64-enc' 54 | ,'b64-dec' 55 | ,'crc32' 56 | ]; 57 | 58 | function die (str) { 59 | console.log(str); 60 | process.exit(); 61 | } 62 | 63 | function procesAlgorithm() { 64 | var algorithm = args[0].split('-')[0].toUpperCase(), 65 | encoding = args[0].split('-')[1], 66 | string = args.slice(1).join(' '), 67 | instance, output; 68 | 69 | if (algorithm === 'B64') { 70 | algorithm = 'Base64'; 71 | encoding = encoding === 'dec' ? 'decode' : 'encode'; 72 | } 73 | 74 | if (Hashes.hasOwnProperty(algorithm)) { 75 | if (algorithm === 'CRC32') { 76 | output = Hashes[algorithm](string); 77 | } else { 78 | instance = new Hashes[algorithm]; 79 | if (instance.hasOwnProperty(encoding)) { 80 | output = instance[encoding](string); 81 | } 82 | } 83 | } else { 84 | output = 'Algorithm not supported. Type help to see the list of available options.' 85 | } 86 | return output; 87 | } 88 | 89 | if (command && command.indexOf('node') !== -1) { 90 | args = args.slice(2); 91 | command = args[0]; 92 | } 93 | 94 | if (command === '-v' || command === '--version' || command === 'version') { 95 | die(version); 96 | } 97 | if (command === '-h' || command === '--help' || command === 'help' || args.length < 2 || options.indexOf(command) === -1) { 98 | die(usage); 99 | } 100 | 101 | die(procesAlgorithm()); 102 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jshashes", 3 | "version": "1.0.8", 4 | "description": "A fast and independent hashing library pure JavaScript implemented (ES3 compliant) for both server and client side (MD5, SHA1, SHA256, SHA512, RIPEMD, HMAC and Base64)", 5 | "keywords": ["hash", "md5", "sha1", "sha256", "hashes", "sha512", "RIPEMD", "base64", "hmac", "crc", "encoding", "algorithm"], 6 | "author": "Tomas Aparicio ", 7 | "main": "hashes.js", 8 | "ignore": [ 9 | "**/.*", 10 | "bin", 11 | "test", 12 | "examples/server", 13 | "package.json", 14 | "Makefile", 15 | "node_modules" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jshashes", 3 | "main": "hashes.js", 4 | "version": "1.0.8", 5 | "scripts": [ 6 | "hashes.js", 7 | "hashes.min.js" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /examples/client/base64.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jsHashes - Base64 enconding hash example 6 | 7 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /examples/client/benchmark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jsHashes - Benchmark example 6 | 7 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /examples/client/custom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jsHashes - Custom values enconding example 6 | 7 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /examples/client/hexadecimal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jsHashes - Hexadecimal Hash example 6 | 7 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /examples/client/hmac.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jsHashes - HMAC salt key enconding example 6 | 7 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /examples/client/others.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jsHashes - Base64, CRC-32 and URL enconding example 6 | 7 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/client/uppercase.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jsHashes - Hexadecimal Uppercase example 6 | 7 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /examples/server/base64.js: -------------------------------------------------------------------------------- 1 | var Hashes = require('../../hashes'); 2 | 3 | // sample string 4 | var str = 'This is a sample text!'; 5 | 6 | // new MD5 instance 7 | var MD5 = new Hashes.MD5; 8 | // new SHA1 instance 9 | var SHA1 = new Hashes.SHA1; 10 | // new SHA256 instance 11 | var SHA256 = new Hashes.SHA256; 12 | // new SHA512 instace 13 | var SHA512 = new Hashes.SHA512; 14 | // new RIPEMD160 instace 15 | var RMD160 = new Hashes.RMD160; 16 | 17 | console.log('jsHashes\nBase64 encoding hash example...\n'); 18 | 19 | console.log('MD5 -> ' + MD5.b64(str)); 20 | console.log('SHA1 -> ' + SHA1.b64(str)); 21 | console.log('SHA256 -> ' + SHA256.b64(str)); 22 | console.log('SHA512 -> ' + SHA512.b64(str)); 23 | console.log('RIPEMD160 -> ' + RMD160.b64(str)); 24 | -------------------------------------------------------------------------------- /examples/server/benchmark.js: -------------------------------------------------------------------------------- 1 | var Hashes = require('../../hashes'); 2 | 3 | function randomString(string_length) { 4 | var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; 5 | string_length = string_length || 50; 6 | var randomstring = ''; 7 | for (var i=0; i ' + MD5.any(str,custom)); 23 | console.log('SHA1 -> ' + SHA1.any(str,custom)); 24 | console.log('SHA256 -> ' + SHA256.any(str,custom)); 25 | console.log('SHA512 -> ' + SHA512.any(str,custom)); 26 | console.log('RIPEMD160 -> ' + RMD160.any(str,custom)); 27 | -------------------------------------------------------------------------------- /examples/server/hexadecimal.js: -------------------------------------------------------------------------------- 1 | var Hashes = require('../../hashes'); 2 | 3 | // sample string 4 | var str = 'This is a sample text'; 5 | 6 | // new MD5 instance 7 | var MD5 = new Hashes.MD5; 8 | // new SHA1 instance 9 | var SHA1 = new Hashes.SHA1; 10 | // new SHA256 instance 11 | var SHA256 = new Hashes.SHA256; 12 | // new SHA512 instace 13 | var SHA512 = new Hashes.SHA512; 14 | // new RIPEMD160 instace 15 | var RMD160 = new Hashes.RMD160; 16 | 17 | console.log('jsHashes\nHexadecimal encoding hashes example...\n'); 18 | 19 | console.log('MD5 -> ' + MD5.hex(str)); 20 | console.log('SHA1 -> ' + SHA1.hex(str)); 21 | console.log('SHA256 -> ' + SHA256.hex(str)); 22 | console.log('SHA512 -> ' + SHA512.hex(str)); 23 | console.log('RIPEMD160 -> ' + RMD160.hex(str)); 24 | -------------------------------------------------------------------------------- /examples/server/hmac.js: -------------------------------------------------------------------------------- 1 | var Hashes = require('../../hashes'); 2 | 3 | // sample string 4 | var str = 'This is a sample text!'; 5 | 6 | // new MD5 instance 7 | var MD5 = new Hashes.MD5; 8 | // new SHA1 instance 9 | var SHA1 = new Hashes.SHA1; 10 | // new SHA256 instance 11 | var SHA256 = new Hashes.SHA256; 12 | // new SHA512 instace 13 | var SHA512 = new Hashes.SHA512; 14 | // new RIPEMD160 instace 15 | var RMD160 = new Hashes.RMD160; 16 | 17 | console.log('jsHashes\nHashes example with HMAC salt key encoding...\n'); 18 | 19 | // HMAC salt key 20 | var key = 'th!$-!S-@-k3Y'; 21 | 22 | // hexadecimal 23 | console.log('Hexadecimal:'); 24 | console.log('MD5 -> ' + MD5.hex_hmac(str,key)); 25 | console.log('SHA1 -> ' + SHA1.hex_hmac(str,key)); 26 | console.log('SHA256 -> ' + SHA256.hex_hmac(str,key)); 27 | console.log('SHA512 -> ' + SHA512.hex_hmac(str,key)); 28 | console.log('RIPEMD160 -> ' + RMD160.hex_hmac(str,key)); 29 | 30 | // base64 31 | console.log('\nBase64:'); 32 | console.log('MD5 -> ' + MD5.b64_hmac(str,key)); 33 | console.log('SHA1 -> ' + SHA1.b64_hmac(str,key)); 34 | console.log('SHA256 -> ' + SHA256.b64_hmac(str,key)); 35 | console.log('SHA512 -> ' + SHA512.b64_hmac(str,key)); 36 | console.log('RIPEMD160 -> ' + RMD160.b64_hmac(str,key)); 37 | 38 | // custom encoding values 39 | 40 | var custom = 'abc123'; 41 | 42 | console.log('\nCustom encoding values:'); 43 | console.log('MD5 -> ' + MD5.any_hmac(str,key,custom)); 44 | console.log('SHA1 -> ' + SHA1.any_hmac(str,key,custom)); 45 | console.log('SHA256 -> ' + SHA256.any_hmac(str,key,custom)); 46 | console.log('SHA512 -> ' + SHA512.any_hmac(str,key,custom)); 47 | console.log('RIPEMD160 -> ' + RMD160.any_hmac(str,key,custom)); 48 | -------------------------------------------------------------------------------- /examples/server/uppercase.js: -------------------------------------------------------------------------------- 1 | var Hashes = require('../../hashes'); 2 | 3 | // sample string 4 | var str = 'This is a sample text!'; 5 | 6 | // new MD5 instance 7 | var MD5 = new Hashes.MD5; 8 | // new SHA1 instance 9 | var SHA1 = new Hashes.SHA1; 10 | // new SHA256 instance 11 | var SHA256 = new Hashes.SHA256; 12 | // new SHA512 instace 13 | var SHA512 = new Hashes.SHA512; 14 | // new RIPEMD160 instace 15 | var RMD160 = new Hashes.RMD160; 16 | 17 | console.log('jsHashes\nHexadecimal uppercase encoding hashes example...\n'); 18 | 19 | console.log('\nLowercase encoding (default):'); 20 | console.log('MD5 -> ' + MD5.hex(str)); 21 | console.log('SHA1 -> ' + SHA1.hex(str)); 22 | console.log('SHA256 -> ' + SHA256.hex(str)); 23 | console.log('SHA512 -> ' + SHA512.hex(str)); 24 | console.log('RIPEMD160 -> ' + RMD160.hex(str)); 25 | 26 | // set uppercase via setUpperCase() method 27 | console.log('\n\nUppercase (calling setUpperCase() method):'); 28 | MD5.setUpperCase(true); 29 | console.log('MD5 -> ' + MD5.hex(str)); 30 | SHA1.setUpperCase(true); 31 | console.log('SHA1 -> ' + SHA1.hex(str)); 32 | SHA256.setUpperCase(true); 33 | console.log('SHA256 -> ' + SHA256.hex(str)); 34 | SHA512.setUpperCase(true); 35 | console.log('SHA512 -> ' + SHA512.hex(str)); 36 | RMD160.setUpperCase(true); 37 | console.log('RIPEMD-160 -> ' + RMD160.hex(str)); -------------------------------------------------------------------------------- /hashes.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'jshashes' { 2 | class HashesClass { 3 | /** 4 | * Hexadecimal hash encoding from string. 5 | */ 6 | hex(input: string): string; 7 | 8 | /** 9 | * Base64 hash encoding from string. 10 | */ 11 | b64(input: string): string; 12 | 13 | /** 14 | * Custom hash algorithm values encoding. 15 | */ 16 | any(input: string, encoding: string): string; 17 | 18 | /** 19 | * Hexadecimal hash with HMAC salt key. 20 | */ 21 | hex_hmac(key: string, input: string): string; 22 | 23 | /** 24 | * Custom hash values encoding with HMAC salt key support. 25 | */ 26 | b64_hmac(key: string, input: string): string; 27 | 28 | /** 29 | * Custom hash values encoding with HMAC salt key support. 30 | */ 31 | any_hmac(key: string, input: string, encoding: string): string; 32 | 33 | /** 34 | * Simple self-test to see if working. 35 | */ 36 | vm_test(): this; 37 | 38 | /** 39 | * Enable/disable uppercase hexadecimal returned string. 40 | */ 41 | setUpperCase(isEnabled: boolean): this; 42 | 43 | /** 44 | * Defines a custom base64 pad string. Default is '=' according with the RFC standard. 45 | */ 46 | setPad(pad: string): this; 47 | 48 | /** 49 | * Enable/disable UTF-8 character encoding. 50 | */ 51 | setUTF8(isEnabled: boolean): this; 52 | } 53 | 54 | namespace Hashes { 55 | export class MD5 extends HashesClass { } 56 | export class SHA1 extends HashesClass { } 57 | export class SHA256 extends HashesClass { } 58 | export class SHA512 extends HashesClass { } 59 | export class RMD160 extends HashesClass { } 60 | } 61 | 62 | export = Hashes; 63 | } 64 | -------------------------------------------------------------------------------- /hashes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jshashes - https://github.com/h2non/jshashes 3 | * Released under the "New BSD" license 4 | * 5 | * Algorithms specification: 6 | * 7 | * MD5 - http://www.ietf.org/rfc/rfc1321.txt 8 | * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html 9 | * SHA1 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf 10 | * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf 11 | * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf 12 | * HMAC - http://www.ietf.org/rfc/rfc2104.txt 13 | */ 14 | (function() { 15 | var Hashes; 16 | 17 | function utf8Encode(str) { 18 | var x, y, output = '', 19 | i = -1, 20 | l; 21 | 22 | if (str && str.length) { 23 | l = str.length; 24 | while ((i += 1) < l) { 25 | /* Decode utf-16 surrogate pairs */ 26 | x = str.charCodeAt(i); 27 | y = i + 1 < l ? str.charCodeAt(i + 1) : 0; 28 | if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) { 29 | x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); 30 | i += 1; 31 | } 32 | /* Encode output as utf-8 */ 33 | if (x <= 0x7F) { 34 | output += String.fromCharCode(x); 35 | } else if (x <= 0x7FF) { 36 | output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), 37 | 0x80 | (x & 0x3F)); 38 | } else if (x <= 0xFFFF) { 39 | output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 40 | 0x80 | ((x >>> 6) & 0x3F), 41 | 0x80 | (x & 0x3F)); 42 | } else if (x <= 0x1FFFFF) { 43 | output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 44 | 0x80 | ((x >>> 12) & 0x3F), 45 | 0x80 | ((x >>> 6) & 0x3F), 46 | 0x80 | (x & 0x3F)); 47 | } 48 | } 49 | } 50 | return output; 51 | } 52 | 53 | function utf8Decode(str) { 54 | var i, ac, c1, c2, c3, arr = [], 55 | l; 56 | i = ac = c1 = c2 = c3 = 0; 57 | 58 | if (str && str.length) { 59 | l = str.length; 60 | str += ''; 61 | 62 | while (i < l) { 63 | c1 = str.charCodeAt(i); 64 | ac += 1; 65 | if (c1 < 128) { 66 | arr[ac] = String.fromCharCode(c1); 67 | i += 1; 68 | } else if (c1 > 191 && c1 < 224) { 69 | c2 = str.charCodeAt(i + 1); 70 | arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)); 71 | i += 2; 72 | } else { 73 | c2 = str.charCodeAt(i + 1); 74 | c3 = str.charCodeAt(i + 2); 75 | arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 76 | i += 3; 77 | } 78 | } 79 | } 80 | return arr.join(''); 81 | } 82 | 83 | /** 84 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 85 | * to work around bugs in some JS interpreters. 86 | */ 87 | 88 | function safe_add(x, y) { 89 | var lsw = (x & 0xFFFF) + (y & 0xFFFF), 90 | msw = (x >> 16) + (y >> 16) + (lsw >> 16); 91 | return (msw << 16) | (lsw & 0xFFFF); 92 | } 93 | 94 | /** 95 | * Bitwise rotate a 32-bit number to the left. 96 | */ 97 | 98 | function bit_rol(num, cnt) { 99 | return (num << cnt) | (num >>> (32 - cnt)); 100 | } 101 | 102 | /** 103 | * Convert a raw string to a hex string 104 | */ 105 | 106 | function rstr2hex(input, hexcase) { 107 | var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef', 108 | output = '', 109 | x, i = 0, 110 | l = input.length; 111 | for (; i < l; i += 1) { 112 | x = input.charCodeAt(i); 113 | output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F); 114 | } 115 | return output; 116 | } 117 | 118 | /** 119 | * Encode a string as utf-16 120 | */ 121 | 122 | function str2rstr_utf16le(input) { 123 | var i, l = input.length, 124 | output = ''; 125 | for (i = 0; i < l; i += 1) { 126 | output += String.fromCharCode(input.charCodeAt(i) & 0xFF, (input.charCodeAt(i) >>> 8) & 0xFF); 127 | } 128 | return output; 129 | } 130 | 131 | function str2rstr_utf16be(input) { 132 | var i, l = input.length, 133 | output = ''; 134 | for (i = 0; i < l; i += 1) { 135 | output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, input.charCodeAt(i) & 0xFF); 136 | } 137 | return output; 138 | } 139 | 140 | /** 141 | * Convert an array of big-endian words to a string 142 | */ 143 | 144 | function binb2rstr(input) { 145 | var i, l = input.length * 32, 146 | output = ''; 147 | for (i = 0; i < l; i += 8) { 148 | output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF); 149 | } 150 | return output; 151 | } 152 | 153 | /** 154 | * Convert an array of little-endian words to a string 155 | */ 156 | 157 | function binl2rstr(input) { 158 | var i, l = input.length * 32, 159 | output = ''; 160 | for (i = 0; i < l; i += 8) { 161 | output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); 162 | } 163 | return output; 164 | } 165 | 166 | /** 167 | * Convert a raw string to an array of little-endian words 168 | * Characters >255 have their high-byte silently ignored. 169 | */ 170 | 171 | function rstr2binl(input) { 172 | var i, l = input.length * 8, 173 | output = Array(input.length >> 2), 174 | lo = output.length; 175 | for (i = 0; i < lo; i += 1) { 176 | output[i] = 0; 177 | } 178 | for (i = 0; i < l; i += 8) { 179 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32); 180 | } 181 | return output; 182 | } 183 | 184 | /** 185 | * Convert a raw string to an array of big-endian words 186 | * Characters >255 have their high-byte silently ignored. 187 | */ 188 | 189 | function rstr2binb(input) { 190 | var i, l = input.length * 8, 191 | output = Array(input.length >> 2), 192 | lo = output.length; 193 | for (i = 0; i < lo; i += 1) { 194 | output[i] = 0; 195 | } 196 | for (i = 0; i < l; i += 8) { 197 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); 198 | } 199 | return output; 200 | } 201 | 202 | /** 203 | * Convert a raw string to an arbitrary string encoding 204 | */ 205 | 206 | function rstr2any(input, encoding) { 207 | var divisor = encoding.length, 208 | remainders = Array(), 209 | i, q, x, ld, quotient, dividend, output, full_length; 210 | 211 | /* Convert to an array of 16-bit big-endian values, forming the dividend */ 212 | dividend = Array(Math.ceil(input.length / 2)); 213 | ld = dividend.length; 214 | for (i = 0; i < ld; i += 1) { 215 | dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); 216 | } 217 | 218 | /** 219 | * Repeatedly perform a long division. The binary array forms the dividend, 220 | * the length of the encoding is the divisor. Once computed, the quotient 221 | * forms the dividend for the next step. We stop when the dividend is zerHashes. 222 | * All remainders are stored for later use. 223 | */ 224 | while (dividend.length > 0) { 225 | quotient = Array(); 226 | x = 0; 227 | for (i = 0; i < dividend.length; i += 1) { 228 | x = (x << 16) + dividend[i]; 229 | q = Math.floor(x / divisor); 230 | x -= q * divisor; 231 | if (quotient.length > 0 || q > 0) { 232 | quotient[quotient.length] = q; 233 | } 234 | } 235 | remainders[remainders.length] = x; 236 | dividend = quotient; 237 | } 238 | 239 | /* Convert the remainders to the output string */ 240 | output = ''; 241 | for (i = remainders.length - 1; i >= 0; i--) { 242 | output += encoding.charAt(remainders[i]); 243 | } 244 | 245 | /* Append leading zero equivalents */ 246 | full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))); 247 | for (i = output.length; i < full_length; i += 1) { 248 | output = encoding[0] + output; 249 | } 250 | return output; 251 | } 252 | 253 | /** 254 | * Convert a raw string to a base-64 string 255 | */ 256 | 257 | function rstr2b64(input, b64pad) { 258 | var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', 259 | output = '', 260 | len = input.length, 261 | i, j, triplet; 262 | b64pad = b64pad || '='; 263 | for (i = 0; i < len; i += 3) { 264 | triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0); 265 | for (j = 0; j < 4; j += 1) { 266 | if (i * 8 + j * 6 > input.length * 8) { 267 | output += b64pad; 268 | } else { 269 | output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F); 270 | } 271 | } 272 | } 273 | return output; 274 | } 275 | 276 | Hashes = { 277 | /** 278 | * @property {String} version 279 | * @readonly 280 | */ 281 | VERSION: '1.0.6', 282 | /** 283 | * @member Hashes 284 | * @class Base64 285 | * @constructor 286 | */ 287 | Base64: function() { 288 | // private properties 289 | var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', 290 | pad = '=', // default pad according with the RFC standard 291 | url = false, // URL encoding support @todo 292 | utf8 = true; // by default enable UTF-8 support encoding 293 | 294 | // public method for encoding 295 | this.encode = function(input) { 296 | var i, j, triplet, 297 | output = ''; 298 | 299 | pad = pad || '='; 300 | input = (utf8) ? utf8Encode(input) : input; 301 | len = input.length; 302 | 303 | for (i = 0; i < len; i += 3) { 304 | triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0); 305 | for (j = 0; j < 4; j += 1) { 306 | if (i * 8 + j * 6 > len * 8) { 307 | output += pad; 308 | } else { 309 | output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F); 310 | } 311 | } 312 | } 313 | return output; 314 | }; 315 | 316 | // public method for decoding 317 | this.decode = function(input) { 318 | // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 319 | var i, o1, o2, o3, h1, h2, h3, h4, bits, ac, 320 | dec = '', 321 | arr = []; 322 | if (!input) { 323 | return input; 324 | } 325 | 326 | i = ac = 0; 327 | input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '=' 328 | //input += ''; 329 | 330 | do { // unpack four hexets into three octets using index points in b64 331 | h1 = tab.indexOf(input.charAt(i++)); 332 | h2 = tab.indexOf(input.charAt(i++)); 333 | h3 = tab.indexOf(input.charAt(i++)); 334 | h4 = tab.indexOf(input.charAt(i++)); 335 | 336 | bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; 337 | 338 | o1 = bits >> 16 & 0xff; 339 | o2 = bits >> 8 & 0xff; 340 | o3 = bits & 0xff; 341 | ac += 1; 342 | 343 | if (h3 === 64) { 344 | arr[ac] = String.fromCharCode(o1); 345 | } else if (h4 === 64) { 346 | arr[ac] = String.fromCharCode(o1, o2); 347 | } else { 348 | arr[ac] = String.fromCharCode(o1, o2, o3); 349 | } 350 | } while (i < input.length); 351 | 352 | dec = arr.join(''); 353 | dec = (utf8) ? utf8Decode(dec) : dec; 354 | 355 | return dec; 356 | }; 357 | 358 | // set custom pad string 359 | this.setPad = function(str) { 360 | pad = str || pad; 361 | return this; 362 | }; 363 | // set custom tab string characters 364 | this.setTab = function(str) { 365 | tab = str || tab; 366 | return this; 367 | }; 368 | this.setUTF8 = function(bool) { 369 | if (typeof bool === 'boolean') { 370 | utf8 = bool; 371 | } 372 | return this; 373 | }; 374 | }, 375 | 376 | /** 377 | * CRC-32 calculation 378 | * @member Hashes 379 | * @method CRC32 380 | * @static 381 | * @param {String} str Input String 382 | * @return {String} 383 | */ 384 | CRC32: function(str) { 385 | var crc = 0, 386 | x = 0, 387 | y = 0, 388 | table, i, iTop; 389 | str = utf8Encode(str); 390 | 391 | table = [ 392 | '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ', 393 | '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ', 394 | '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ', 395 | '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ', 396 | 'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ', 397 | '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ', 398 | 'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ', 399 | '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ', 400 | 'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ', 401 | '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ', 402 | 'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ', 403 | '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ', 404 | 'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ', 405 | '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ', 406 | '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ', 407 | '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ', 408 | '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ', 409 | 'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ', 410 | '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ', 411 | 'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ', 412 | '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ', 413 | 'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ', 414 | '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ', 415 | 'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ', 416 | '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ', 417 | 'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D' 418 | ].join(''); 419 | 420 | crc = crc ^ (-1); 421 | for (i = 0, iTop = str.length; i < iTop; i += 1) { 422 | y = (crc ^ str.charCodeAt(i)) & 0xFF; 423 | x = '0x' + table.substr(y * 9, 8); 424 | crc = (crc >>> 8) ^ x; 425 | } 426 | // always return a positive number (that's what >>> 0 does) 427 | return (crc ^ (-1)) >>> 0; 428 | }, 429 | /** 430 | * @member Hashes 431 | * @class MD5 432 | * @constructor 433 | * @param {Object} [config] 434 | * 435 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message 436 | * Digest Algorithm, as defined in RFC 1321. 437 | * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 438 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 439 | * See for more infHashes. 440 | */ 441 | MD5: function(options) { 442 | /** 443 | * Private config properties. You may need to tweak these to be compatible with 444 | * the server-side, but the defaults work in most cases. 445 | * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase} 446 | */ 447 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase 448 | b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance 449 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding 450 | 451 | // privileged (public) methods 452 | this.hex = function(s) { 453 | return rstr2hex(rstr(s, utf8), hexcase); 454 | }; 455 | this.b64 = function(s) { 456 | return rstr2b64(rstr(s), b64pad); 457 | }; 458 | this.any = function(s, e) { 459 | return rstr2any(rstr(s, utf8), e); 460 | }; 461 | this.raw = function(s) { 462 | return rstr(s, utf8); 463 | }; 464 | this.hex_hmac = function(k, d) { 465 | return rstr2hex(rstr_hmac(k, d), hexcase); 466 | }; 467 | this.b64_hmac = function(k, d) { 468 | return rstr2b64(rstr_hmac(k, d), b64pad); 469 | }; 470 | this.any_hmac = function(k, d, e) { 471 | return rstr2any(rstr_hmac(k, d), e); 472 | }; 473 | /** 474 | * Perform a simple self-test to see if the VM is working 475 | * @return {String} Hexadecimal hash sample 476 | */ 477 | this.vm_test = function() { 478 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; 479 | }; 480 | /** 481 | * Enable/disable uppercase hexadecimal returned string 482 | * @param {Boolean} 483 | * @return {Object} this 484 | */ 485 | this.setUpperCase = function(a) { 486 | if (typeof a === 'boolean') { 487 | hexcase = a; 488 | } 489 | return this; 490 | }; 491 | /** 492 | * Defines a base64 pad string 493 | * @param {String} Pad 494 | * @return {Object} this 495 | */ 496 | this.setPad = function(a) { 497 | b64pad = a || b64pad; 498 | return this; 499 | }; 500 | /** 501 | * Defines a base64 pad string 502 | * @param {Boolean} 503 | * @return {Object} [this] 504 | */ 505 | this.setUTF8 = function(a) { 506 | if (typeof a === 'boolean') { 507 | utf8 = a; 508 | } 509 | return this; 510 | }; 511 | 512 | // private methods 513 | 514 | /** 515 | * Calculate the MD5 of a raw string 516 | */ 517 | 518 | function rstr(s) { 519 | s = (utf8) ? utf8Encode(s) : s; 520 | return binl2rstr(binl(rstr2binl(s), s.length * 8)); 521 | } 522 | 523 | /** 524 | * Calculate the HMAC-MD5, of a key and some data (raw strings) 525 | */ 526 | 527 | function rstr_hmac(key, data) { 528 | var bkey, ipad, opad, hash, i; 529 | 530 | key = (utf8) ? utf8Encode(key) : key; 531 | data = (utf8) ? utf8Encode(data) : data; 532 | bkey = rstr2binl(key); 533 | if (bkey.length > 16) { 534 | bkey = binl(bkey, key.length * 8); 535 | } 536 | 537 | ipad = Array(16), opad = Array(16); 538 | for (i = 0; i < 16; i += 1) { 539 | ipad[i] = bkey[i] ^ 0x36363636; 540 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 541 | } 542 | hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8); 543 | return binl2rstr(binl(opad.concat(hash), 512 + 128)); 544 | } 545 | 546 | /** 547 | * Calculate the MD5 of an array of little-endian words, and a bit length. 548 | */ 549 | 550 | function binl(x, len) { 551 | var i, olda, oldb, oldc, oldd, 552 | a = 1732584193, 553 | b = -271733879, 554 | c = -1732584194, 555 | d = 271733878; 556 | 557 | /* append padding */ 558 | x[len >> 5] |= 0x80 << ((len) % 32); 559 | x[(((len + 64) >>> 9) << 4) + 14] = len; 560 | 561 | for (i = 0; i < x.length; i += 16) { 562 | olda = a; 563 | oldb = b; 564 | oldc = c; 565 | oldd = d; 566 | 567 | a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936); 568 | d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); 569 | c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); 570 | b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); 571 | a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); 572 | d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); 573 | c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); 574 | b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); 575 | a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); 576 | d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); 577 | c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); 578 | b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); 579 | a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); 580 | d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); 581 | c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); 582 | b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); 583 | 584 | a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); 585 | d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); 586 | c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); 587 | b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302); 588 | a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); 589 | d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); 590 | c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); 591 | b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); 592 | a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); 593 | d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); 594 | c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); 595 | b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); 596 | a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); 597 | d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); 598 | c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); 599 | b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); 600 | 601 | a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); 602 | d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); 603 | c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); 604 | b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); 605 | a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); 606 | d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); 607 | c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); 608 | b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); 609 | a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); 610 | d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222); 611 | c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); 612 | b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); 613 | a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); 614 | d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); 615 | c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); 616 | b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); 617 | 618 | a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844); 619 | d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); 620 | c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); 621 | b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); 622 | a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); 623 | d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); 624 | c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); 625 | b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); 626 | a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); 627 | d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); 628 | c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); 629 | b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); 630 | a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); 631 | d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); 632 | c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); 633 | b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); 634 | 635 | a = safe_add(a, olda); 636 | b = safe_add(b, oldb); 637 | c = safe_add(c, oldc); 638 | d = safe_add(d, oldd); 639 | } 640 | return Array(a, b, c, d); 641 | } 642 | 643 | /** 644 | * These functions implement the four basic operations the algorithm uses. 645 | */ 646 | 647 | function md5_cmn(q, a, b, x, s, t) { 648 | return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); 649 | } 650 | 651 | function md5_ff(a, b, c, d, x, s, t) { 652 | return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); 653 | } 654 | 655 | function md5_gg(a, b, c, d, x, s, t) { 656 | return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); 657 | } 658 | 659 | function md5_hh(a, b, c, d, x, s, t) { 660 | return md5_cmn(b ^ c ^ d, a, b, x, s, t); 661 | } 662 | 663 | function md5_ii(a, b, c, d, x, s, t) { 664 | return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); 665 | } 666 | }, 667 | /** 668 | * @member Hashes 669 | * @class Hashes.SHA1 670 | * @param {Object} [config] 671 | * @constructor 672 | * 673 | * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1 674 | * Version 2.2 Copyright Paul Johnston 2000 - 2009. 675 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 676 | * See http://pajhome.org.uk/crypt/md5 for details. 677 | */ 678 | SHA1: function(options) { 679 | /** 680 | * Private config properties. You may need to tweak these to be compatible with 681 | * the server-side, but the defaults work in most cases. 682 | * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase} 683 | */ 684 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase 685 | b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance 686 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding 687 | 688 | // public methods 689 | this.hex = function(s) { 690 | return rstr2hex(rstr(s, utf8), hexcase); 691 | }; 692 | this.b64 = function(s) { 693 | return rstr2b64(rstr(s, utf8), b64pad); 694 | }; 695 | this.any = function(s, e) { 696 | return rstr2any(rstr(s, utf8), e); 697 | }; 698 | this.raw = function(s) { 699 | return rstr(s, utf8); 700 | }; 701 | this.hex_hmac = function(k, d) { 702 | return rstr2hex(rstr_hmac(k, d)); 703 | }; 704 | this.b64_hmac = function(k, d) { 705 | return rstr2b64(rstr_hmac(k, d), b64pad); 706 | }; 707 | this.any_hmac = function(k, d, e) { 708 | return rstr2any(rstr_hmac(k, d), e); 709 | }; 710 | /** 711 | * Perform a simple self-test to see if the VM is working 712 | * @return {String} Hexadecimal hash sample 713 | * @public 714 | */ 715 | this.vm_test = function() { 716 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; 717 | }; 718 | /** 719 | * @description Enable/disable uppercase hexadecimal returned string 720 | * @param {boolean} 721 | * @return {Object} this 722 | * @public 723 | */ 724 | this.setUpperCase = function(a) { 725 | if (typeof a === 'boolean') { 726 | hexcase = a; 727 | } 728 | return this; 729 | }; 730 | /** 731 | * @description Defines a base64 pad string 732 | * @param {string} Pad 733 | * @return {Object} this 734 | * @public 735 | */ 736 | this.setPad = function(a) { 737 | b64pad = a || b64pad; 738 | return this; 739 | }; 740 | /** 741 | * @description Defines a base64 pad string 742 | * @param {boolean} 743 | * @return {Object} this 744 | * @public 745 | */ 746 | this.setUTF8 = function(a) { 747 | if (typeof a === 'boolean') { 748 | utf8 = a; 749 | } 750 | return this; 751 | }; 752 | 753 | // private methods 754 | 755 | /** 756 | * Calculate the SHA-512 of a raw string 757 | */ 758 | 759 | function rstr(s) { 760 | s = (utf8) ? utf8Encode(s) : s; 761 | return binb2rstr(binb(rstr2binb(s), s.length * 8)); 762 | } 763 | 764 | /** 765 | * Calculate the HMAC-SHA1 of a key and some data (raw strings) 766 | */ 767 | 768 | function rstr_hmac(key, data) { 769 | var bkey, ipad, opad, i, hash; 770 | key = (utf8) ? utf8Encode(key) : key; 771 | data = (utf8) ? utf8Encode(data) : data; 772 | bkey = rstr2binb(key); 773 | 774 | if (bkey.length > 16) { 775 | bkey = binb(bkey, key.length * 8); 776 | } 777 | ipad = Array(16), opad = Array(16); 778 | for (i = 0; i < 16; i += 1) { 779 | ipad[i] = bkey[i] ^ 0x36363636; 780 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 781 | } 782 | hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8); 783 | return binb2rstr(binb(opad.concat(hash), 512 + 160)); 784 | } 785 | 786 | /** 787 | * Calculate the SHA-1 of an array of big-endian words, and a bit length 788 | */ 789 | 790 | function binb(x, len) { 791 | var i, j, t, olda, oldb, oldc, oldd, olde, 792 | w = Array(80), 793 | a = 1732584193, 794 | b = -271733879, 795 | c = -1732584194, 796 | d = 271733878, 797 | e = -1009589776; 798 | 799 | /* append padding */ 800 | x[len >> 5] |= 0x80 << (24 - len % 32); 801 | x[((len + 64 >> 9) << 4) + 15] = len; 802 | 803 | for (i = 0; i < x.length; i += 16) { 804 | olda = a; 805 | oldb = b; 806 | oldc = c; 807 | oldd = d; 808 | olde = e; 809 | 810 | for (j = 0; j < 80; j += 1) { 811 | if (j < 16) { 812 | w[j] = x[i + j]; 813 | } else { 814 | w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); 815 | } 816 | t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)), 817 | safe_add(safe_add(e, w[j]), sha1_kt(j))); 818 | e = d; 819 | d = c; 820 | c = bit_rol(b, 30); 821 | b = a; 822 | a = t; 823 | } 824 | 825 | a = safe_add(a, olda); 826 | b = safe_add(b, oldb); 827 | c = safe_add(c, oldc); 828 | d = safe_add(d, oldd); 829 | e = safe_add(e, olde); 830 | } 831 | return Array(a, b, c, d, e); 832 | } 833 | 834 | /** 835 | * Perform the appropriate triplet combination function for the current 836 | * iteration 837 | */ 838 | 839 | function sha1_ft(t, b, c, d) { 840 | if (t < 20) { 841 | return (b & c) | ((~b) & d); 842 | } 843 | if (t < 40) { 844 | return b ^ c ^ d; 845 | } 846 | if (t < 60) { 847 | return (b & c) | (b & d) | (c & d); 848 | } 849 | return b ^ c ^ d; 850 | } 851 | 852 | /** 853 | * Determine the appropriate additive constant for the current iteration 854 | */ 855 | 856 | function sha1_kt(t) { 857 | return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : 858 | (t < 60) ? -1894007588 : -899497514; 859 | } 860 | }, 861 | /** 862 | * @class Hashes.SHA256 863 | * @param {config} 864 | * 865 | * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2 866 | * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009. 867 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 868 | * See http://pajhome.org.uk/crypt/md5 for details. 869 | * Also http://anmar.eu.org/projects/jssha2/ 870 | */ 871 | SHA256: function(options) { 872 | /** 873 | * Private properties configuration variables. You may need to tweak these to be compatible with 874 | * the server-side, but the defaults work in most cases. 875 | * @see this.setUpperCase() method 876 | * @see this.setPad() method 877 | */ 878 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase */ 879 | b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', 880 | /* base-64 pad character. Default '=' for strict RFC compliance */ 881 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true, 882 | /* enable/disable utf8 encoding */ 883 | sha256_K; 884 | 885 | /* privileged (public) methods */ 886 | this.hex = function(s) { 887 | return rstr2hex(rstr(s, utf8)); 888 | }; 889 | this.b64 = function(s) { 890 | return rstr2b64(rstr(s, utf8), b64pad); 891 | }; 892 | this.any = function(s, e) { 893 | return rstr2any(rstr(s, utf8), e); 894 | }; 895 | this.raw = function(s) { 896 | return rstr(s, utf8); 897 | }; 898 | this.hex_hmac = function(k, d) { 899 | return rstr2hex(rstr_hmac(k, d)); 900 | }; 901 | this.b64_hmac = function(k, d) { 902 | return rstr2b64(rstr_hmac(k, d), b64pad); 903 | }; 904 | this.any_hmac = function(k, d, e) { 905 | return rstr2any(rstr_hmac(k, d), e); 906 | }; 907 | /** 908 | * Perform a simple self-test to see if the VM is working 909 | * @return {String} Hexadecimal hash sample 910 | * @public 911 | */ 912 | this.vm_test = function() { 913 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; 914 | }; 915 | /** 916 | * Enable/disable uppercase hexadecimal returned string 917 | * @param {boolean} 918 | * @return {Object} this 919 | * @public 920 | */ 921 | this.setUpperCase = function(a) { 922 | if (typeof a === 'boolean') { 923 | hexcase = a; 924 | } 925 | return this; 926 | }; 927 | /** 928 | * @description Defines a base64 pad string 929 | * @param {string} Pad 930 | * @return {Object} this 931 | * @public 932 | */ 933 | this.setPad = function(a) { 934 | b64pad = a || b64pad; 935 | return this; 936 | }; 937 | /** 938 | * Defines a base64 pad string 939 | * @param {boolean} 940 | * @return {Object} this 941 | * @public 942 | */ 943 | this.setUTF8 = function(a) { 944 | if (typeof a === 'boolean') { 945 | utf8 = a; 946 | } 947 | return this; 948 | }; 949 | 950 | // private methods 951 | 952 | /** 953 | * Calculate the SHA-512 of a raw string 954 | */ 955 | 956 | function rstr(s, utf8) { 957 | s = (utf8) ? utf8Encode(s) : s; 958 | return binb2rstr(binb(rstr2binb(s), s.length * 8)); 959 | } 960 | 961 | /** 962 | * Calculate the HMAC-sha256 of a key and some data (raw strings) 963 | */ 964 | 965 | function rstr_hmac(key, data) { 966 | key = (utf8) ? utf8Encode(key) : key; 967 | data = (utf8) ? utf8Encode(data) : data; 968 | var hash, i = 0, 969 | bkey = rstr2binb(key), 970 | ipad = Array(16), 971 | opad = Array(16); 972 | 973 | if (bkey.length > 16) { 974 | bkey = binb(bkey, key.length * 8); 975 | } 976 | 977 | for (; i < 16; i += 1) { 978 | ipad[i] = bkey[i] ^ 0x36363636; 979 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 980 | } 981 | 982 | hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8); 983 | return binb2rstr(binb(opad.concat(hash), 512 + 256)); 984 | } 985 | 986 | /* 987 | * Main sha256 function, with its support functions 988 | */ 989 | 990 | function sha256_S(X, n) { 991 | return (X >>> n) | (X << (32 - n)); 992 | } 993 | 994 | function sha256_R(X, n) { 995 | return (X >>> n); 996 | } 997 | 998 | function sha256_Ch(x, y, z) { 999 | return ((x & y) ^ ((~x) & z)); 1000 | } 1001 | 1002 | function sha256_Maj(x, y, z) { 1003 | return ((x & y) ^ (x & z) ^ (y & z)); 1004 | } 1005 | 1006 | function sha256_Sigma0256(x) { 1007 | return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22)); 1008 | } 1009 | 1010 | function sha256_Sigma1256(x) { 1011 | return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25)); 1012 | } 1013 | 1014 | function sha256_Gamma0256(x) { 1015 | return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3)); 1016 | } 1017 | 1018 | function sha256_Gamma1256(x) { 1019 | return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10)); 1020 | } 1021 | 1022 | function sha256_Sigma0512(x) { 1023 | return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39)); 1024 | } 1025 | 1026 | function sha256_Sigma1512(x) { 1027 | return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41)); 1028 | } 1029 | 1030 | function sha256_Gamma0512(x) { 1031 | return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7)); 1032 | } 1033 | 1034 | function sha256_Gamma1512(x) { 1035 | return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6)); 1036 | } 1037 | 1038 | sha256_K = [ 1039 | 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987, 1040 | 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522, 1041 | 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585, 1042 | 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1043 | 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344, 1044 | 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1045 | 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998 1046 | ]; 1047 | 1048 | function binb(m, l) { 1049 | var HASH = [1779033703, -1150833019, 1013904242, -1521486534, 1050 | 1359893119, -1694144372, 528734635, 1541459225 1051 | ]; 1052 | var W = new Array(64); 1053 | var a, b, c, d, e, f, g, h; 1054 | var i, j, T1, T2; 1055 | 1056 | /* append padding */ 1057 | m[l >> 5] |= 0x80 << (24 - l % 32); 1058 | m[((l + 64 >> 9) << 4) + 15] = l; 1059 | 1060 | for (i = 0; i < m.length; i += 16) { 1061 | a = HASH[0]; 1062 | b = HASH[1]; 1063 | c = HASH[2]; 1064 | d = HASH[3]; 1065 | e = HASH[4]; 1066 | f = HASH[5]; 1067 | g = HASH[6]; 1068 | h = HASH[7]; 1069 | 1070 | for (j = 0; j < 64; j += 1) { 1071 | if (j < 16) { 1072 | W[j] = m[j + i]; 1073 | } else { 1074 | W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]), 1075 | sha256_Gamma0256(W[j - 15])), W[j - 16]); 1076 | } 1077 | 1078 | T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)), 1079 | sha256_K[j]), W[j]); 1080 | T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c)); 1081 | h = g; 1082 | g = f; 1083 | f = e; 1084 | e = safe_add(d, T1); 1085 | d = c; 1086 | c = b; 1087 | b = a; 1088 | a = safe_add(T1, T2); 1089 | } 1090 | 1091 | HASH[0] = safe_add(a, HASH[0]); 1092 | HASH[1] = safe_add(b, HASH[1]); 1093 | HASH[2] = safe_add(c, HASH[2]); 1094 | HASH[3] = safe_add(d, HASH[3]); 1095 | HASH[4] = safe_add(e, HASH[4]); 1096 | HASH[5] = safe_add(f, HASH[5]); 1097 | HASH[6] = safe_add(g, HASH[6]); 1098 | HASH[7] = safe_add(h, HASH[7]); 1099 | } 1100 | return HASH; 1101 | } 1102 | 1103 | }, 1104 | 1105 | /** 1106 | * @class Hashes.SHA512 1107 | * @param {config} 1108 | * 1109 | * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2 1110 | * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009. 1111 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 1112 | * See http://pajhome.org.uk/crypt/md5 for details. 1113 | */ 1114 | SHA512: function(options) { 1115 | /** 1116 | * Private properties configuration variables. You may need to tweak these to be compatible with 1117 | * the server-side, but the defaults work in most cases. 1118 | * @see this.setUpperCase() method 1119 | * @see this.setPad() method 1120 | */ 1121 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, 1122 | /* hexadecimal output case format. false - lowercase; true - uppercase */ 1123 | b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', 1124 | /* base-64 pad character. Default '=' for strict RFC compliance */ 1125 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true, 1126 | /* enable/disable utf8 encoding */ 1127 | sha512_k; 1128 | 1129 | /* privileged (public) methods */ 1130 | this.hex = function(s) { 1131 | return rstr2hex(rstr(s)); 1132 | }; 1133 | this.b64 = function(s) { 1134 | return rstr2b64(rstr(s), b64pad); 1135 | }; 1136 | this.any = function(s, e) { 1137 | return rstr2any(rstr(s), e); 1138 | }; 1139 | this.raw = function(s) { 1140 | return rstr(s, utf8); 1141 | }; 1142 | this.hex_hmac = function(k, d) { 1143 | return rstr2hex(rstr_hmac(k, d)); 1144 | }; 1145 | this.b64_hmac = function(k, d) { 1146 | return rstr2b64(rstr_hmac(k, d), b64pad); 1147 | }; 1148 | this.any_hmac = function(k, d, e) { 1149 | return rstr2any(rstr_hmac(k, d), e); 1150 | }; 1151 | /** 1152 | * Perform a simple self-test to see if the VM is working 1153 | * @return {String} Hexadecimal hash sample 1154 | * @public 1155 | */ 1156 | this.vm_test = function() { 1157 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; 1158 | }; 1159 | /** 1160 | * @description Enable/disable uppercase hexadecimal returned string 1161 | * @param {boolean} 1162 | * @return {Object} this 1163 | * @public 1164 | */ 1165 | this.setUpperCase = function(a) { 1166 | if (typeof a === 'boolean') { 1167 | hexcase = a; 1168 | } 1169 | return this; 1170 | }; 1171 | /** 1172 | * @description Defines a base64 pad string 1173 | * @param {string} Pad 1174 | * @return {Object} this 1175 | * @public 1176 | */ 1177 | this.setPad = function(a) { 1178 | b64pad = a || b64pad; 1179 | return this; 1180 | }; 1181 | /** 1182 | * @description Defines a base64 pad string 1183 | * @param {boolean} 1184 | * @return {Object} this 1185 | * @public 1186 | */ 1187 | this.setUTF8 = function(a) { 1188 | if (typeof a === 'boolean') { 1189 | utf8 = a; 1190 | } 1191 | return this; 1192 | }; 1193 | 1194 | /* private methods */ 1195 | 1196 | /** 1197 | * Calculate the SHA-512 of a raw string 1198 | */ 1199 | 1200 | function rstr(s) { 1201 | s = (utf8) ? utf8Encode(s) : s; 1202 | return binb2rstr(binb(rstr2binb(s), s.length * 8)); 1203 | } 1204 | /* 1205 | * Calculate the HMAC-SHA-512 of a key and some data (raw strings) 1206 | */ 1207 | 1208 | function rstr_hmac(key, data) { 1209 | key = (utf8) ? utf8Encode(key) : key; 1210 | data = (utf8) ? utf8Encode(data) : data; 1211 | 1212 | var hash, i = 0, 1213 | bkey = rstr2binb(key), 1214 | ipad = Array(32), 1215 | opad = Array(32); 1216 | 1217 | if (bkey.length > 32) { 1218 | bkey = binb(bkey, key.length * 8); 1219 | } 1220 | 1221 | for (; i < 32; i += 1) { 1222 | ipad[i] = bkey[i] ^ 0x36363636; 1223 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 1224 | } 1225 | 1226 | hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8); 1227 | return binb2rstr(binb(opad.concat(hash), 1024 + 512)); 1228 | } 1229 | 1230 | /** 1231 | * Calculate the SHA-512 of an array of big-endian dwords, and a bit length 1232 | */ 1233 | 1234 | function binb(x, len) { 1235 | var j, i, l, 1236 | W = new Array(80), 1237 | hash = new Array(16), 1238 | //Initial hash values 1239 | H = [ 1240 | new int64(0x6a09e667, -205731576), 1241 | new int64(-1150833019, -2067093701), 1242 | new int64(0x3c6ef372, -23791573), 1243 | new int64(-1521486534, 0x5f1d36f1), 1244 | new int64(0x510e527f, -1377402159), 1245 | new int64(-1694144372, 0x2b3e6c1f), 1246 | new int64(0x1f83d9ab, -79577749), 1247 | new int64(0x5be0cd19, 0x137e2179) 1248 | ], 1249 | T1 = new int64(0, 0), 1250 | T2 = new int64(0, 0), 1251 | a = new int64(0, 0), 1252 | b = new int64(0, 0), 1253 | c = new int64(0, 0), 1254 | d = new int64(0, 0), 1255 | e = new int64(0, 0), 1256 | f = new int64(0, 0), 1257 | g = new int64(0, 0), 1258 | h = new int64(0, 0), 1259 | //Temporary variables not specified by the document 1260 | s0 = new int64(0, 0), 1261 | s1 = new int64(0, 0), 1262 | Ch = new int64(0, 0), 1263 | Maj = new int64(0, 0), 1264 | r1 = new int64(0, 0), 1265 | r2 = new int64(0, 0), 1266 | r3 = new int64(0, 0); 1267 | 1268 | if (sha512_k === undefined) { 1269 | //SHA512 constants 1270 | sha512_k = [ 1271 | new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd), 1272 | new int64(-1245643825, -330482897), new int64(-373957723, -2121671748), 1273 | new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031), 1274 | new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736), 1275 | new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe), 1276 | new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302), 1277 | new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1), 1278 | new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428), 1279 | new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3), 1280 | new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65), 1281 | new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483), 1282 | new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459), 1283 | new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210), 1284 | new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340), 1285 | new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395), 1286 | new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70), 1287 | new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926), 1288 | new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473), 1289 | new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8), 1290 | new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b), 1291 | new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023), 1292 | new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30), 1293 | new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910), 1294 | new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8), 1295 | new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53), 1296 | new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016), 1297 | new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893), 1298 | new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397), 1299 | new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60), 1300 | new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec), 1301 | new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047), 1302 | new int64(-1090935817, -1295615723), new int64(-965641998, -479046869), 1303 | new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207), 1304 | new int64(-354779690, -840897762), new int64(-176337025, -294727304), 1305 | new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026), 1306 | new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b), 1307 | new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493), 1308 | new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620), 1309 | new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430), 1310 | new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817) 1311 | ]; 1312 | } 1313 | 1314 | for (i = 0; i < 80; i += 1) { 1315 | W[i] = new int64(0, 0); 1316 | } 1317 | 1318 | // append padding to the source string. The format is described in the FIPS. 1319 | x[len >> 5] |= 0x80 << (24 - (len & 0x1f)); 1320 | x[((len + 128 >> 10) << 5) + 31] = len; 1321 | l = x.length; 1322 | for (i = 0; i < l; i += 32) { //32 dwords is the block size 1323 | int64copy(a, H[0]); 1324 | int64copy(b, H[1]); 1325 | int64copy(c, H[2]); 1326 | int64copy(d, H[3]); 1327 | int64copy(e, H[4]); 1328 | int64copy(f, H[5]); 1329 | int64copy(g, H[6]); 1330 | int64copy(h, H[7]); 1331 | 1332 | for (j = 0; j < 16; j += 1) { 1333 | W[j].h = x[i + 2 * j]; 1334 | W[j].l = x[i + 2 * j + 1]; 1335 | } 1336 | 1337 | for (j = 16; j < 80; j += 1) { 1338 | //sigma1 1339 | int64rrot(r1, W[j - 2], 19); 1340 | int64revrrot(r2, W[j - 2], 29); 1341 | int64shr(r3, W[j - 2], 6); 1342 | s1.l = r1.l ^ r2.l ^ r3.l; 1343 | s1.h = r1.h ^ r2.h ^ r3.h; 1344 | //sigma0 1345 | int64rrot(r1, W[j - 15], 1); 1346 | int64rrot(r2, W[j - 15], 8); 1347 | int64shr(r3, W[j - 15], 7); 1348 | s0.l = r1.l ^ r2.l ^ r3.l; 1349 | s0.h = r1.h ^ r2.h ^ r3.h; 1350 | 1351 | int64add4(W[j], s1, W[j - 7], s0, W[j - 16]); 1352 | } 1353 | 1354 | for (j = 0; j < 80; j += 1) { 1355 | //Ch 1356 | Ch.l = (e.l & f.l) ^ (~e.l & g.l); 1357 | Ch.h = (e.h & f.h) ^ (~e.h & g.h); 1358 | 1359 | //Sigma1 1360 | int64rrot(r1, e, 14); 1361 | int64rrot(r2, e, 18); 1362 | int64revrrot(r3, e, 9); 1363 | s1.l = r1.l ^ r2.l ^ r3.l; 1364 | s1.h = r1.h ^ r2.h ^ r3.h; 1365 | 1366 | //Sigma0 1367 | int64rrot(r1, a, 28); 1368 | int64revrrot(r2, a, 2); 1369 | int64revrrot(r3, a, 7); 1370 | s0.l = r1.l ^ r2.l ^ r3.l; 1371 | s0.h = r1.h ^ r2.h ^ r3.h; 1372 | 1373 | //Maj 1374 | Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l); 1375 | Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h); 1376 | 1377 | int64add5(T1, h, s1, Ch, sha512_k[j], W[j]); 1378 | int64add(T2, s0, Maj); 1379 | 1380 | int64copy(h, g); 1381 | int64copy(g, f); 1382 | int64copy(f, e); 1383 | int64add(e, d, T1); 1384 | int64copy(d, c); 1385 | int64copy(c, b); 1386 | int64copy(b, a); 1387 | int64add(a, T1, T2); 1388 | } 1389 | int64add(H[0], H[0], a); 1390 | int64add(H[1], H[1], b); 1391 | int64add(H[2], H[2], c); 1392 | int64add(H[3], H[3], d); 1393 | int64add(H[4], H[4], e); 1394 | int64add(H[5], H[5], f); 1395 | int64add(H[6], H[6], g); 1396 | int64add(H[7], H[7], h); 1397 | } 1398 | 1399 | //represent the hash as an array of 32-bit dwords 1400 | for (i = 0; i < 8; i += 1) { 1401 | hash[2 * i] = H[i].h; 1402 | hash[2 * i + 1] = H[i].l; 1403 | } 1404 | return hash; 1405 | } 1406 | 1407 | //A constructor for 64-bit numbers 1408 | 1409 | function int64(h, l) { 1410 | this.h = h; 1411 | this.l = l; 1412 | //this.toString = int64toString; 1413 | } 1414 | 1415 | //Copies src into dst, assuming both are 64-bit numbers 1416 | 1417 | function int64copy(dst, src) { 1418 | dst.h = src.h; 1419 | dst.l = src.l; 1420 | } 1421 | 1422 | //Right-rotates a 64-bit number by shift 1423 | //Won't handle cases of shift>=32 1424 | //The function revrrot() is for that 1425 | 1426 | function int64rrot(dst, x, shift) { 1427 | dst.l = (x.l >>> shift) | (x.h << (32 - shift)); 1428 | dst.h = (x.h >>> shift) | (x.l << (32 - shift)); 1429 | } 1430 | 1431 | //Reverses the dwords of the source and then rotates right by shift. 1432 | //This is equivalent to rotation by 32+shift 1433 | 1434 | function int64revrrot(dst, x, shift) { 1435 | dst.l = (x.h >>> shift) | (x.l << (32 - shift)); 1436 | dst.h = (x.l >>> shift) | (x.h << (32 - shift)); 1437 | } 1438 | 1439 | //Bitwise-shifts right a 64-bit number by shift 1440 | //Won't handle shift>=32, but it's never needed in SHA512 1441 | 1442 | function int64shr(dst, x, shift) { 1443 | dst.l = (x.l >>> shift) | (x.h << (32 - shift)); 1444 | dst.h = (x.h >>> shift); 1445 | } 1446 | 1447 | //Adds two 64-bit numbers 1448 | //Like the original implementation, does not rely on 32-bit operations 1449 | 1450 | function int64add(dst, x, y) { 1451 | var w0 = (x.l & 0xffff) + (y.l & 0xffff); 1452 | var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16); 1453 | var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16); 1454 | var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16); 1455 | dst.l = (w0 & 0xffff) | (w1 << 16); 1456 | dst.h = (w2 & 0xffff) | (w3 << 16); 1457 | } 1458 | 1459 | //Same, except with 4 addends. Works faster than adding them one by one. 1460 | 1461 | function int64add4(dst, a, b, c, d) { 1462 | var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff); 1463 | var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16); 1464 | var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16); 1465 | var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16); 1466 | dst.l = (w0 & 0xffff) | (w1 << 16); 1467 | dst.h = (w2 & 0xffff) | (w3 << 16); 1468 | } 1469 | 1470 | //Same, except with 5 addends 1471 | 1472 | function int64add5(dst, a, b, c, d, e) { 1473 | var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff), 1474 | w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16), 1475 | w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16), 1476 | w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16); 1477 | dst.l = (w0 & 0xffff) | (w1 << 16); 1478 | dst.h = (w2 & 0xffff) | (w3 << 16); 1479 | } 1480 | }, 1481 | /** 1482 | * @class Hashes.RMD160 1483 | * @constructor 1484 | * @param {Object} [config] 1485 | * 1486 | * A JavaScript implementation of the RIPEMD-160 Algorithm 1487 | * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009. 1488 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 1489 | * See http://pajhome.org.uk/crypt/md5 for details. 1490 | * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/ 1491 | */ 1492 | RMD160: function(options) { 1493 | /** 1494 | * Private properties configuration variables. You may need to tweak these to be compatible with 1495 | * the server-side, but the defaults work in most cases. 1496 | * @see this.setUpperCase() method 1497 | * @see this.setPad() method 1498 | */ 1499 | var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, 1500 | /* hexadecimal output case format. false - lowercase; true - uppercase */ 1501 | b64pad = (options && typeof options.pad === 'string') ? options.pa : '=', 1502 | /* base-64 pad character. Default '=' for strict RFC compliance */ 1503 | utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true, 1504 | /* enable/disable utf8 encoding */ 1505 | rmd160_r1 = [ 1506 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1507 | 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 1508 | 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1509 | 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 1510 | 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 1511 | ], 1512 | rmd160_r2 = [ 1513 | 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 1514 | 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 1515 | 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 1516 | 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 1517 | 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 1518 | ], 1519 | rmd160_s1 = [ 1520 | 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 1521 | 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 1522 | 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 1523 | 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 1524 | 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 1525 | ], 1526 | rmd160_s2 = [ 1527 | 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 1528 | 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 1529 | 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 1530 | 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 1531 | 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 1532 | ]; 1533 | 1534 | /* privileged (public) methods */ 1535 | this.hex = function(s) { 1536 | return rstr2hex(rstr(s, utf8)); 1537 | }; 1538 | this.b64 = function(s) { 1539 | return rstr2b64(rstr(s, utf8), b64pad); 1540 | }; 1541 | this.any = function(s, e) { 1542 | return rstr2any(rstr(s, utf8), e); 1543 | }; 1544 | this.raw = function(s) { 1545 | return rstr(s, utf8); 1546 | }; 1547 | this.hex_hmac = function(k, d) { 1548 | return rstr2hex(rstr_hmac(k, d)); 1549 | }; 1550 | this.b64_hmac = function(k, d) { 1551 | return rstr2b64(rstr_hmac(k, d), b64pad); 1552 | }; 1553 | this.any_hmac = function(k, d, e) { 1554 | return rstr2any(rstr_hmac(k, d), e); 1555 | }; 1556 | /** 1557 | * Perform a simple self-test to see if the VM is working 1558 | * @return {String} Hexadecimal hash sample 1559 | * @public 1560 | */ 1561 | this.vm_test = function() { 1562 | return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72'; 1563 | }; 1564 | /** 1565 | * @description Enable/disable uppercase hexadecimal returned string 1566 | * @param {boolean} 1567 | * @return {Object} this 1568 | * @public 1569 | */ 1570 | this.setUpperCase = function(a) { 1571 | if (typeof a === 'boolean') { 1572 | hexcase = a; 1573 | } 1574 | return this; 1575 | }; 1576 | /** 1577 | * @description Defines a base64 pad string 1578 | * @param {string} Pad 1579 | * @return {Object} this 1580 | * @public 1581 | */ 1582 | this.setPad = function(a) { 1583 | if (typeof a !== 'undefined') { 1584 | b64pad = a; 1585 | } 1586 | return this; 1587 | }; 1588 | /** 1589 | * @description Defines a base64 pad string 1590 | * @param {boolean} 1591 | * @return {Object} this 1592 | * @public 1593 | */ 1594 | this.setUTF8 = function(a) { 1595 | if (typeof a === 'boolean') { 1596 | utf8 = a; 1597 | } 1598 | return this; 1599 | }; 1600 | 1601 | /* private methods */ 1602 | 1603 | /** 1604 | * Calculate the rmd160 of a raw string 1605 | */ 1606 | 1607 | function rstr(s) { 1608 | s = (utf8) ? utf8Encode(s) : s; 1609 | return binl2rstr(binl(rstr2binl(s), s.length * 8)); 1610 | } 1611 | 1612 | /** 1613 | * Calculate the HMAC-rmd160 of a key and some data (raw strings) 1614 | */ 1615 | 1616 | function rstr_hmac(key, data) { 1617 | key = (utf8) ? utf8Encode(key) : key; 1618 | data = (utf8) ? utf8Encode(data) : data; 1619 | var i, hash, 1620 | bkey = rstr2binl(key), 1621 | ipad = Array(16), 1622 | opad = Array(16); 1623 | 1624 | if (bkey.length > 16) { 1625 | bkey = binl(bkey, key.length * 8); 1626 | } 1627 | 1628 | for (i = 0; i < 16; i += 1) { 1629 | ipad[i] = bkey[i] ^ 0x36363636; 1630 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 1631 | } 1632 | hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8); 1633 | return binl2rstr(binl(opad.concat(hash), 512 + 160)); 1634 | } 1635 | 1636 | /** 1637 | * Convert an array of little-endian words to a string 1638 | */ 1639 | 1640 | function binl2rstr(input) { 1641 | var i, output = '', 1642 | l = input.length * 32; 1643 | for (i = 0; i < l; i += 8) { 1644 | output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); 1645 | } 1646 | return output; 1647 | } 1648 | 1649 | /** 1650 | * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length. 1651 | */ 1652 | 1653 | function binl(x, len) { 1654 | var T, j, i, l, 1655 | h0 = 0x67452301, 1656 | h1 = 0xefcdab89, 1657 | h2 = 0x98badcfe, 1658 | h3 = 0x10325476, 1659 | h4 = 0xc3d2e1f0, 1660 | A1, B1, C1, D1, E1, 1661 | A2, B2, C2, D2, E2; 1662 | 1663 | /* append padding */ 1664 | x[len >> 5] |= 0x80 << (len % 32); 1665 | x[(((len + 64) >>> 9) << 4) + 14] = len; 1666 | l = x.length; 1667 | 1668 | for (i = 0; i < l; i += 16) { 1669 | A1 = A2 = h0; 1670 | B1 = B2 = h1; 1671 | C1 = C2 = h2; 1672 | D1 = D2 = h3; 1673 | E1 = E2 = h4; 1674 | for (j = 0; j <= 79; j += 1) { 1675 | T = safe_add(A1, rmd160_f(j, B1, C1, D1)); 1676 | T = safe_add(T, x[i + rmd160_r1[j]]); 1677 | T = safe_add(T, rmd160_K1(j)); 1678 | T = safe_add(bit_rol(T, rmd160_s1[j]), E1); 1679 | A1 = E1; 1680 | E1 = D1; 1681 | D1 = bit_rol(C1, 10); 1682 | C1 = B1; 1683 | B1 = T; 1684 | T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2)); 1685 | T = safe_add(T, x[i + rmd160_r2[j]]); 1686 | T = safe_add(T, rmd160_K2(j)); 1687 | T = safe_add(bit_rol(T, rmd160_s2[j]), E2); 1688 | A2 = E2; 1689 | E2 = D2; 1690 | D2 = bit_rol(C2, 10); 1691 | C2 = B2; 1692 | B2 = T; 1693 | } 1694 | 1695 | T = safe_add(h1, safe_add(C1, D2)); 1696 | h1 = safe_add(h2, safe_add(D1, E2)); 1697 | h2 = safe_add(h3, safe_add(E1, A2)); 1698 | h3 = safe_add(h4, safe_add(A1, B2)); 1699 | h4 = safe_add(h0, safe_add(B1, C2)); 1700 | h0 = T; 1701 | } 1702 | return [h0, h1, h2, h3, h4]; 1703 | } 1704 | 1705 | // specific algorithm methods 1706 | 1707 | function rmd160_f(j, x, y, z) { 1708 | return (0 <= j && j <= 15) ? (x ^ y ^ z) : 1709 | (16 <= j && j <= 31) ? (x & y) | (~x & z) : 1710 | (32 <= j && j <= 47) ? (x | ~y) ^ z : 1711 | (48 <= j && j <= 63) ? (x & z) | (y & ~z) : 1712 | (64 <= j && j <= 79) ? x ^ (y | ~z) : 1713 | 'rmd160_f: j out of range'; 1714 | } 1715 | 1716 | function rmd160_K1(j) { 1717 | return (0 <= j && j <= 15) ? 0x00000000 : 1718 | (16 <= j && j <= 31) ? 0x5a827999 : 1719 | (32 <= j && j <= 47) ? 0x6ed9eba1 : 1720 | (48 <= j && j <= 63) ? 0x8f1bbcdc : 1721 | (64 <= j && j <= 79) ? 0xa953fd4e : 1722 | 'rmd160_K1: j out of range'; 1723 | } 1724 | 1725 | function rmd160_K2(j) { 1726 | return (0 <= j && j <= 15) ? 0x50a28be6 : 1727 | (16 <= j && j <= 31) ? 0x5c4dd124 : 1728 | (32 <= j && j <= 47) ? 0x6d703ef3 : 1729 | (48 <= j && j <= 63) ? 0x7a6d76e9 : 1730 | (64 <= j && j <= 79) ? 0x00000000 : 1731 | 'rmd160_K2: j out of range'; 1732 | } 1733 | } 1734 | }; 1735 | 1736 | // exposes Hashes 1737 | (function(window, undefined) { 1738 | var freeExports = false; 1739 | if (typeof exports === 'object') { 1740 | freeExports = exports; 1741 | if (exports && typeof global === 'object' && global && global === global.global) { 1742 | window = global; 1743 | } 1744 | } 1745 | 1746 | if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { 1747 | // define as an anonymous module, so, through path mapping, it can be aliased 1748 | define(function() { 1749 | return Hashes; 1750 | }); 1751 | } else if (freeExports) { 1752 | // in Node.js or RingoJS v0.8.0+ 1753 | if (typeof module === 'object' && module && module.exports === freeExports) { 1754 | module.exports = Hashes; 1755 | } 1756 | // in Narwhal or RingoJS v0.7.0- 1757 | else { 1758 | freeExports.Hashes = Hashes; 1759 | } 1760 | } else { 1761 | // in a browser or Rhino 1762 | window.Hashes = Hashes; 1763 | } 1764 | }(this)); 1765 | }()); // IIFE 1766 | -------------------------------------------------------------------------------- /hashes.min.js: -------------------------------------------------------------------------------- 1 | /*! jshashes - New BSD License - https://github.com/h2non/jshashes */ 2 | (function(){var n;function e(n){var e,t,r="",o=-1,f;if(n&&n.length){f=n.length;while((o+=1)>>6&31,128|e&63)}else if(e<=65535){r+=String.fromCharCode(224|e>>>12&15,128|e>>>6&63,128|e&63)}else if(e<=2097151){r+=String.fromCharCode(240|e>>>18&7,128|e>>>12&63,128|e>>>6&63,128|e&63)}}}return r}function t(n){var e,t,r,o,f,i=[],h;e=t=r=o=f=0;if(n&&n.length){h=n.length;n+="";while(e191&&r<224){o=n.charCodeAt(e+1);i[t]=String.fromCharCode((r&31)<<6|o&63);e+=2}else{o=n.charCodeAt(e+1);f=n.charCodeAt(e+2);i[t]=String.fromCharCode((r&15)<<12|(o&63)<<6|f&63);e+=3}}}return i.join("")}function r(n,e){var t=(n&65535)+(e&65535),r=(n>>16)+(e>>16)+(t>>16);return r<<16|t&65535}function o(n,e){return n<>>32-e}function f(n,e){var t=e?"0123456789ABCDEF":"0123456789abcdef",r="",o,f=0,i=n.length;for(;f>>4&15)+t.charAt(o&15)}return r}function i(n){var e,t=n.length,r="";for(e=0;e>>8&255)}return r}function h(n){var e,t=n.length,r="";for(e=0;e>>8&255,n.charCodeAt(e)&255)}return r}function u(n){var e,t=n.length*32,r="";for(e=0;e>5]>>>24-e%32&255)}return r}function a(n){var e,t=n.length*32,r="";for(e=0;e>5]>>>e%32&255)}return r}function c(n){var e,t=n.length*8,r=Array(n.length>>2),o=r.length;for(e=0;e>5]|=(n.charCodeAt(e/8)&255)<>2),o=r.length;for(e=0;e>5]|=(n.charCodeAt(e/8)&255)<<24-e%32}return r}function D(n,e){var t=e.length,r=Array(),o,f,i,h,u,a,c,l;a=Array(Math.ceil(n.length/2));h=a.length;for(o=0;o0){u=Array();i=0;for(o=0;o0||f>0){u[u.length]=f}}r[r.length]=i;a=u}c="";for(o=r.length-1;o>=0;o--){c+=e.charAt(r[o])}l=Math.ceil(n.length*8/(Math.log(e.length)/Math.log(2)));for(o=c.length;on.length*8){r+=e}else{r+=t.charAt(h>>>6*(3-i)&63)}}}return r}n={VERSION:"1.0.6",Base64:function(){var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r="=",o=false,f=true;this.encode=function(t){var o,i,h,u="",a=t.length;r=r||"=";t=f?e(t):t;for(o=0;oa*8){u+=r}else{u+=n.charAt(h>>>6*(3-i)&63)}}}return u};this.decode=function(e){var o,i,h,u,a,c,l,D,B,C,A="",s=[];if(!e){return e}o=C=0;e=e.replace(new RegExp("\\"+r,"gi"),"");do{a=n.indexOf(e.charAt(o+=1));c=n.indexOf(e.charAt(o+=1));l=n.indexOf(e.charAt(o+=1));D=n.indexOf(e.charAt(o+=1));B=a<<18|c<<12|l<<6|D;i=B>>16&255;h=B>>8&255;u=B&255;C+=1;if(l===64){s[C]=String.fromCharCode(i)}else if(D===64){s[C]=String.fromCharCode(i,h)}else{s[C]=String.fromCharCode(i,h,u)}}while(o>>8^r}return(t^-1)>>>0},MD5:function(n){var t=n&&typeof n.uppercase==="boolean"?n.uppercase:false,i=n&&typeof n.pad==="string"?n.pad:"=",h=n&&typeof n.utf8==="boolean"?n.utf8:true;this.hex=function(n){return f(u(n,h),t)};this.b64=function(n){return B(u(n),i)};this.any=function(n,e){return D(u(n,h),e)};this.raw=function(n){return u(n,h)};this.hex_hmac=function(n,e){return f(l(n,e),t)};this.b64_hmac=function(n,e){return B(l(n,e),i)};this.any_hmac=function(n,e,t){return D(l(n,e),t)};this.vm_test=function(){return hex("abc").toLowerCase()==="900150983cd24fb0d6963f7d28e17f72"};this.setUpperCase=function(n){if(typeof n==="boolean"){t=n}return this};this.setPad=function(n){i=n||i;return this};this.setUTF8=function(n){if(typeof n==="boolean"){h=n}return this};function u(n){n=h?e(n):n;return a(C(c(n),n.length*8))}function l(n,t){var r,o,f,i,u;n=h?e(n):n;t=h?e(t):t;r=c(n);if(r.length>16){r=C(r,n.length*8)}o=Array(16),f=Array(16);for(u=0;u<16;u+=1){o[u]=r[u]^909522486;f[u]=r[u]^1549556828}i=C(o.concat(c(t)),512+t.length*8);return a(C(f.concat(i),512+128))}function C(n,e){var t,o,f,i,h,u=1732584193,a=-271733879,c=-1732584194,l=271733878;n[e>>5]|=128<>>9<<4)+14]=e;for(t=0;t16){r=C(r,n.length*8)}o=Array(16),f=Array(16);for(i=0;i<16;i+=1){o[i]=r[i]^909522486;f[i]=r[i]^1549556828}a=C(o.concat(l(t)),512+t.length*8);return u(C(f.concat(a),512+160))}function C(n,e){var t,f,i,h,u,a,c,l,D=Array(80),B=1732584193,C=-271733879,w=-1732584194,F=271733878,E=-1009589776;n[e>>5]|=128<<24-e%32;n[(e+64>>9<<4)+15]=e;for(t=0;t16){f=m(f,n.length*8)}for(;o<16;o+=1){h[o]=f[o]^909522486;a[o]=f[o]^1549556828}r=m(h.concat(l(t)),512+t.length*8);return u(m(a.concat(r),512+256))}function C(n,e){return n>>>e|n<<32-e}function A(n,e){return n>>>e}function s(n,e,t){return n&e^~n&t}function w(n,e,t){return n&e^n&t^e&t}function F(n){return C(n,2)^C(n,13)^C(n,22)}function E(n){return C(n,6)^C(n,11)^C(n,25)}function d(n){return C(n,7)^C(n,18)^A(n,3)}function g(n){return C(n,17)^C(n,19)^A(n,10)}function p(n){return C(n,28)^C(n,34)^C(n,39)}function y(n){return C(n,14)^C(n,18)^C(n,41)}function b(n){return C(n,1)^C(n,8)^A(n,7)}function v(n){return C(n,19)^C(n,61)^A(n,6)}h=[1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,-778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998];function m(n,e){var t=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225];var o=new Array(64);var f,i,u,a,c,l,D,B;var C,A,p,y;n[e>>5]|=128<<24-e%32;n[(e+64>>9<<4)+15]=e;for(C=0;C32){i=c(i,n.length*8)}for(;f<32;f+=1){h[f]=i[f]^909522486;a[f]=i[f]^1549556828}r=c(h.concat(l(t)),1024+t.length*8);return u(c(a.concat(r),1024+512))}function c(n,e){var t,r,o,f=new Array(80),h=new Array(16),u=[new C(1779033703,-205731576),new C(-1150833019,-2067093701),new C(1013904242,-23791573),new C(-1521486534,1595750129),new C(1359893119,-1377402159),new C(-1694144372,725511199),new C(528734635,-79577749),new C(1541459225,327033209)],a=new C(0,0),c=new C(0,0),l=new C(0,0),D=new C(0,0),B=new C(0,0),p=new C(0,0),y=new C(0,0),b=new C(0,0),v=new C(0,0),m=new C(0,0),x=new C(0,0),_=new C(0,0),S=new C(0,0),U=new C(0,0),j=new C(0,0),M=new C(0,0),T=new C(0,0);if(i===undefined){i=[new C(1116352408,-685199838),new C(1899447441,602891725),new C(-1245643825,-330482897),new C(-373957723,-2121671748),new C(961987163,-213338824),new C(1508970993,-1241133031),new C(-1841331548,-1357295717),new C(-1424204075,-630357736),new C(-670586216,-1560083902),new C(310598401,1164996542),new C(607225278,1323610764),new C(1426881987,-704662302),new C(1925078388,-226784913),new C(-2132889090,991336113),new C(-1680079193,633803317),new C(-1046744716,-815192428),new C(-459576895,-1628353838),new C(-272742522,944711139),new C(264347078,-1953704523),new C(604807628,2007800933),new C(770255983,1495990901),new C(1249150122,1856431235),new C(1555081692,-1119749164),new C(1996064986,-2096016459),new C(-1740746414,-295247957),new C(-1473132947,766784016),new C(-1341970488,-1728372417),new C(-1084653625,-1091629340),new C(-958395405,1034457026),new C(-710438585,-1828018395),new C(113926993,-536640913),new C(338241895,168717936),new C(666307205,1188179964),new C(773529912,1546045734),new C(1294757372,1522805485),new C(1396182291,-1651133473),new C(1695183700,-1951439906),new C(1986661051,1014477480),new C(-2117940946,1206759142),new C(-1838011259,344077627),new C(-1564481375,1290863460),new C(-1474664885,-1136513023),new C(-1035236496,-789014639),new C(-949202525,106217008),new C(-778901479,-688958952),new C(-694614492,1432725776),new C(-200395387,1467031594),new C(275423344,851169720),new C(430227734,-1194143544),new C(506948616,1363258195),new C(659060556,-544281703),new C(883997877,-509917016),new C(958139571,-976659869),new C(1322822218,-482243893),new C(1537002063,2003034995),new C(1747873779,-692930397),new C(1955562222,1575990012),new C(2024104815,1125592928),new C(-2067236844,-1578062990),new C(-1933114872,442776044),new C(-1866530822,593698344),new C(-1538233109,-561857047),new C(-1090935817,-1295615723),new C(-965641998,-479046869),new C(-903397682,-366583396),new C(-779700025,566280711),new C(-354779690,-840897762),new C(-176337025,-294727304),new C(116418474,1914138554),new C(174292421,-1563912026),new C(289380356,-1090974290),new C(460393269,320620315),new C(685471733,587496836),new C(852142971,1086792851),new C(1017036298,365543100),new C(1126000580,-1676669620),new C(1288033470,-885112138),new C(1501505948,-60457430),new C(1607167915,987167468),new C(1816402316,1246189591)]}for(r=0;r<80;r+=1){f[r]=new C(0,0)}n[e>>5]|=128<<24-(e&31);n[(e+128>>10<<5)+31]=e;o=n.length;for(r=0;r>>t|e.h<<32-t;n.h=e.h>>>t|e.l<<32-t}function w(n,e,t){n.l=e.h>>>t|e.l<<32-t;n.h=e.l>>>t|e.h<<32-t}function F(n,e,t){n.l=e.l>>>t|e.h<<32-t;n.h=e.h>>>t}function E(n,e,t){var r=(e.l&65535)+(t.l&65535);var o=(e.l>>>16)+(t.l>>>16)+(r>>>16);var f=(e.h&65535)+(t.h&65535)+(o>>>16);var i=(e.h>>>16)+(t.h>>>16)+(f>>>16);n.l=r&65535|o<<16;n.h=f&65535|i<<16}function d(n,e,t,r,o){var f=(e.l&65535)+(t.l&65535)+(r.l&65535)+(o.l&65535);var i=(e.l>>>16)+(t.l>>>16)+(r.l>>>16)+(o.l>>>16)+(f>>>16);var h=(e.h&65535)+(t.h&65535)+(r.h&65535)+(o.h&65535)+(i>>>16);var u=(e.h>>>16)+(t.h>>>16)+(r.h>>>16)+(o.h>>>16)+(h>>>16);n.l=f&65535|i<<16;n.h=h&65535|u<<16}function g(n,e,t,r,o,f){var i=(e.l&65535)+(t.l&65535)+(r.l&65535)+(o.l&65535)+(f.l&65535),h=(e.l>>>16)+(t.l>>>16)+(r.l>>>16)+(o.l>>>16)+(f.l>>>16)+(i>>>16),u=(e.h&65535)+(t.h&65535)+(r.h&65535)+(o.h&65535)+(f.h&65535)+(h>>>16),a=(e.h>>>16)+(t.h>>>16)+(r.h>>>16)+(o.h>>>16)+(f.h>>>16)+(u>>>16);n.l=i&65535|h<<16;n.h=u&65535|a<<16}},RMD160:function(n){var t=n&&typeof n.uppercase==="boolean"?n.uppercase:false,i=n&&typeof n.pad==="string"?n.pa:"=",h=n&&typeof n.utf8==="boolean"?n.utf8:true,u=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],a=[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11],l=[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],C=[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11];this.hex=function(n){return f(A(n,h))};this.b64=function(n){return B(A(n,h),i)};this.any=function(n,e){return D(A(n,h),e)};this.raw=function(n){return A(n,h)};this.hex_hmac=function(n,e){return f(s(n,e))};this.b64_hmac=function(n,e){return B(s(n,e),i)};this.any_hmac=function(n,e,t){return D(s(n,e),t)};this.vm_test=function(){return hex("abc").toLowerCase()==="900150983cd24fb0d6963f7d28e17f72"};this.setUpperCase=function(n){if(typeof n==="boolean"){t=n}return this};this.setPad=function(n){if(typeof n!=="undefined"){i=n}return this};this.setUTF8=function(n){if(typeof n==="boolean"){h=n}return this};function A(n){n=h?e(n):n;return w(F(c(n),n.length*8))}function s(n,t){n=h?e(n):n;t=h?e(t):t;var r,o,f=c(n),i=Array(16),u=Array(16);if(f.length>16){f=F(f,n.length*8)}for(r=0;r<16;r+=1){i[r]=f[r]^909522486;u[r]=f[r]^1549556828}o=F(i.concat(c(t)),512+t.length*8);return w(F(u.concat(o),512+160))}function w(n){var e,t="",r=n.length*32;for(e=0;e>5]>>>e%32&255)}return t}function F(n,e){var t,f,i,h,c=1732584193,D=4023233417,B=2562383102,A=271733878,s=3285377520,w,F,p,y,b,v,m,x,_,S;n[e>>5]|=128<>>9<<4)+14]=e;h=n.length;for(i=0;i", 7 | "contributors": [ 8 | { 9 | "name": "C. Scott Ananian", 10 | "email": "cscott@cscott.net", 11 | "web": "http://cscott.net" 12 | } 13 | ], 14 | "engines": { 15 | "node": "*" 16 | }, 17 | "main": "./hashes.js", 18 | "types": "./hashes.d.ts", 19 | "bin": { 20 | "hashes": "./bin/hashes" 21 | }, 22 | "licenses": [ 23 | { 24 | "type": "New BSD", 25 | "url": "http://github.com/h2non/jshashes/raw/master/LICENSE" 26 | } 27 | ], 28 | "directories": { 29 | "test": "test" 30 | }, 31 | "scripts": { 32 | "test": "mocha" 33 | }, 34 | "devDependencies": { 35 | "mocha": "~1.9.0", 36 | "uglify-js": "~3.7.6" 37 | }, 38 | "keywords": [ 39 | "hash", 40 | "md5", 41 | "sha1", 42 | "sha256", 43 | "hashes", 44 | "sha512", 45 | "RIPEMD", 46 | "base64", 47 | "hmac", 48 | "crc", 49 | "encoding", 50 | "algorithm" 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /test/crc32.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Test CRC32 functionality. 3 | */ 4 | var assert = require('assert'); 5 | var jsHashes = require('../'); 6 | 7 | // Test vectors from https://quickhash.com/ 8 | // This is actually what quickhash.com calls "CRC32(b)", a "variation 9 | // of CRC32, it is a 32-bit Frame Check Sequence of the formal 10 | // standard 'ITU V.42'." 11 | var testVectors = { 12 | "": 0x00000000, 13 | "a": 0xe8b7be43, 14 | "abc": 0x352441c2, 15 | "abcdefghijklmnopqrstuvwxyz": 0x4c2750bd, 16 | "message checksum": 0xf853178f, 17 | "The quick brown fox jumps over the lazy dog": 0x414fa339, 18 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": 0x1fc2e6d2 19 | }; 20 | 21 | describe('Test CRC32', function() { 22 | Object.keys(testVectors).forEach(function(data) { 23 | it('should checksum '+JSON.stringify(data)+' correctly', function() { 24 | assert.equal(jsHashes.CRC32(data), testVectors[data]); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/hashes.js: -------------------------------------------------------------------------------- 1 | /** Verify hashes. */ 2 | var assert = require('assert'); 3 | var jsHashes = require('../'); 4 | 5 | var JSH = { 6 | // new MD5 instance 7 | MD5: new jsHashes.MD5, 8 | // new SHA1 instance 9 | SHA1: new jsHashes.SHA1, 10 | // new SHA256 instance 11 | SHA256: new jsHashes.SHA256, 12 | // new SHA512 instace 13 | SHA512: new jsHashes.SHA512, 14 | // new RIPEMD-160 instace 15 | RMD160: new jsHashes.RMD160 16 | }; 17 | var testVectors = { 18 | "Hello, world!": { 19 | MD5: "6cd3556deb0da54bca060b4c39479839", 20 | SHA1: "943a702d06f34599aee1f8da8ef9f7296031d699", 21 | SHA256: "315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3", 22 | SHA512: "c1527cd893c124773d811911970c8fe6e857d6df5dc9226bd8a160614c0cd963a4ddea2b94bb7d36021ef9d865d5cea294a82dd49a0bb269f51f6e7a57f79421" 23 | }, 24 | // vectors from 25 | // http://www.ietf.org/rfc/rfc1321.txt 26 | // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA1.pdf 27 | // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf 28 | // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA512.pdf 29 | // http://homes.esat.kuleuven.be/~bosselae/ripemd160.html 30 | "": { 31 | MD5: "d41d8cd98f00b204e9800998ecf8427e", 32 | RMD160: "9c1185a5c5e9fc54612808977ee8f548b2258d31" 33 | }, 34 | "a": { 35 | MD5: "0cc175b9c0f1b6a831c399e269772661", 36 | RMD160: "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe" 37 | }, 38 | "abc": { 39 | MD5: "900150983cd24fb0d6963f7d28e17f72", 40 | SHA1: "a9993e364706816aba3e25717850c26c9cd0d89d", 41 | SHA256: "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", 42 | SHA512: "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", 43 | RMD160: "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" 44 | }, 45 | "message digest": { 46 | MD5: "f96b697d7cb7938d525a2f31aaf161d0", 47 | RMD160: "5d0689ef49d2fae572b881b123a85ffa21595f36" 48 | }, 49 | "abcdefghijklmnopqrstuvwxyz": { 50 | MD5: "c3fcd3d76192e4007dfb496cca67e13b", 51 | RMD160: "f71c27109c692c1b56bbdceb5b9d2865b3708dbc" 52 | }, 53 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq": { 54 | SHA1: "84983e441c3bd26ebaae4aa1f95129e5e54670f1", 55 | SHA256: "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1", 56 | RMD160: "12a053384a9c0c88e405a06c27dcf49ada62eb2b" 57 | }, 58 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu": { 59 | SHA512: "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" 60 | }, 61 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789": { 62 | MD5: "d174ab98d277d9f5a5611c2c9f419d9f", 63 | RMD160: "b0e20b6e3116640286ed3a87a5713079b21f5189" 64 | }, 65 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890": { 66 | MD5: "57edf4a22be3c955ac49da2e2107b67a", 67 | RMD160: "9b752e45573d4b39f4dbd3323cab82bf63326bfb" 68 | } 69 | }; 70 | 71 | Object.keys(testVectors).forEach(function(v) { 72 | describe('Test vector: '+JSON.stringify(v), function() { 73 | Object.keys(testVectors[v]).forEach(function(h) { 74 | it('should have the proper '+h+' hash', function() { 75 | var HF = new jsHashes[h]();//JSH[h] 76 | var computedHash = HF.hex(v); 77 | assert.equal(computedHash, testVectors[v][h]); 78 | }); 79 | }); 80 | }); 81 | }); 82 | -------------------------------------------------------------------------------- /test/hmac.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Test HMAC functionality. 3 | */ 4 | var assert = require('assert'); 5 | var jsHashes = require('../'); 6 | 7 | var MD5 = new jsHashes.MD5; 8 | MD5.setUTF8(false); 9 | 10 | // test vectors from http://www.ietf.org/rfc/rfc2104.txt 11 | describe('Test MD5 HMAC (rfc2104)', function() { 12 | it("should pass test vector #1", function() { 13 | var key = '\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'; 14 | assert.equal(MD5.hex_hmac(key, 'Hi There'), 15 | "9294727a3638bb1c13f48ef8158bfc9d"); 16 | }); 17 | it("should pass test vector #2", function() { 18 | assert.equal(MD5.hex_hmac("Jefe", "what do ya want for nothing?"), 19 | "750c783e6ab0b503eaa86e310a5db738"); 20 | }); 21 | it("should pass test vector #3", function() { 22 | var key = '', data = '', i; 23 | for (i=0; i<16; i++) { 24 | key += '\xAA'; 25 | } 26 | for (i=0; i<50; i++) { 27 | data += '\xDD'; 28 | } 29 | assert.equal(MD5.hex_hmac(key, data), 30 | '56be34521d144c88dbb8c733f0e8b3f6'); 31 | }); 32 | }); 33 | 34 | // test vectors from 35 | // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code 36 | // SHA512/RMD160 from https://quickhash.com/ 37 | var testVectors = [ 38 | { 39 | key: "", 40 | data: "", 41 | hmac: { 42 | MD5: "74e6f7298a9c2d168935f58c001bad88", 43 | SHA1: "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d", 44 | SHA256: "b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad", 45 | SHA512: "b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4ac6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47", 46 | RMD160: "44d86b658a3e7cbc1a2010848b53e35c917720ca" 47 | } 48 | }, 49 | { 50 | key: "key", 51 | data: "The quick brown fox jumps over the lazy dog", 52 | hmac: { 53 | MD5: "80070713463e7749b90c2dc24911e275", 54 | SHA1: "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9", 55 | SHA256: "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8", 56 | SHA512: "b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a", 57 | RMD160: "50278a77d4d7670561ab72e867383aef6ce50b3e" 58 | } 59 | }, 60 | // Test key > block size 61 | // These vectors are from https://quickhash.com/ 62 | { 63 | key: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 64 | data: "The quick brown fox jumps over the lazy dog", 65 | hmac: { 66 | MD5: "8e86bf7840bbe52ba3f45030dba9d39a", 67 | SHA1: "ee114807434bea4ab839b940286f0c3f5b4f8a11", 68 | SHA256: "359706cae34991529dbf545ed055bed283da8b7339807db6affa2ae517d8b389", 69 | SHA512: "3135e1514cd8f6b471feb6980eedd1858047dd0c1fd44b135fade32d053b9a649f6c448fb81a6f0dc77f28f7d2505cd475aea018f90ff6961bd775acf3b8daad", 70 | RMD160: "5031d8b3399e949d4a48c9fcf10ae537b7294cbb" 71 | } 72 | } 73 | ]; 74 | describe('Test HMAC (wikipedia test vectors)', function() { 75 | testVectors.forEach(function(tv) { 76 | var key = tv.key, data = tv.data; 77 | describe('key='+JSON.stringify(key)+" data="+JSON.stringify(data), function() { 78 | Object.keys(tv.hmac).forEach(function(h) { 79 | it('should have the correct HMAC_'+h, function() { 80 | var HF = new jsHashes[h](); 81 | assert.equal(HF.hex_hmac(key, data), tv.hmac[h]); 82 | }); 83 | }); 84 | }); 85 | }); 86 | }); 87 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --check-leaks 2 | --reporter spec 3 | --------------------------------------------------------------------------------