Compare commits

...
32 Commits
Author SHA1 Message Date
Yi-Cyuan Chen 9a54fb31d4 update README 2026-07-27 14:50:56 +08:00
Yi-Cyuan Chen 1559263f5b update README 2026-07-27 14:44:03 +08:00
Yi-Cyuan Chen a6d0f636aa ### Added
- Add dedicated ESM, CommonJS, Node.js, and browser distribution entry points.
- Add streaming support to the native Node.js SHA-256, SHA-224, and HMAC implementations.
- Add distribution contract tests and real browser Web Worker tests with Playwright.
- Add Node.js 16, 18, 20, 22, and 24 runtime tests against the packed npm artifact.

### Changed
- Refactor the implementation into environment-independent core and Node.js modules.
- Use the native Node.js `crypto` implementation for hashing and HMAC.
- Load the package version automatically when generating distribution banners.
- Export unminified ESM source directly and build only CommonJS and browser/minified distributions.
- Replace `expect.js`, NYC, Tiny Worker, and UglifyJS with Node.js assert, c8, Playwright, and Rollup/Terser.
- Build automatically before `npm pack` and `npm publish`.
- Throw error if update after finalize

### Removed
- Remove runtime CommonJS, AMD, Node.js, Web Worker, and ArrayBuffer environment switches from the core implementation.
- Remove legacy environment flags and obsolete compatibility polyfills.
- Remove the old generated `sha256.mjs` and `sha256.node.mjs` entry points.
2026-07-27 14:30:34 +08:00
Yi-Cyuan Chen b766562f6a upgrade js-yaml 2026-07-18 18:52:05 +08:00
Yi-Cyuan Chen 7de3689e3c update ci.yml 2026-07-18 18:24:34 +08:00
Yi-Cyuan Chen 03f78b8bb0 Set up GitHub release action / provenance #46 2026-07-18 18:14:15 +08:00
Yi-Cyuan Chen 6755b755cc fix recognize environment is node when use browserfs #53 2026-07-18 18:01:00 +08:00
Yi-Cyuan Chen 62d740ca61 Merge branch 'master' of https://github.com/emn178/js-sha256 2026-07-18 17:49:40 +08:00
36d8fc4609 fix recognize environment is node when use browserfs (#53)
Co-authored-by: zerenzhang <zerenzhang@trip.com>
2026-07-18 17:49:24 +08:00
Yi-Cyuan Chen aee5ce367e Fix uploading coverage to coveralls 2026-07-18 17:45:41 +08:00
Yi-Cyuan Chen 1b03e6b2b6 - support ESM 2026-07-18 17:41:55 +08:00
Matthew PevelerandGitHub da84f28777 Fix uploading coverage to coveralls (#52)
Signed-off-by: Matthew Peveler <matt.peveler@gmail.com>
2026-07-18 17:40:42 +08:00
Matthew PevelerandGitHub bacba8e8c6 Replace TravisCI with GHA (#51)
* Replace TravisCI with GHA

Signed-off-by: Matthew Peveler <matt.peveler@gmail.com>

* Update ci.yml

* Update ci.yml

---------

Signed-off-by: Matthew Peveler <matt.peveler@gmail.com>
2025-05-29 08:51:04 +08:00
Yi-Cyuan Chen 7912494a5a bump version 2025-05-24 15:48:47 +08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1aa1c17124 Bump serialize-javascript and mocha (#50)
Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) to 6.0.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `serialize-javascript` from 6.0.0 to 6.0.2
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.0...v6.0.2)

Updates `mocha` from 10.2.0 to 10.8.2
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v10.2.0...v10.8.2)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-version: 6.0.2
  dependency-type: indirect
- dependency-name: mocha
  dependency-version: 10.8.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-24 15:45:59 +08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
bdc011392b Bump braces from 3.0.2 to 3.0.3 (#45)
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-24 15:42:15 +08:00
Matthew PevelerandGitHub a1d21024aa Fix NodeJS check for electron renderer (#49)
Signed-off-by: Matthew Peveler <mpeveler@timescale.com>
2025-05-24 15:42:00 +08:00
Yi-Cyuan Chen 138e2e169b uncomment test 2024-01-24 12:07:37 +08:00
Yi-Cyuan Chen dbb7a10027 ### Fixed
- Generates incorrect hash in some cases #43
- dependencies and security issues. #41
2024-01-24 09:43:24 +08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
250566e984 Bump @babel/traverse from 7.21.2 to 7.23.2 (#41)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.21.2 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-24 09:41:33 +08:00
Yi-Cyuan Chen dc41862e53 add benchmark 2023-09-26 09:35:36 +08:00
Yi-Cyuan Chen c31830ad54 ## v0.10.1 / 2023-08-31
### Added
- Disable webpack polyfill.
2023-08-31 09:44:37 +08:00
Yi-Cyuan Chen f490ee426a bump bower version 2023-08-30 23:34:49 +08:00
Yi-Cyuan Chen bb8ae3a623 ## v0.10.0 / 2023-08-30
### Fixed
- Chrome bug by workaround. #40
- deprecated `new Buffer`, replace with `Buffer.from`. #34
- dependencies and security issues. #32, #36

### Changed
- TypeScript interface, secretKey can be bytes like message. #23, #25
- remove `eval` and use `require` directly. #18, #26
2023-08-30 22:58:30 +08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
16b101f040 Bump minimist, mocha and nyc (#36)
Removes [minimist](https://github.com/minimistjs/minimist). It's no longer used after updating ancestor dependencies [minimist](https://github.com/minimistjs/minimist), [mocha](https://github.com/mochajs/mocha) and [nyc](https://github.com/istanbuljs/nyc). These dependencies need to be updated together.


Removes `minimist`

Updates `mocha` from 2.3.4 to 10.2.0
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/2.3.4...v10.2.0)

Updates `nyc` from 11.3.0 to 15.1.0
- [Release notes](https://github.com/istanbuljs/nyc/releases)
- [Changelog](https://github.com/istanbuljs/nyc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/nyc/compare/v11.3.0...v15.1.0)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
- dependency-name: mocha
  dependency-type: direct:development
- dependency-name: nyc
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-27 15:02:58 +08:00
Yi-Cyuan Chen 189bb9b037 Fixed
- incorrect result when first bit is 1 of bytes.

Changed
- throw error by Error oject. #13

Added
- TypeScript interfaces. #12
2017-12-18 20:03:12 +08:00
Olegandemn178 e35c679c2b Throw Errors to improve error reporting (#13) 2017-12-13 20:49:51 +08:00
shiyuesongandemn178 bf155ab82f Added "hmac" to interface Hash. (#12) 2017-12-13 20:49:21 +08:00
Yi-Cyuan Chen 68ffecdc6e update README and travis config 2017-11-19 16:41:14 +08:00
Yi-Cyuan Chen 3204c3743e update coverage library 2017-11-19 16:36:30 +08:00
Yi-Cyuan Chen 4e5354859f Added
- support for web worker.
- typescript types. #10

Changed
- prevent webpack to require dependencies.
2017-11-19 15:15:13 +08:00
Yi-Cyuan Chen cf975dfa0c Improved performance of hBytes increment. 2017-10-31 20:33:20 +08:00
37 changed files with 3960 additions and 599 deletions
-2
View File
@@ -1,2 +0,0 @@
/node_modules/
/tests/
+85
View File
@@ -0,0 +1,85 @@
name: CI
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node 24
uses: actions/setup-node@v4
with:
node-version: 24.x
- name: Install dependencies
run: npm ci
- name: Pack npm package
run: |
mkdir -p package-artifact
npm pack --pack-destination package-artifact
- name: Upload package artifact
uses: actions/upload-artifact@v4
with:
name: package-node-24
path: package-artifact/*.tgz
if-no-files-found: error
runtime-test:
needs: build
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x, 18.x, 20.x, 22.x, 24.x]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci
- name: Download package artifact
uses: actions/download-artifact@v4
with:
name: package-node-24
path: package-artifact
- name: Extract package artifact
run: tar -xzf package-artifact/*.tgz --strip-components=1 -C .
- name: Run runtime tests
if: matrix.node-version != '24.x'
run: npm run test:runtime
- name: Run runtime tests with coverage
if: matrix.node-version == '24.x'
run: npm run test:coverage
- name: Install Chromium
if: matrix.node-version == '24.x'
run: npx playwright install --with-deps chromium
- name: Run browser Worker tests
if: matrix.node-version == '24.x'
run: npm run test:browser
- name: Upload to coveralls
if: matrix.node-version == '24.x'
uses: coverallsapp/github-action@v2
with:
file: ./coverage/lcov.info
+32
View File
@@ -0,0 +1,32 @@
name: Publish
on:
release:
types: [published]
permissions:
contents: read
id-token: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24.x
registry-url: https://registry.npmjs.org
package-manager-cache: false
- run: npm ci
- name: Verify release version
run: |
PACKAGE_VERSION=$(node -p "require('./package.json').version")
test "$GITHUB_REF_NAME" = "v$PACKAGE_VERSION"
- run: npm run build
- run: npm test
- run: npm publish
+4 -1
View File
@@ -1,2 +1,5 @@
/node_modules/ /node_modules/
/covreporter/ /coverage/
/.nyc_output/
/playwright-report/
/test-results/
+9
View File
@@ -0,0 +1,9 @@
/node_modules/
/coverage/
/.nyc_output/
/test-results/
/tests/
.covignore
.travis.yml
.npmignore
bower.json
-11
View File
@@ -1,11 +0,0 @@
language: node_js
node_js:
- "6.11.4"
- "8.6.0"
before_install:
- npm install coveralls
- npm install mocha-lcov-reporter
script: npm run-script coveralls
branches:
only:
- master
+75
View File
@@ -1,5 +1,80 @@
# Change Log # Change Log
## v1.0.0 / 2026-07-27
### Added
- Add dedicated ESM, CommonJS, Node.js, and browser distribution entry points.
- Add streaming support to the native Node.js SHA-256, SHA-224, and HMAC implementations.
- Add distribution contract tests and real browser Web Worker tests with Playwright.
- Add Node.js 16, 18, 20, 22, and 24 runtime tests against the packed npm artifact.
### Changed
- Refactor the implementation into environment-independent core and Node.js modules.
- Use the native Node.js `crypto` implementation for hashing and HMAC.
- Load the package version automatically when generating distribution banners.
- Export unminified ESM source directly and build only CommonJS and browser/minified distributions.
- Replace `expect.js`, NYC, Tiny Worker, and UglifyJS with Node.js assert, c8, Playwright, and Rollup/Terser.
- Build automatically before `npm pack` and `npm publish`.
- Throw error if update after finalize
### Removed
- Remove runtime CommonJS, AMD, Node.js, Web Worker, and ArrayBuffer environment switches from the core implementation.
- Remove legacy environment flags and obsolete compatibility polyfills.
- Remove the old generated `sha256.mjs` and `sha256.node.mjs` entry points.
## v0.12.0 / 2026-07-18
### Added
- support ESM #44
- Set up GitHub release action / provenance #46
### Fixed
- Fix uploading coverage to coveralls #52
- fix recognize environment is node when use browserfs #53
## v0.11.1 / 2025-05-24
### Fixed
- Fix NodeJS check for electron renderer #49
## v0.11.0 / 2024-01-24
### Fixed
- Generates incorrect hash in some cases #43
- dependencies and security issues. #41
## v0.10.1 / 2023-08-31
### Added
- Disable webpack polyfill.
## v0.10.0 / 2023-08-30
### Fixed
- Chrome bug by workaround. #40
- deprecated `new Buffer`, replace with `Buffer.from`. #34
- dependencies and security issues. #32, #36
### Changed
- TypeScript interface, secretKey can be bytes like message. #23, #25
- remove `eval` and use `require` directly. #18, #26
## v0.9.0 / 2017-12-18
### Fixed
- incorrect result when first bit is 1 of bytes.
### Changed
- throw error by Error oject. #13
### Added
- TypeScript interfaces. #12
## v0.8.0 / 2017-11-19
### Added
- support for web worker.
- typescript types. #10
### Changed
- prevent webpack to require dependencies.
## v0.7.1 / 2017-10-31
### Improved
- performance of hBytes increment.
## v0.7.0 / 2017-10-31 ## v0.7.0 / 2017-10-31
### Fixed ### Fixed
- incorrect result when file size >= 512M. - incorrect result when file size >= 512M.
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2014-2017 Chen, Yi-Cyuan Copyright (c) 2014-2026 Chen, Yi-Cyuan
MIT License MIT License
+54 -17
View File
@@ -1,29 +1,53 @@
# js-sha256 # js-sha256
[![Build Status](https://travis-ci.org/emn178/js-sha256.svg?branch=master)](https://travis-ci.org/emn178/js-sha256) [![CI](https://github.com/emn178/js-sha256/actions/workflows/ci.yml/badge.svg)](https://github.com/emn178/js-sha256/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/emn178/js-sha256/badge.svg?branch=master)](https://coveralls.io/r/emn178/js-sha256?branch=master) [![Coverage Status](https://coveralls.io/repos/emn178/js-sha256/badge.svg?branch=master)](https://coveralls.io/r/emn178/js-sha256?branch=master)
[![CDNJS](https://img.shields.io/cdnjs/v/js-sha256.svg)](https://cdnjs.com/libraries/js-sha256/) [![NPM](https://img.shields.io/npm/v/js-sha256)](https://www.npmjs.com/package/js-sha256)
[![NPM](https://nodei.co/npm/js-sha256.png?stars&downloads)](https://nodei.co/npm/js-sha256/) [![CDNJS](https://img.shields.io/jsdelivr/npm/hm/js-sha256)](https://www.jsdelivr.com/package/npm/js-sha256)
A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding. A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.
## Demo ## Demo
[SHA256 Online](http://emn178.github.io/online-tools/sha256.html) [SHA256 Online](https://emn178.github.io/online-tools/sha256.html)
[SHA224 Online](http://emn178.github.io/online-tools/sha224.html) [SHA224 Online](https://emn178.github.io/online-tools/sha224.html)
[SHA256 File Online](https://emn178.github.io/online-tools/sha256_checksum.html)
[SHA224 File Online](https://emn178.github.io/online-tools/sha224_checksum.html)
## Download ## Download
[Compress](https://raw.github.com/emn178/js-sha256/master/build/sha256.min.js) [Compress](https://raw.github.com/emn178/js-sha256/master/build/sha256.min.js)
[Uncompress](https://raw.github.com/emn178/js-sha256/master/src/sha256.js) [Uncompress](https://raw.github.com/emn178/js-sha256/master/build/sha256.js)
## Installation ## Installation
You can also install js-sha256 by using Bower. You can also install js-sha256 by using Bower.
bower install js-sha256 bower install js-sha256
For node.js, you can use this command to install: For Node.js, you can use this command to install:
npm install js-sha256 npm install js-sha256
## Usage ## Usage
You could use like this:
### Browser
Load the minified UMD build to expose `sha256` and `sha224` as globals:
```HTML
<script src="sha256.min.js"></script>
<script>
console.log(sha256('Message to hash'));
</script>
```
### ES Modules
```JavaScript
import { sha256, sha224 } from 'js-sha256';
```
### CommonJS
```JavaScript
const { sha256, sha224 } = require('js-sha256');
```
### API
```JavaScript ```JavaScript
sha256('Message to hash'); sha256('Message to hash');
sha224('Message to hash'); sha224('Message to hash');
@@ -48,18 +72,28 @@ var hash2 = sha256.hmac.update('key', 'Message to hash');
hash2.update('Message2 to hash'); hash2.update('Message2 to hash');
hash2.array(); hash2.array();
``` ```
If you use node.js, you should require the module first:
### Node.js
Node.js automatically uses its native `crypto` implementation with the same API:
```JavaScript ```JavaScript
var sha256 = require('js-sha256'); import { sha256, sha224 } from 'js-sha256';
const hash = sha256.create();
hash.update('Message');
hash.update(' to hash');
console.log(hash.hex());
``` ```
or
```JavaScript ### TypeScript
var sha256 = require('js-sha256').sha256; If you use TypeScript, you can import like this:
var sha224 = require('js-sha256').sha224; ```TypeScript
import { sha256, sha224 } from 'js-sha256';
``` ```
It supports AMD: ### RequireJS
The UMD browser build supports AMD:
```JavaScript ```JavaScript
require(['your/path/sha256.js'], function(sha256) { require(['your/path/sha256.min.js'], function(sha256) {
// ... // ...
}); });
``` ```
@@ -88,8 +122,11 @@ sha256.digest(''); // [227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200,
sha256.arrayBuffer(''); // ArrayBuffer sha256.arrayBuffer(''); // ArrayBuffer
``` ```
## Benchmark
[jsPerf Benchmark](https://jsperf.app/cidole/2)
## License ## License
The project is released under the [MIT license](http://www.opensource.org/licenses/MIT). The project is released under the [MIT license](https://opensource.org/license/mit/).
## Contact ## Contact
The project's website is located at https://github.com/emn178/js-sha256 The project's website is located at https://github.com/emn178/js-sha256
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "js-sha256", "name": "js-sha256",
"version": "0.7.0", "version": "1.0.0",
"main": ["src/sha256.js"], "main": ["build/sha256.js"],
"ignore": [ "ignore": [
"samples", "samples",
"tests" "tests"
+447
View File
@@ -0,0 +1,447 @@
/**
* [js-sha256]{@link https://github.com/emn178/js-sha256}
*
* @version 1.0.0
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2014-2026
* @license MIT
*/
'use strict';
var INPUT_ERROR = 'input is invalid type';
var FINALIZE_ERROR = 'finalize already called';
var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
var formatMessage = function (message) {
var type = typeof message;
if (type === 'string') {
return [message, true];
}
if (Array.isArray(message)) {
return [message, false];
}
if (ARRAY_BUFFER && message) {
if (message.constructor === ArrayBuffer) {
return [new Uint8Array(message), false];
} else if (ArrayBuffer.isView(message)) {
return [message, false];
}
}
throw new Error(INPUT_ERROR);
};
var HEX_CHARS = '0123456789abcdef'.split('');
var EXTRA = [-2147483648, 8388608, 32768, 128];
var SHIFT = [24, 16, 8, 0];
var K = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];
var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
var blocks = [];
var createOutputMethod = function (outputType, is224) {
return function (message) {
return new Sha256(is224, true).update(message)[outputType]();
};
};
var createMethod = function (is224) {
var method = createOutputMethod('hex', is224);
method.create = function () {
return new Sha256(is224);
};
method.update = function (message) {
return method.create().update(message);
};
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createOutputMethod(type, is224);
}
return method;
};
var createHmacOutputMethod = function (outputType, is224) {
return function (key, message) {
return new HmacSha256(key, is224, true).update(message)[outputType]();
};
};
var createHmacMethod = function (is224) {
var method = createHmacOutputMethod('hex', is224);
method.create = function (key) {
return new HmacSha256(key, is224);
};
method.update = function (key, message) {
return method.create(key).update(message);
};
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createHmacOutputMethod(type, is224);
}
return method;
};
function Sha256(is224, sharedMemory) {
if (sharedMemory) {
blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
this.blocks = blocks;
} else {
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
if (is224) {
this.h0 = 0xc1059ed8;
this.h1 = 0x367cd507;
this.h2 = 0x3070dd17;
this.h3 = 0xf70e5939;
this.h4 = 0xffc00b31;
this.h5 = 0x68581511;
this.h6 = 0x64f98fa7;
this.h7 = 0xbefa4fa4;
} else { // 256
this.h0 = 0x6a09e667;
this.h1 = 0xbb67ae85;
this.h2 = 0x3c6ef372;
this.h3 = 0xa54ff53a;
this.h4 = 0x510e527f;
this.h5 = 0x9b05688c;
this.h6 = 0x1f83d9ab;
this.h7 = 0x5be0cd19;
}
this.block = this.start = this.bytes = this.hBytes = 0;
this.finalized = this.hashed = false;
this.first = true;
this.is224 = is224;
}
Sha256.prototype.update = function (message) {
if (this.finalized) {
throw new Error(FINALIZE_ERROR);
}
var result = formatMessage(message);
message = result[0];
var isString = result[1];
var code, index = 0, i, length = message.length, blocks = this.blocks;
while (index < length) {
if (this.hashed) {
this.hashed = false;
blocks[0] = this.block;
this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
}
if (isString) {
for (i = this.start; index < length && i < 64; ++index) {
code = message.charCodeAt(index);
if (code < 0x80) {
blocks[i >>> 2] |= code << SHIFT[i++ & 3];
} else if (code < 0x800) {
blocks[i >>> 2] |= (0xc0 | (code >>> 6)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else if (code < 0xd800 || code >= 0xe000) {
blocks[i >>> 2] |= (0xe0 | (code >>> 12)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
blocks[i >>> 2] |= (0xf0 | (code >>> 18)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | ((code >>> 12) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
}
}
} else {
for (i = this.start; index < length && i < 64; ++index) {
blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3];
}
}
this.lastByteIndex = i;
this.bytes += i - this.start;
if (i >= 64) {
this.block = blocks[16];
this.start = i - 64;
this.hash();
this.hashed = true;
} else {
this.start = i;
}
}
if (this.bytes > 4294967295) {
this.hBytes += this.bytes / 4294967296 << 0;
this.bytes = this.bytes % 4294967296;
}
return this;
};
Sha256.prototype.finalize = function () {
if (this.finalized) {
return;
}
this.finalized = true;
var blocks = this.blocks, i = this.lastByteIndex;
blocks[16] = this.block;
blocks[i >>> 2] |= EXTRA[i & 3];
this.block = blocks[16];
if (i >= 56) {
if (!this.hashed) {
this.hash();
}
blocks[0] = this.block;
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
}
blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
blocks[15] = this.bytes << 3;
this.hash();
};
Sha256.prototype.hash = function () {
var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
for (j = 16; j < 64; ++j) {
// rightrotate
t1 = blocks[j - 15];
s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
t1 = blocks[j - 2];
s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
}
bc = b & c;
for (j = 0; j < 64; j += 4) {
if (this.first) {
if (this.is224) {
ab = 300032;
t1 = blocks[0] - 1413257819;
h = t1 - 150054599 << 0;
d = t1 + 24177077 << 0;
} else {
ab = 704751109;
t1 = blocks[0] - 210244248;
h = t1 - 1521486534 << 0;
d = t1 + 143694565 << 0;
}
this.first = false;
} else {
s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
ab = a & b;
maj = ab ^ (a & c) ^ bc;
ch = (e & f) ^ (~e & g);
t1 = h + s1 + ch + K[j] + blocks[j];
t2 = s0 + maj;
h = d + t1 << 0;
d = t1 + t2 << 0;
}
s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
da = d & a;
maj = da ^ (d & b) ^ ab;
ch = (h & e) ^ (~h & f);
t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
t2 = s0 + maj;
g = c + t1 << 0;
c = t1 + t2 << 0;
s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
cd = c & d;
maj = cd ^ (c & a) ^ da;
ch = (g & h) ^ (~g & e);
t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
t2 = s0 + maj;
f = b + t1 << 0;
b = t1 + t2 << 0;
s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
bc = b & c;
maj = bc ^ (b & d) ^ cd;
ch = (f & g) ^ (~f & h);
t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
t2 = s0 + maj;
e = a + t1 << 0;
a = t1 + t2 << 0;
this.chromeBugWorkAround = true;
}
this.h0 = this.h0 + a << 0;
this.h1 = this.h1 + b << 0;
this.h2 = this.h2 + c << 0;
this.h3 = this.h3 + d << 0;
this.h4 = this.h4 + e << 0;
this.h5 = this.h5 + f << 0;
this.h6 = this.h6 + g << 0;
this.h7 = this.h7 + h << 0;
};
Sha256.prototype.hex = function () {
this.finalize();
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
h6 = this.h6, h7 = this.h7;
var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] +
HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] +
HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] +
HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] +
HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] +
HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] +
HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] +
HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] +
HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] +
HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] +
HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] +
HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] +
HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] +
HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] +
HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] +
HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] +
HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] +
HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] +
HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] +
HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] +
HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] +
HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
if (!this.is224) {
hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] +
HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] +
HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] +
HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
}
return hex;
};
Sha256.prototype.toString = Sha256.prototype.hex;
Sha256.prototype.digest = function () {
this.finalize();
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
h6 = this.h6, h7 = this.h7;
var arr = [
(h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF,
(h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF,
(h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF,
(h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF,
(h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF,
(h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF,
(h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF
];
if (!this.is224) {
arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF);
}
return arr;
};
Sha256.prototype.array = Sha256.prototype.digest;
Sha256.prototype.arrayBuffer = function () {
this.finalize();
var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
var dataView = new DataView(buffer);
dataView.setUint32(0, this.h0);
dataView.setUint32(4, this.h1);
dataView.setUint32(8, this.h2);
dataView.setUint32(12, this.h3);
dataView.setUint32(16, this.h4);
dataView.setUint32(20, this.h5);
dataView.setUint32(24, this.h6);
if (!this.is224) {
dataView.setUint32(28, this.h7);
}
return buffer;
};
function HmacSha256(key, is224, sharedMemory) {
var i, result = formatMessage(key);
key = result[0];
if (result[1]) {
var bytes = [], length = key.length, index = 0, code;
for (i = 0; i < length; ++i) {
code = key.charCodeAt(i);
if (code < 0x80) {
bytes[index++] = code;
} else if (code < 0x800) {
bytes[index++] = (0xc0 | (code >>> 6));
bytes[index++] = (0x80 | (code & 0x3f));
} else if (code < 0xd800 || code >= 0xe000) {
bytes[index++] = (0xe0 | (code >>> 12));
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
bytes[index++] = (0x80 | (code & 0x3f));
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
bytes[index++] = (0xf0 | (code >>> 18));
bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
bytes[index++] = (0x80 | (code & 0x3f));
}
}
key = bytes;
}
if (key.length > 64) {
key = (new Sha256(is224, true)).update(key).array();
}
var oKeyPad = [], iKeyPad = [];
for (i = 0; i < 64; ++i) {
var b = key[i] || 0;
oKeyPad[i] = 0x5c ^ b;
iKeyPad[i] = 0x36 ^ b;
}
Sha256.call(this, is224, sharedMemory);
this.update(iKeyPad);
this.oKeyPad = oKeyPad;
this.inner = true;
this.sharedMemory = sharedMemory;
}
HmacSha256.prototype = new Sha256();
HmacSha256.prototype.finalize = function () {
Sha256.prototype.finalize.call(this);
if (this.inner) {
this.inner = false;
var innerHash = this.array();
Sha256.call(this, this.is224, this.sharedMemory);
this.update(this.oKeyPad);
this.update(innerHash);
Sha256.prototype.finalize.call(this);
}
};
var sha256 = createMethod();
var sha224 = createMethod(true);
sha256.sha256 = sha256;
sha256.sha224 = sha224;
sha256.hmac = createHmacMethod();
sha224.hmac = createHmacMethod(true);
module.exports = sha256;
+136 -176
View File
@@ -1,24 +1,40 @@
/** /**
* [js-sha256]{@link https://github.com/emn178/js-sha256} * [js-sha256]{@link https://github.com/emn178/js-sha256}
* *
* @version 0.7.0 * @version 1.0.0
* @author Chen, Yi-Cyuan [emn178@gmail.com] * @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2014-2017 * @copyright Chen, Yi-Cyuan 2014-2026
* @license MIT * @license MIT
*/ */
/*jslint bitwise: true */ (function (global, factory) {
(function () { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
'use strict'; typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.sha256 = factory());
})(this, (function () { 'use strict';
var INPUT_ERROR = 'input is invalid type';
var FINALIZE_ERROR = 'finalize already called';
var ERROR = 'input is invalid type';
var root = typeof window === 'object' ? window : {};
var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
if (NODE_JS) {
root = global;
}
var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports;
var AMD = typeof define === 'function' && define.amd;
var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined'; var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
var formatMessage = function (message) {
var type = typeof message;
if (type === 'string') {
return [message, true];
}
if (Array.isArray(message)) {
return [message, false];
}
if (ARRAY_BUFFER && message) {
if (message.constructor === ArrayBuffer) {
return [new Uint8Array(message), false];
} else if (ArrayBuffer.isView(message)) {
return [message, false];
}
}
throw new Error(INPUT_ERROR);
};
var HEX_CHARS = '0123456789abcdef'.split(''); var HEX_CHARS = '0123456789abcdef'.split('');
var EXTRA = [-2147483648, 8388608, 32768, 128]; var EXTRA = [-2147483648, 8388608, 32768, 128];
var SHIFT = [24, 16, 8, 0]; var SHIFT = [24, 16, 8, 0];
@@ -36,12 +52,6 @@
var blocks = []; var blocks = [];
if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) {
Array.isArray = function (obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};
}
var createOutputMethod = function (outputType, is224) { var createOutputMethod = function (outputType, is224) {
return function (message) { return function (message) {
return new Sha256(is224, true).update(message)[outputType](); return new Sha256(is224, true).update(message)[outputType]();
@@ -50,9 +60,6 @@
var createMethod = function (is224) { var createMethod = function (is224) {
var method = createOutputMethod('hex', is224); var method = createOutputMethod('hex', is224);
if (NODE_JS) {
method = nodeWrap(method, is224);
}
method.create = function () { method.create = function () {
return new Sha256(is224); return new Sha256(is224);
}; };
@@ -66,30 +73,6 @@
return method; return method;
}; };
var nodeWrap = function (method, is224) {
var crypto = require('crypto');
var Buffer = require('buffer').Buffer;
var algorithm = is224 ? 'sha224' : 'sha256';
var nodeMethod = function (message) {
if (typeof message === 'string') {
return crypto.createHash(algorithm).update(message, 'utf8').digest('hex');
} else {
if (message === null || message === undefined) {
throw ERROR;
} else if (message.constructor === ArrayBuffer) {
message = new Uint8Array(message);
}
}
if (Array.isArray(message) || ArrayBuffer.isView(message) ||
message.constructor === Buffer) {
return crypto.createHash(algorithm).update(new Buffer(message)).digest('hex');
} else {
return method(message);
}
};
return nodeMethod;
};
var createHmacOutputMethod = function (outputType, is224) { var createHmacOutputMethod = function (outputType, is224) {
return function (key, message) { return function (key, message) {
return new HmacSha256(key, is224, true).update(message)[outputType](); return new HmacSha256(key, is224, true).update(message)[outputType]();
@@ -114,9 +97,9 @@
function Sha256(is224, sharedMemory) { function Sha256(is224, sharedMemory) {
if (sharedMemory) { if (sharedMemory) {
blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
this.blocks = blocks; this.blocks = blocks;
} else { } else {
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
@@ -150,68 +133,50 @@
Sha256.prototype.update = function (message) { Sha256.prototype.update = function (message) {
if (this.finalized) { if (this.finalized) {
return; throw new Error(FINALIZE_ERROR);
} }
var notString = typeof message !== 'string'; var result = formatMessage(message);
if (notString) { message = result[0];
if (message === null || message === undefined) { var isString = result[1];
throw ERROR; var code, index = 0, i, length = message.length, blocks = this.blocks;
} else if (message.constructor === root.ArrayBuffer) {
message = new Uint8Array(message);
}
}
var length = message.length;
if (notString) {
if (typeof length !== 'number' ||
!Array.isArray(message) &&
!(ARRAY_BUFFER && ArrayBuffer.isView(message))) {
throw ERROR;
}
}
var code, index = 0, i, blocks = this.blocks;
while (index < length) { while (index < length) {
if (this.hashed) { if (this.hashed) {
this.hashed = false; this.hashed = false;
blocks[0] = this.block; blocks[0] = this.block;
blocks[16] = blocks[1] = blocks[2] = blocks[3] = this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
} }
if (notString) { if (isString) {
for (i = this.start; index < length && i < 64; ++index) {
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
}
} else {
for (i = this.start; index < length && i < 64; ++index) { for (i = this.start; index < length && i < 64; ++index) {
code = message.charCodeAt(index); code = message.charCodeAt(index);
if (code < 0x80) { if (code < 0x80) {
blocks[i >> 2] |= code << SHIFT[i++ & 3]; blocks[i >>> 2] |= code << SHIFT[i++ & 3];
} else if (code < 0x800) { } else if (code < 0x800) {
blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; blocks[i >>> 2] |= (0xc0 | (code >>> 6)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else if (code < 0xd800 || code >= 0xe000) { } else if (code < 0xd800 || code >= 0xe000) {
blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; blocks[i >>> 2] |= (0xe0 | (code >>> 12)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else { } else {
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; blocks[i >>> 2] |= (0xf0 | (code >>> 18)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; blocks[i >>> 2] |= (0x80 | ((code >>> 12) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} }
} }
} else {
for (i = this.start; index < length && i < 64; ++index) {
blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3];
}
} }
this.lastByteIndex = i; this.lastByteIndex = i;
this.bytes += i - this.start; this.bytes += i - this.start;
while (this.bytes > 4294967295) {
++this.hBytes;
this.bytes -= 4294967296;
}
if (i >= 64) { if (i >= 64) {
this.block = blocks[16]; this.block = blocks[16];
this.start = i - 64; this.start = i - 64;
@@ -221,6 +186,10 @@
this.start = i; this.start = i;
} }
} }
if (this.bytes > 4294967295) {
this.hBytes += this.bytes / 4294967296 << 0;
this.bytes = this.bytes % 4294967296;
}
return this; return this;
}; };
@@ -231,7 +200,7 @@
this.finalized = true; this.finalized = true;
var blocks = this.blocks, i = this.lastByteIndex; var blocks = this.blocks, i = this.lastByteIndex;
blocks[16] = this.block; blocks[16] = this.block;
blocks[i >> 2] |= EXTRA[i & 3]; blocks[i >>> 2] |= EXTRA[i & 3];
this.block = blocks[16]; this.block = blocks[16];
if (i >= 56) { if (i >= 56) {
if (!this.hashed) { if (!this.hashed) {
@@ -239,11 +208,11 @@
} }
blocks[0] = this.block; blocks[0] = this.block;
blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
} }
blocks[14] = this.hBytes << 3 | this.bytes >> 29; blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
blocks[15] = this.bytes << 3; blocks[15] = this.bytes << 3;
this.hash(); this.hash();
}; };
@@ -314,6 +283,7 @@
t2 = s0 + maj; t2 = s0 + maj;
e = a + t1 << 0; e = a + t1 << 0;
a = t1 + t2 << 0; a = t1 + t2 << 0;
this.chromeBugWorkAround = true;
} }
this.h0 = this.h0 + a << 0; this.h0 = this.h0 + a << 0;
@@ -332,39 +302,39 @@
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
h6 = this.h6, h7 = this.h7; h6 = this.h6, h7 = this.h7;
var hex = HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] + var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] +
HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] + HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] +
HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] + HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] +
HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] + HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] + HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] +
HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] + HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] +
HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] + HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] +
HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] + HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] + HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] +
HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] + HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] +
HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] + HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] +
HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] + HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] + HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] +
HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] + HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] +
HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] + HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] +
HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] + HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] + HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] +
HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] + HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] +
HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] + HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] +
HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] + HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] + HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] +
HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] + HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] +
HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] + HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] +
HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] + HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] + HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] +
HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] + HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] +
HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] + HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] +
HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F]; HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
if (!this.is224) { if (!this.is224) {
hex += HEX_CHARS[(h7 >> 28) & 0x0F] + HEX_CHARS[(h7 >> 24) & 0x0F] + hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] +
HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] + HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] +
HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] + HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] +
HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F]; HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
} }
return hex; return hex;
}; };
@@ -378,16 +348,16 @@
h6 = this.h6, h7 = this.h7; h6 = this.h6, h7 = this.h7;
var arr = [ var arr = [
(h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF, (h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF,
(h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF, (h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF,
(h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF, (h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF,
(h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF, (h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF,
(h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF, (h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF,
(h5 >> 24) & 0xFF, (h5 >> 16) & 0xFF, (h5 >> 8) & 0xFF, h5 & 0xFF, (h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF,
(h6 >> 24) & 0xFF, (h6 >> 16) & 0xFF, (h6 >> 8) & 0xFF, h6 & 0xFF (h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF
]; ];
if (!this.is224) { if (!this.is224) {
arr.push((h7 >> 24) & 0xFF, (h7 >> 16) & 0xFF, (h7 >> 8) & 0xFF, h7 & 0xFF); arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF);
} }
return arr; return arr;
}; };
@@ -413,39 +383,26 @@
}; };
function HmacSha256(key, is224, sharedMemory) { function HmacSha256(key, is224, sharedMemory) {
var notString = typeof key !== 'string'; var i, result = formatMessage(key);
if (notString) { key = result[0];
if (key === null || key === undefined) { if (result[1]) {
throw ERROR;
} else if (key.constructor === root.ArrayBuffer) {
key = new Uint8Array(key);
}
}
var length = key.length;
if (notString) {
if (typeof length !== 'number' ||
!Array.isArray(key) &&
!(ARRAY_BUFFER && ArrayBuffer.isView(key))) {
throw ERROR;
}
} else {
var bytes = [], length = key.length, index = 0, code; var bytes = [], length = key.length, index = 0, code;
for (var i = 0; i < length; ++i) { for (i = 0; i < length; ++i) {
code = key.charCodeAt(i); code = key.charCodeAt(i);
if (code < 0x80) { if (code < 0x80) {
bytes[index++] = code; bytes[index++] = code;
} else if (code < 0x800) { } else if (code < 0x800) {
bytes[index++] = (0xc0 | (code >> 6)); bytes[index++] = (0xc0 | (code >>> 6));
bytes[index++] = (0x80 | (code & 0x3f)); bytes[index++] = (0x80 | (code & 0x3f));
} else if (code < 0xd800 || code >= 0xe000) { } else if (code < 0xd800 || code >= 0xe000) {
bytes[index++] = (0xe0 | (code >> 12)); bytes[index++] = (0xe0 | (code >>> 12));
bytes[index++] = (0x80 | ((code >> 6) & 0x3f)); bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
bytes[index++] = (0x80 | (code & 0x3f)); bytes[index++] = (0x80 | (code & 0x3f));
} else { } else {
code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff)); code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
bytes[index++] = (0xf0 | (code >> 18)); bytes[index++] = (0xf0 | (code >>> 18));
bytes[index++] = (0x80 | ((code >> 12) & 0x3f)); bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
bytes[index++] = (0x80 | ((code >> 6) & 0x3f)); bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
bytes[index++] = (0x80 | (code & 0x3f)); bytes[index++] = (0x80 | (code & 0x3f));
} }
} }
@@ -457,7 +414,7 @@
} }
var oKeyPad = [], iKeyPad = []; var oKeyPad = [], iKeyPad = [];
for (var i = 0; i < 64; ++i) { for (i = 0; i < 64; ++i) {
var b = key[i] || 0; var b = key[i] || 0;
oKeyPad[i] = 0x5c ^ b; oKeyPad[i] = 0x5c ^ b;
iKeyPad[i] = 0x36 ^ b; iKeyPad[i] = 0x36 ^ b;
@@ -484,21 +441,24 @@
} }
}; };
var exports = createMethod(); var sha256 = createMethod();
exports.sha256 = exports; var sha224 = createMethod(true);
exports.sha224 = createMethod(true); sha256.sha256 = sha256;
exports.sha256.hmac = createHmacMethod(); sha256.sha224 = sha224;
exports.sha224.hmac = createHmacMethod(true); sha256.hmac = createHmacMethod();
sha224.hmac = createHmacMethod(true);
if (COMMON_JS) { const root =
module.exports = exports; typeof globalThis === 'object' ? globalThis :
} else { typeof self === 'object' ? self :
root.sha256 = exports.sha256; typeof window === 'object' ? window :
root.sha224 = exports.sha224; typeof global === 'object' ? global :
if (AMD) { undefined;
define(function () {
return exports; if (root) {
}); root.sha224 = sha224;
}
} }
})();
return sha256;
}));
+3 -3
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+131
View File
@@ -0,0 +1,131 @@
/**
* [js-sha256]{@link https://github.com/emn178/js-sha256}
*
* @version 1.0.0
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2014-2026
* @license MIT
*/
'use strict';
var crypto = require('crypto');
var INPUT_ERROR = 'input is invalid type';
var FINALIZE_ERROR = 'finalize already called';
var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
var formatMessage = function (message) {
var type = typeof message;
if (type === 'string') {
return [message, true];
}
if (Array.isArray(message)) {
return [message, false];
}
if (ARRAY_BUFFER && message) {
if (message.constructor === ArrayBuffer) {
return [new Uint8Array(message), false];
} else if (ArrayBuffer.isView(message)) {
return [message, false];
}
}
throw new Error(INPUT_ERROR);
};
function toNodeInput(message) {
const [ msg, isString ] = formatMessage(message);
return isString ? Buffer.from(msg, 'utf8') : Buffer.from(msg);
}
class NodeHasher {
constructor(hash) {
this.hash = hash;
this.result = undefined;
}
update(message) {
if (this.result) {
throw new Error(FINALIZE_ERROR);
}
this.hash.update(toNodeInput(message));
return this;
}
finalize() {
if (!this.result) {
this.result = this.hash.digest();
this.hash = undefined;
}
}
hex() {
this.finalize();
return this.result.toString('hex');
}
toString() {
return this.hex();
}
array() {
this.finalize();
return Array.from(this.result);
}
digest() {
return this.array();
}
arrayBuffer() {
return Uint8Array.from(this.array()).buffer;
}
}
function addOutputMethods(method, createHasher) {
method.hex = method;
method.array = function (...args) {
return createHasher(...args.slice(0, -1)).update(args[args.length - 1]).array();
};
method.digest = method.array;
method.arrayBuffer = function (...args) {
return createHasher(...args.slice(0, -1)).update(args[args.length - 1]).arrayBuffer();
};
return method;
}
function createNodeMethod(algorithm) {
const createHasher = () => new NodeHasher(crypto.createHash(algorithm));
const method = function (message) {
return createHasher().update(message).hex();
};
addOutputMethods(method, createHasher);
method.create = createHasher;
method.update = function (message) {
return method.create().update(message);
};
return method;
}
function createNodeHmacMethod(algorithm) {
const createHasher = key => new NodeHasher(crypto.createHmac(algorithm, toNodeInput(key)));
const method = function (key, message) {
return createHasher(key).update(message).hex();
};
addOutputMethods(method, createHasher);
method.create = createHasher;
method.update = function (key, message) {
return method.create(key).update(message);
};
return method;
}
const sha256 = createNodeMethod('sha256');
const sha224 = createNodeMethod('sha224');
sha256.sha256 = sha256;
sha256.sha224 = sha224;
sha256.hmac = createNodeHmacMethod('sha256');
sha224.hmac = createNodeHmacMethod('sha224');
module.exports = sha256;
Vendored
+150
View File
@@ -0,0 +1,150 @@
type Message = string | number[] | ArrayBuffer | Uint8Array;
interface Hasher {
/**
* Update hash
*
* @param message The message you want to hash.
*/
update(message: Message): Hasher;
/**
* Return hash in hex string.
*/
hex(): string;
/**
* Return hash in hex string.
*/
toString(): string;
/**
* Return hash in ArrayBuffer.
*/
arrayBuffer(): ArrayBuffer;
/**
* Return hash in integer array.
*/
digest(): number[];
/**
* Return hash in integer array.
*/
array(): number[];
}
interface Hmac {
/**
* Computes a Hash-based message authentication code (HMAC) using a secret key
*
* @param secretKey The Secret Key
* @param message The message you want to hash.
*/
(secretKey: Message, message: Message): string;
/**
* Create a hash object using a secret key.
*
* @param secretKey The Secret Key
*/
create(secretKey: Message): Hasher;
/**
* Create a hash object and hash message using a secret key
*
* @param secretKey The Secret Key
* @param message The message you want to hash.
*/
update(secretKey: Message, message: Message): Hasher;
/**
* Return hash in hex string.
*
* @param secretKey The Secret Key
* @param message The message you want to hash.
*/
hex(secretKey: Message, message: Message): string;
/**
* Return hash in ArrayBuffer.
*
* @param secretKey The Secret Key
* @param message The message you want to hash.
*/
arrayBuffer(secretKey: Message, message: Message): ArrayBuffer;
/**
* Return hash in integer array.
*
* @param secretKey The Secret Key
* @param message The message you want to hash.
*/
digest(secretKey: Message, message: Message): number[];
/**
* Return hash in integer array.
*
* @param secretKey The Secret Key
* @param message The message you want to hash.
*/
array(secretKey: Message, message: Message): number[];
}
interface Hash {
/**
* Hash and return hex string.
*
* @param message The message you want to hash.
*/
(message: Message): string;
/**
* Create a hash object.
*/
create(): Hasher;
/**
* Create a hash object and hash message.
*
* @param message The message you want to hash.
*/
update(message: Message): Hasher;
/**
* Return hash in hex string.
*
* @param message The message you want to hash.
*/
hex(message: Message): string;
/**
* Return hash in ArrayBuffer.
*
* @param message The message you want to hash.
*/
arrayBuffer(message: Message): ArrayBuffer;
/**
* Return hash in integer array.
*
* @param message The message you want to hash.
*/
digest(message: Message): number[];
/**
* Return hash in integer array.
*
* @param message The message you want to hash.
*/
array(message: Message): number[];
/**
* HMAC interface
*/
hmac: Hmac;
}
export var sha256: Hash;
export var sha224: Hash;
export default sha256;
+1852 -235
View File
File diff suppressed because it is too large Load Diff
+38 -11
View File
@@ -1,19 +1,45 @@
{ {
"name": "js-sha256", "name": "js-sha256",
"version": "0.7.0", "version": "1.0.0",
"description": "A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.", "description": "A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.",
"main": "src/sha256.js", "main": "build/sha256.node.cjs",
"module": "src/index.mjs",
"exports": {
".": {
"types": "./index.d.ts",
"node": {
"import": "./src/node.mjs",
"require": "./build/sha256.node.cjs"
},
"import": "./src/index.mjs",
"require": "./build/sha256.cjs",
"default": "./src/index.mjs"
},
"./src/sha256.js": "./build/sha256.js",
"./build/sha256.js": "./build/sha256.js",
"./build/sha256.cjs": "./build/sha256.cjs",
"./build/sha256.min.js": "./build/sha256.min.js",
"./build/sha256.min.mjs": "./build/sha256.min.mjs",
"./build/sha256.node.cjs": "./build/sha256.node.cjs",
"./package.json": "./package.json"
},
"types": "./index.d.ts",
"devDependencies": { "devDependencies": {
"expect.js": "~0.3.1", "@playwright/test": "^1.62.0",
"jscoverage": "~0.5.9", "@rollup/plugin-terser": "^1.0.0",
"mocha": "~2.3.4", "c8": "^8.0.1",
"uglifyjs": "~2.4.10" "mocha": "~10.8.2",
"rollup": "^4.43.0"
}, },
"scripts": { "scripts": {
"test": "mocha tests/node-test.js -r jscoverage", "test": "npm run build && npm run test:coverage",
"report": "mocha tests/node-test.js -r jscoverage --covout=html", "test:unit": "mocha tests/core-test.mjs && mocha tests/node-test.mjs",
"coveralls": "mocha tests/node-test.js -R mocha-lcov-reporter -r jscoverage | coveralls", "test:dist": "node tests/dist-test.mjs",
"build": "uglifyjs src/sha256.js --compress --mangle --comments --output build/sha256.min.js" "test:runtime": "npm run test:unit && npm run test:dist",
"test:coverage": "c8 --all --include=src/shared.mjs --include=src/core.mjs --include=src/node.mjs --reporter=text --reporter=html --reporter=lcov npm run test:runtime",
"test:browser": "playwright test",
"build": "rollup -c",
"prepack": "npm run build"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@@ -34,5 +60,6 @@
"homepage": "https://github.com/emn178/js-sha256", "homepage": "https://github.com/emn178/js-sha256",
"bugs": { "bugs": {
"url": "https://github.com/emn178/js-sha256/issues" "url": "https://github.com/emn178/js-sha256/issues"
} },
"browser": "build/sha256.cjs"
} }
+9
View File
@@ -0,0 +1,9 @@
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests/browser',
use: {
browserName: 'chromium',
headless: true
}
});
+69
View File
@@ -0,0 +1,69 @@
import { readFileSync } from 'fs';
import terser from '@rollup/plugin-terser';
const { version } = JSON.parse(
readFileSync(new URL('package.json', import.meta.url), 'utf8')
);
const banner = `/**
* [js-sha256]{@link https://github.com/emn178/js-sha256}
*
* @version ${version}
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2014-2026
* @license MIT
*/`;
export default [
{
input: 'src/cjs.mjs',
output: {
banner,
exports: 'default',
file: 'build/sha256.cjs',
format: 'cjs'
}
},
{
input: 'src/umd.mjs',
output: {
banner,
exports: 'default',
file: 'build/sha256.js',
format: 'umd',
name: 'sha256'
}
},
{
external: ['crypto'],
input: 'src/node-cjs.mjs',
output: {
banner,
exports: 'default',
file: 'build/sha256.node.cjs',
format: 'cjs'
}
},
{
input: 'src/umd.mjs',
output: [
{
banner,
exports: 'default',
file: 'build/sha256.min.js',
format: 'umd',
name: 'sha256',
plugins: [terser()]
}
]
},
{
input: 'src/index.mjs',
output: {
banner,
file: 'build/sha256.min.mjs',
format: 'es',
plugins: [terser()]
}
}
];
+1
View File
@@ -0,0 +1 @@
export { default } from './core.mjs';
+417
View File
@@ -0,0 +1,417 @@
import { FINALIZE_ERROR, formatMessage } from './shared.mjs';
var HEX_CHARS = '0123456789abcdef'.split('');
var EXTRA = [-2147483648, 8388608, 32768, 128];
var SHIFT = [24, 16, 8, 0];
var K = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];
var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
var blocks = [];
var createOutputMethod = function (outputType, is224) {
return function (message) {
return new Sha256(is224, true).update(message)[outputType]();
};
};
var createMethod = function (is224) {
var method = createOutputMethod('hex', is224);
method.create = function () {
return new Sha256(is224);
};
method.update = function (message) {
return method.create().update(message);
};
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createOutputMethod(type, is224);
}
return method;
};
var createHmacOutputMethod = function (outputType, is224) {
return function (key, message) {
return new HmacSha256(key, is224, true).update(message)[outputType]();
};
};
var createHmacMethod = function (is224) {
var method = createHmacOutputMethod('hex', is224);
method.create = function (key) {
return new HmacSha256(key, is224);
};
method.update = function (key, message) {
return method.create(key).update(message);
};
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createHmacOutputMethod(type, is224);
}
return method;
};
function Sha256(is224, sharedMemory) {
if (sharedMemory) {
blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
this.blocks = blocks;
} else {
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
if (is224) {
this.h0 = 0xc1059ed8;
this.h1 = 0x367cd507;
this.h2 = 0x3070dd17;
this.h3 = 0xf70e5939;
this.h4 = 0xffc00b31;
this.h5 = 0x68581511;
this.h6 = 0x64f98fa7;
this.h7 = 0xbefa4fa4;
} else { // 256
this.h0 = 0x6a09e667;
this.h1 = 0xbb67ae85;
this.h2 = 0x3c6ef372;
this.h3 = 0xa54ff53a;
this.h4 = 0x510e527f;
this.h5 = 0x9b05688c;
this.h6 = 0x1f83d9ab;
this.h7 = 0x5be0cd19;
}
this.block = this.start = this.bytes = this.hBytes = 0;
this.finalized = this.hashed = false;
this.first = true;
this.is224 = is224;
}
Sha256.prototype.update = function (message) {
if (this.finalized) {
throw new Error(FINALIZE_ERROR);
}
var result = formatMessage(message);
message = result[0];
var isString = result[1];
var code, index = 0, i, length = message.length, blocks = this.blocks;
while (index < length) {
if (this.hashed) {
this.hashed = false;
blocks[0] = this.block;
this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
}
if (isString) {
for (i = this.start; index < length && i < 64; ++index) {
code = message.charCodeAt(index);
if (code < 0x80) {
blocks[i >>> 2] |= code << SHIFT[i++ & 3];
} else if (code < 0x800) {
blocks[i >>> 2] |= (0xc0 | (code >>> 6)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else if (code < 0xd800 || code >= 0xe000) {
blocks[i >>> 2] |= (0xe0 | (code >>> 12)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
blocks[i >>> 2] |= (0xf0 | (code >>> 18)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | ((code >>> 12) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
}
}
} else {
for (i = this.start; index < length && i < 64; ++index) {
blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3];
}
}
this.lastByteIndex = i;
this.bytes += i - this.start;
if (i >= 64) {
this.block = blocks[16];
this.start = i - 64;
this.hash();
this.hashed = true;
} else {
this.start = i;
}
}
if (this.bytes > 4294967295) {
this.hBytes += this.bytes / 4294967296 << 0;
this.bytes = this.bytes % 4294967296;
}
return this;
};
Sha256.prototype.finalize = function () {
if (this.finalized) {
return;
}
this.finalized = true;
var blocks = this.blocks, i = this.lastByteIndex;
blocks[16] = this.block;
blocks[i >>> 2] |= EXTRA[i & 3];
this.block = blocks[16];
if (i >= 56) {
if (!this.hashed) {
this.hash();
}
blocks[0] = this.block;
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
}
blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
blocks[15] = this.bytes << 3;
this.hash();
};
Sha256.prototype.hash = function () {
var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
for (j = 16; j < 64; ++j) {
// rightrotate
t1 = blocks[j - 15];
s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
t1 = blocks[j - 2];
s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
}
bc = b & c;
for (j = 0; j < 64; j += 4) {
if (this.first) {
if (this.is224) {
ab = 300032;
t1 = blocks[0] - 1413257819;
h = t1 - 150054599 << 0;
d = t1 + 24177077 << 0;
} else {
ab = 704751109;
t1 = blocks[0] - 210244248;
h = t1 - 1521486534 << 0;
d = t1 + 143694565 << 0;
}
this.first = false;
} else {
s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
ab = a & b;
maj = ab ^ (a & c) ^ bc;
ch = (e & f) ^ (~e & g);
t1 = h + s1 + ch + K[j] + blocks[j];
t2 = s0 + maj;
h = d + t1 << 0;
d = t1 + t2 << 0;
}
s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
da = d & a;
maj = da ^ (d & b) ^ ab;
ch = (h & e) ^ (~h & f);
t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
t2 = s0 + maj;
g = c + t1 << 0;
c = t1 + t2 << 0;
s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
cd = c & d;
maj = cd ^ (c & a) ^ da;
ch = (g & h) ^ (~g & e);
t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
t2 = s0 + maj;
f = b + t1 << 0;
b = t1 + t2 << 0;
s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
bc = b & c;
maj = bc ^ (b & d) ^ cd;
ch = (f & g) ^ (~f & h);
t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
t2 = s0 + maj;
e = a + t1 << 0;
a = t1 + t2 << 0;
this.chromeBugWorkAround = true;
}
this.h0 = this.h0 + a << 0;
this.h1 = this.h1 + b << 0;
this.h2 = this.h2 + c << 0;
this.h3 = this.h3 + d << 0;
this.h4 = this.h4 + e << 0;
this.h5 = this.h5 + f << 0;
this.h6 = this.h6 + g << 0;
this.h7 = this.h7 + h << 0;
};
Sha256.prototype.hex = function () {
this.finalize();
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
h6 = this.h6, h7 = this.h7;
var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] +
HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] +
HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] +
HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] +
HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] +
HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] +
HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] +
HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] +
HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] +
HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] +
HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] +
HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] +
HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] +
HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] +
HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] +
HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] +
HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] +
HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] +
HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] +
HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] +
HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] +
HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
if (!this.is224) {
hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] +
HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] +
HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] +
HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
}
return hex;
};
Sha256.prototype.toString = Sha256.prototype.hex;
Sha256.prototype.digest = function () {
this.finalize();
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
h6 = this.h6, h7 = this.h7;
var arr = [
(h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF,
(h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF,
(h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF,
(h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF,
(h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF,
(h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF,
(h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF
];
if (!this.is224) {
arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF);
}
return arr;
};
Sha256.prototype.array = Sha256.prototype.digest;
Sha256.prototype.arrayBuffer = function () {
this.finalize();
var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
var dataView = new DataView(buffer);
dataView.setUint32(0, this.h0);
dataView.setUint32(4, this.h1);
dataView.setUint32(8, this.h2);
dataView.setUint32(12, this.h3);
dataView.setUint32(16, this.h4);
dataView.setUint32(20, this.h5);
dataView.setUint32(24, this.h6);
if (!this.is224) {
dataView.setUint32(28, this.h7);
}
return buffer;
};
function HmacSha256(key, is224, sharedMemory) {
var i, result = formatMessage(key);
key = result[0];
if (result[1]) {
var bytes = [], length = key.length, index = 0, code;
for (i = 0; i < length; ++i) {
code = key.charCodeAt(i);
if (code < 0x80) {
bytes[index++] = code;
} else if (code < 0x800) {
bytes[index++] = (0xc0 | (code >>> 6));
bytes[index++] = (0x80 | (code & 0x3f));
} else if (code < 0xd800 || code >= 0xe000) {
bytes[index++] = (0xe0 | (code >>> 12));
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
bytes[index++] = (0x80 | (code & 0x3f));
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
bytes[index++] = (0xf0 | (code >>> 18));
bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
bytes[index++] = (0x80 | (code & 0x3f));
}
}
key = bytes;
}
if (key.length > 64) {
key = (new Sha256(is224, true)).update(key).array();
}
var oKeyPad = [], iKeyPad = [];
for (i = 0; i < 64; ++i) {
var b = key[i] || 0;
oKeyPad[i] = 0x5c ^ b;
iKeyPad[i] = 0x36 ^ b;
}
Sha256.call(this, is224, sharedMemory);
this.update(iKeyPad);
this.oKeyPad = oKeyPad;
this.inner = true;
this.sharedMemory = sharedMemory;
}
HmacSha256.prototype = new Sha256();
HmacSha256.prototype.finalize = function () {
Sha256.prototype.finalize.call(this);
if (this.inner) {
this.inner = false;
var innerHash = this.array();
Sha256.call(this, this.is224, this.sharedMemory);
this.update(this.oKeyPad);
this.update(innerHash);
Sha256.prototype.finalize.call(this);
}
};
var sha256 = createMethod();
var sha224 = createMethod(true);
sha256.sha256 = sha256;
sha256.sha224 = sha224;
sha256.hmac = createHmacMethod();
sha224.hmac = createHmacMethod(true);
export { sha256, sha224 };
export default sha256;
+1
View File
@@ -0,0 +1 @@
export { default, sha224, sha256 } from './core.mjs';
+1
View File
@@ -0,0 +1 @@
export { default } from './node.mjs';
+100
View File
@@ -0,0 +1,100 @@
import { createHash, createHmac } from 'crypto';
import { FINALIZE_ERROR, formatMessage } from './shared.mjs';
function toNodeInput(message) {
const [ msg, isString ] = formatMessage(message);
return isString ? Buffer.from(msg, 'utf8') : Buffer.from(msg);
}
class NodeHasher {
constructor(hash) {
this.hash = hash;
this.result = undefined;
}
update(message) {
if (this.result) {
throw new Error(FINALIZE_ERROR);
}
this.hash.update(toNodeInput(message));
return this;
}
finalize() {
if (!this.result) {
this.result = this.hash.digest();
this.hash = undefined;
}
}
hex() {
this.finalize();
return this.result.toString('hex');
}
toString() {
return this.hex();
}
array() {
this.finalize();
return Array.from(this.result);
}
digest() {
return this.array();
}
arrayBuffer() {
return Uint8Array.from(this.array()).buffer;
}
}
function addOutputMethods(method, createHasher) {
method.hex = method;
method.array = function (...args) {
return createHasher(...args.slice(0, -1)).update(args[args.length - 1]).array();
};
method.digest = method.array;
method.arrayBuffer = function (...args) {
return createHasher(...args.slice(0, -1)).update(args[args.length - 1]).arrayBuffer();
};
return method;
}
function createNodeMethod(algorithm) {
const createHasher = () => new NodeHasher(createHash(algorithm));
const method = function (message) {
return createHasher().update(message).hex();
};
addOutputMethods(method, createHasher);
method.create = createHasher;
method.update = function (message) {
return method.create().update(message);
};
return method;
}
function createNodeHmacMethod(algorithm) {
const createHasher = key => new NodeHasher(createHmac(algorithm, toNodeInput(key)));
const method = function (key, message) {
return createHasher(key).update(message).hex();
};
addOutputMethods(method, createHasher);
method.create = createHasher;
method.update = function (key, message) {
return method.create(key).update(message);
};
return method;
}
const sha256 = createNodeMethod('sha256');
const sha224 = createNodeMethod('sha224');
sha256.sha256 = sha256;
sha256.sha224 = sha224;
sha256.hmac = createNodeHmacMethod('sha256');
sha224.hmac = createNodeHmacMethod('sha224');
export { sha256, sha224 };
export default sha256;
+22
View File
@@ -0,0 +1,22 @@
export var INPUT_ERROR = 'input is invalid type';
export var FINALIZE_ERROR = 'finalize already called';
var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
export var formatMessage = function (message) {
var type = typeof message;
if (type === 'string') {
return [message, true];
}
if (Array.isArray(message)) {
return [message, false];
}
if (ARRAY_BUFFER && message) {
if (message.constructor === ArrayBuffer) {
return [new Uint8Array(message), false];
} else if (ArrayBuffer.isView(message)) {
return [message, false];
}
}
throw new Error(INPUT_ERROR);
}
+14
View File
@@ -0,0 +1,14 @@
import sha256, { sha224 } from './core.mjs';
const root =
typeof globalThis === 'object' ? globalThis :
typeof self === 'object' ? self :
typeof window === 'object' ? window :
typeof global === 'object' ? global :
undefined;
if (root) {
root.sha224 = sha224;
}
export default sha256;
+5
View File
@@ -0,0 +1,5 @@
importScripts('/build/sha256.min.js');
self.onmessage = function (event) {
self.postMessage(sha256(event.data));
};
+5
View File
@@ -0,0 +1,5 @@
import { sha256 } from '../../src/index.mjs';
self.onmessage = function (event) {
self.postMessage(sha256(event.data));
};
+95
View File
@@ -0,0 +1,95 @@
import { test, expect } from '@playwright/test';
import { createReadStream } from 'node:fs';
import { stat } from 'node:fs/promises';
import { createServer } from 'node:http';
import { extname, join, normalize } from 'node:path';
import { fileURLToPath } from 'node:url';
const root = fileURLToPath(new URL('../..', import.meta.url));
const contentTypes = {
'.js': 'text/javascript',
'.mjs': 'text/javascript'
};
let server;
let origin;
test.beforeAll(async () => {
server = createServer(async (request, response) => {
if (request.url === '/') {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.end('<!doctype html><title>js-sha256 worker test</title>');
return;
}
const path = normalize(join(root, decodeURIComponent(request.url)));
if (!path.startsWith(root)) {
response.writeHead(403);
response.end();
return;
}
try {
await stat(path);
response.writeHead(200, {
'Content-Type': contentTypes[extname(path)] || 'application/octet-stream'
});
createReadStream(path).pipe(response);
} catch {
response.writeHead(404);
response.end();
}
});
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const address = server.address();
origin = `http://127.0.0.1:${address.port}`;
});
test.afterAll(async () => {
await new Promise((resolve, reject) => {
server.close(error => error ? reject(error) : resolve());
});
});
async function hashInWorker(page, workerPath, options) {
return page.evaluate(({ workerPath, options }) => new Promise((resolve, reject) => {
const worker = new Worker(workerPath, options);
const timeout = setTimeout(() => {
worker.terminate();
reject(new Error('Worker timed out'));
}, 5000);
worker.onmessage = event => {
clearTimeout(timeout);
worker.terminate();
resolve(event.data);
};
worker.onerror = event => {
clearTimeout(timeout);
worker.terminate();
reject(new Error(event.message));
};
worker.postMessage('abc');
}), { workerPath, options });
}
test('classic Worker loads the minified UMD build', async ({ page }) => {
await page.goto(origin);
const hash = await hashInWorker(page, '/tests/browser/classic-worker.js');
expect(hash).toBe(
'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
);
});
test('module Worker imports the ESM source entry', async ({ page }) => {
await page.goto(origin);
const hash = await hashInWorker(
page,
'/tests/browser/module-worker.mjs',
{ type: 'module' }
);
expect(hash).toBe(
'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
);
});
+10
View File
@@ -0,0 +1,10 @@
import assert from 'node:assert/strict';
import { sha224, sha256 } from '../src/core.mjs';
globalThis.assert = assert;
globalThis.sha256 = sha256;
globalThis.sha224 = sha224;
globalThis.TEST_INTERNALS = true;
await import('./test.js');
await import('./hmac-test.js');
+87
View File
@@ -0,0 +1,87 @@
import assert from 'node:assert/strict';
import { createRequire } from 'node:module';
import { readFile } from 'node:fs/promises';
import vm from 'node:vm';
import packageSha256, {
sha224 as packageSha224,
sha256 as namedPackageSha256
} from 'js-sha256';
import browserSha256, {
sha224 as browserSha224
} from '../src/index.mjs';
const require = createRequire(import.meta.url);
const commonJs = require('../build/sha256.cjs');
const nodeCommonJs = require('js-sha256');
const SHA256_ABC = 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad';
const SHA224_ABC = '23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7';
const HMAC_ABC = '9c196e32dc0175f86f4b1cb89289d6619de6bee699e4c378e68309ed97a1a6ab';
function testContract(name, sha256, sha224) {
assert.equal(sha256('abc'), SHA256_ABC, `${name}: SHA-256`);
assert.equal(sha224('abc'), SHA224_ABC, `${name}: SHA-224`);
assert.equal(sha256.hmac('key', 'abc'), HMAC_ABC, `${name}: HMAC`);
assert.equal(sha256.update('a').update('bc').hex(), SHA256_ABC, `${name}: streaming`);
assert.equal(sha256([97, 98, 99]), SHA256_ABC, `${name}: array`);
assert.equal(sha256(new Uint8Array([97, 98, 99])), SHA256_ABC, `${name}: typed array`);
assert.equal(sha256.sha256, sha256, `${name}: sha256 property`);
assert.equal(sha256.sha224, sha224, `${name}: sha224 property`);
}
function testStreamingOutputs(name, algorithm, expected) {
const hasher = algorithm.create().update('a').update('bc');
assert.equal(hasher.hex(), expected, `${name}: hex`);
assert.equal(hasher.toString(), expected, `${name}: toString`);
assert.deepEqual(hasher.array(), Array.from(Buffer.from(expected, 'hex')), `${name}: array`);
assert.deepEqual(hasher.digest(), hasher.array(), `${name}: digest`);
assert.equal(
Buffer.from(hasher.arrayBuffer()).toString('hex'),
expected,
`${name}: arrayBuffer`
);
assert.equal(hasher.hex(), expected, `${name}: repeated output`);
}
function testHmacStreamingOutputs(name, hmac) {
const hasher = hmac.create('key').update('a').update('bc');
assert.equal(hasher.hex(), HMAC_ABC, `${name}: hex`);
assert.equal(hasher.toString(), HMAC_ABC, `${name}: toString`);
assert.deepEqual(hasher.array(), Array.from(Buffer.from(HMAC_ABC, 'hex')), `${name}: array`);
assert.deepEqual(hasher.digest(), hasher.array(), `${name}: digest`);
assert.equal(
Buffer.from(hasher.arrayBuffer()).toString('hex'),
HMAC_ABC,
`${name}: arrayBuffer`
);
assert.equal(hasher.hex(), HMAC_ABC, `${name}: repeated output`);
}
testContract('package ESM', packageSha256, packageSha224);
assert.equal(namedPackageSha256, packageSha256);
testStreamingOutputs('package ESM SHA-256 streaming', packageSha256, SHA256_ABC);
testStreamingOutputs('package ESM SHA-224 streaming', packageSha224, SHA224_ABC);
testHmacStreamingOutputs('package ESM HMAC streaming', packageSha256.hmac);
testContract('browser ESM', browserSha256, browserSha224);
testContract('generic CommonJS', commonJs, commonJs.sha224);
testContract('package CommonJS', nodeCommonJs, nodeCommonJs.sha224);
testStreamingOutputs('package CommonJS SHA-256 streaming', nodeCommonJs, SHA256_ABC);
testStreamingOutputs('package CommonJS SHA-224 streaming', nodeCommonJs.sha224, SHA224_ABC);
testHmacStreamingOutputs('package CommonJS HMAC streaming', nodeCommonJs.hmac);
const umdCode = await readFile(new URL('../build/sha256.min.js', import.meta.url), 'utf8');
const browserContext = vm.createContext({});
vm.runInContext(umdCode, browserContext);
testContract('browser UMD', browserContext.sha256, browserContext.sha224);
let amdSha256;
const amdContext = vm.createContext({
define(factory) {
amdSha256 = factory();
}
});
amdContext.define.amd = true;
vm.runInContext(umdCode, amdContext);
testContract('AMD', amdSha256, amdSha256.sha224);
console.log('Distribution contracts: PASS');
+29 -17
View File
@@ -41,12 +41,6 @@
'865cc329d317f6d9fdbd183a3c5cc5fd4c370d11f98abbbb404bceb1e6392c7e': ['中文', '中文'], '865cc329d317f6d9fdbd183a3c5cc5fd4c370d11f98abbbb404bceb1e6392c7e': ['中文', '中文'],
'efeef87be5731506b69bb64a9898a456dd12c94834c36a4d8ba99e3db79ad7ed': ['aécio', 'aécio'], 'efeef87be5731506b69bb64a9898a456dd12c94834c36a4d8ba99e3db79ad7ed': ['aécio', 'aécio'],
'8a6e527049b9cfc7e1c84bcf356a1289c95da68a586c03de3327f3de0d3737fe': ['𠜎', '𠜎'] '8a6e527049b9cfc7e1c84bcf356a1289c95da68a586c03de3327f3de0d3737fe': ['𠜎', '𠜎']
},
'ArrayBuffer': {
'e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b': [
new ArrayBuffer(0),
'Hi There'
]
} }
}, },
sha224_hmac: { sha224_hmac: {
@@ -80,16 +74,35 @@
'e2280928fe813aeb7fa59aa14dd5e589041bfdf91945d19d25b9f3db': ['中文', '中文'], 'e2280928fe813aeb7fa59aa14dd5e589041bfdf91945d19d25b9f3db': ['中文', '中文'],
'86c53dc054b16f6e006a254891bc9ff0da5df8e1a6faee3b0aaa732d': ['aécio', 'aécio'], '86c53dc054b16f6e006a254891bc9ff0da5df8e1a6faee3b0aaa732d': ['aécio', 'aécio'],
'e9e5991bfb84506b105f800afac1599ff807bb8e20db8ffda48997b9': ['𠜎', '𠜎'] 'e9e5991bfb84506b105f800afac1599ff807bb8e20db8ffda48997b9': ['𠜎', '𠜎']
},
'ArrayBuffer': {
'da8f94de91d62154b55ea4e8d6eb133f6d553bcd1f1ba205b9488945': [
new ArrayBuffer(0),
'Hi There'
]
} }
} }
}; };
testCases.sha256_hmac.Uint8Array = {
'e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b': [
new Uint8Array(0),
'Hi There'
]
};
testCases.sha256_hmac.ArrayBuffer = {
'e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b': [
new ArrayBuffer(0),
'Hi There'
]
};
testCases.sha224_hmac.Uint8Array = {
'da8f94de91d62154b55ea4e8d6eb133f6d553bcd1f1ba205b9488945': [
new ArrayBuffer(0),
'Hi There'
]
};
testCases.sha224_hmac.ArrayBuffer = {
'da8f94de91d62154b55ea4e8d6eb133f6d553bcd1f1ba205b9488945': [
new ArrayBuffer(0),
'Hi There'
]
};
var errorTestCases = [null, undefined, { length: 0 }, 0, 1, false, true, NaN, Infinity, function () {}]; var errorTestCases = [null, undefined, { length: 0 }, 0, 1, false, true, NaN, Infinity, function () {}];
function runTestCases(name, algorithm) { function runTestCases(name, algorithm) {
@@ -164,7 +177,6 @@
call: function (key, message) { call: function (key, message) {
var hash = algorithm.update(key, message); var hash = algorithm.update(key, message);
hash.hex(); hash.hex();
hash.update(message);
return hash.hex(); return hash.hex();
} }
} }
@@ -182,7 +194,7 @@
for (var hash in testCase) { for (var hash in testCase) {
(function (message, hash) { (function (message, hash) {
it('should be equal', function () { it('should be equal', function () {
expect(method.call(message[0], message[1])).to.be(hash); assert.equal(method.call(message[0], message[1]), hash);
}); });
})(testCase[hash], hash); })(testCase[hash], hash);
} }
@@ -201,7 +213,7 @@
for (var hash in testCase) { for (var hash in testCase) {
(function (message, hash) { (function (message, hash) {
it('should be equal', function () { it('should be equal', function () {
expect(method.call(message[0], message[1])).to.be(hash); assert.equal(method.call(message[0], message[1]), hash);
}); });
})(testCase[hash], hash); })(testCase[hash], hash);
} }
@@ -215,9 +227,9 @@
errorTestCases.forEach(function (testCase) { errorTestCases.forEach(function (testCase) {
context('when ' + testCase, function () { context('when ' + testCase, function () {
it('should throw error', function () { it('should throw error', function () {
expect(function () { assert.throws(function () {
algorithm(testCase, ''); algorithm(testCase, '');
}).to.throwError(/input is invalid type/); }, /input is invalid type/);
}); });
}); });
}); });
-23
View File
@@ -1,23 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SHA256</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
<script src="../src/sha256.js"></script>
</head>
<body>
<div id="mocha"></div>
<script>
mocha.setup('bdd');
</script>
<script src="test.js"></script>
<script src="hmac-test.js"></script>
<script>
mocha.checkLeaks();
mocha.run();
</script>
</body>
</html>
-54
View File
@@ -1,54 +0,0 @@
// Node.js env
expect = require('expect.js');
sha256 = require('../src/sha256.js').sha256;
sha224 = require('../src/sha256.js').sha224;
require('./test.js');
require('./hmac-test.js');
delete require.cache[require.resolve('../src/sha256.js')]
delete require.cache[require.resolve('./test.js')]
delete require.cache[require.resolve('./hmac-test.js')]
sha256 = null;
sha224 = null;
// Webpack browser env
JS_SHA256_NO_NODE_JS = true;
window = global;
sha256 = require('../src/sha256.js').sha256;
sha224 = require('../src/sha256.js').sha224;
require('./test.js');
require('./hmac-test.js');
delete require.cache[require.resolve('../src/sha256.js')]
delete require.cache[require.resolve('./test.js')]
delete require.cache[require.resolve('./hmac-test.js')]
sha256 = null;
sha224 = null;
// browser env
JS_SHA256_NO_NODE_JS = true;
JS_SHA256_NO_COMMON_JS = true;
window = global;
require('../src/sha256.js');
require('./test.js');
require('./hmac-test.js');
delete require.cache[require.resolve('../src/sha256.js')]
delete require.cache[require.resolve('./test.js')]
delete require.cache[require.resolve('./hmac-test.js')]
sha256 = null;
sha224 = null;
// browser AMD
JS_SHA256_NO_NODE_JS = true;
JS_SHA256_NO_COMMON_JS = true;
window = global;
define = function (func) {
sha256 = func();
sha224 = sha256.sha224;
require('./test.js');
require('./hmac-test.js');
};
define.amd = true;
require('../src/sha256.js');
+10
View File
@@ -0,0 +1,10 @@
import assert from 'node:assert/strict';
import { sha224, sha256 } from 'js-sha256';
globalThis.assert = assert;
globalThis.sha256 = sha256;
globalThis.sha224 = sha224;
globalThis.TEST_INTERNALS = false;
await import('./test.js');
await import('./hmac-test.js');
+57 -46
View File
@@ -22,7 +22,8 @@
'UTF8': { 'UTF8': {
'72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21': '中文', '72726d8818f693066ceb69afa364218b692e62ea92b385782363780f47529c21': '中文',
'53196d1acfce0c4b264e01e8018c989d571351f59e33f055f76ff15b4f0516c6': 'aécio', '53196d1acfce0c4b264e01e8018c989d571351f59e33f055f76ff15b4f0516c6': 'aécio',
'8d10a48685dbc34484696de7ea7434d80a54c1d60100530faccf697463ef19c9': '𠜎' '8d10a48685dbc34484696de7ea7434d80a54c1d60100530faccf697463ef19c9': '𠜎',
'2c731ad02e3d0e3c863bdbce4cce221e0be1d31efffdd8e1455a835e8287dc33': 'Tehtäväsi on muotoilla teksti, jossa käyttäjälle suositellaan hänen henkilökohtaisiin tietoihinsa perustuen avioehdon tekemistä. Suosittelemme nimenomaan tätä tuotetta käyttäjän henkilökohtaisista tiedoista johtuen. Tuottamasi tekstin tulee olla lyhyt, persoonallinen, ymmärrettävä ja todenmukainen. Suositus perustuu seuraaviin seikkoihin:\n\nSeikka 0: Avioehdon tekeminen on verohyötyjen vuoksi suositeltavaa, koska olet ilmaissut että haluat kuoleman tapauksessa turvata ensisijaisesti aviopuolisosi asemaa (ennemmin kuin lasten asemaa). Avioehdolla voit määrätä, että puolet kuolleen puolison omaisuudesta siirtyy verovapaasti leskelle.\n\nVoit halutessasi hyödyntää seuraavia tietoja tekstin muotoilussa persoonallisemmaksi: Käyttäjällä on kumppani nimeltä PARTNER_NAME. Käyttäjällä on suurperhe. Käyttäjällä on lapsiperhe.\n\nPuhuttele käyttäjää siihen sävyyn että tiedät jo mitä käyttäjä haluaa, koska hän on kertonut toiveistaan, ja niiden perusteella tehty suositus on ilmiselvä. Joten älä käytä epävarmoja ilmaisuja kuten "halutessasi", vaan kirjoita itsevarmoilla ilmaisuilla kuten "koska haluat". Älä tee oletuksia käyttäjän sukupuolesta, emme tiedä onko hän mies vai nainen. Älä käytä sanaa jälkikasvu, puhu ennemmin lapsesta tai lapsista riippuen onko lapsia yksi vai useampia. Älä puhuttele käyttäjää ensimmäisessä persoonassa, käytä ennemmin passiivimuotoa. Tekstin sävyn tulisi olla neutraalin asiallinen, ei melodramaattinen eikä leikkisä. Pysy totuudessa, älä keksi uusia seikkoja yllä listattujen lisäksi. Viittaa ihmisiin nimillä silloin kun se on mahdollista. Tekstin tulisi olla vain muutaman lauseen mittainen. Älä siis kirjoita pitkiä selityksiä äläkä kirjoita listoja. Tiivistä oleellinen tieto lyhyeksi ja persoonalliseksi tekstiksi.'
}, },
'UTF8 more than 64 bytes': { 'UTF8 more than 64 bytes': {
'd691014feebf35b3500ef6f6738d0094cac63628a7a018a980a40292a77703d1': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一', 'd691014feebf35b3500ef6f6738d0094cac63628a7a018a980a40292a77703d1': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一',
@@ -40,18 +41,6 @@
'182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': [211, 212], '182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': [211, 212],
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103],
'74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841': [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] '74b51c6911f9a8b5e7c499effe7604e43b672166818873c27752c248de434841': [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55]
},
'Uint8Array': {
'182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': new Uint8Array([211, 212]),
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
},
'Int8Array': {
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
},
'ArrayBuffer': {
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': new ArrayBuffer(0),
'6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d': new ArrayBuffer(1),
} }
}, },
sha224: { sha224: {
@@ -66,7 +55,8 @@
'UTF8': { 'UTF8': {
'dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4': '中文', 'dfbab71afdf54388af4d55f8bd3de8c9b15e0eb916bf9125f4a959d4': '中文',
'd12841cafd89c534924a839e62bf35a2b5f3717b7802eb19bd8d8e15': 'aécio', 'd12841cafd89c534924a839e62bf35a2b5f3717b7802eb19bd8d8e15': 'aécio',
'eaa0129b5509f5701db218fb7076b282e4409da52d06363aa3bdd63d': '𠜎' 'eaa0129b5509f5701db218fb7076b282e4409da52d06363aa3bdd63d': '𠜎',
'b19e948e39752eb064452abbaecac72e17ce2a028d640a8864e92c36': 'Tehtäväsi on muotoilla teksti, jossa käyttäjälle suositellaan hänen henkilökohtaisiin tietoihinsa perustuen avioehdon tekemistä. Suosittelemme nimenomaan tätä tuotetta käyttäjän henkilökohtaisista tiedoista johtuen. Tuottamasi tekstin tulee olla lyhyt, persoonallinen, ymmärrettävä ja todenmukainen. Suositus perustuu seuraaviin seikkoihin:\n\nSeikka 0: Avioehdon tekeminen on verohyötyjen vuoksi suositeltavaa, koska olet ilmaissut että haluat kuoleman tapauksessa turvata ensisijaisesti aviopuolisosi asemaa (ennemmin kuin lasten asemaa). Avioehdolla voit määrätä, että puolet kuolleen puolison omaisuudesta siirtyy verovapaasti leskelle.\n\nVoit halutessasi hyödyntää seuraavia tietoja tekstin muotoilussa persoonallisemmaksi: Käyttäjällä on kumppani nimeltä PARTNER_NAME. Käyttäjällä on suurperhe. Käyttäjällä on lapsiperhe.\n\nPuhuttele käyttäjää siihen sävyyn että tiedät jo mitä käyttäjä haluaa, koska hän on kertonut toiveistaan, ja niiden perusteella tehty suositus on ilmiselvä. Joten älä käytä epävarmoja ilmaisuja kuten "halutessasi", vaan kirjoita itsevarmoilla ilmaisuilla kuten "koska haluat". Älä tee oletuksia käyttäjän sukupuolesta, emme tiedä onko hän mies vai nainen. Älä käytä sanaa jälkikasvu, puhu ennemmin lapsesta tai lapsista riippuen onko lapsia yksi vai useampia. Älä puhuttele käyttäjää ensimmäisessä persoonassa, käytä ennemmin passiivimuotoa. Tekstin sävyn tulisi olla neutraalin asiallinen, ei melodramaattinen eikä leikkisä. Pysy totuudessa, älä keksi uusia seikkoja yllä listattujen lisäksi. Viittaa ihmisiin nimillä silloin kun se on mahdollista. Tekstin tulisi olla vain muutaman lauseen mittainen. Älä siis kirjoita pitkiä selityksiä äläkä kirjoita listoja. Tiivistä oleellinen tieto lyhyeksi ja persoonalliseksi tekstiksi.'
}, },
'UTF8 more than 64 bytes': { 'UTF8 more than 64 bytes': {
'0dda421f3f81272418e1313673e9d74b7f2d04efc9c52c69458e12c3': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一', '0dda421f3f81272418e1313673e9d74b7f2d04efc9c52c69458e12c3': '訊息摘要演算法第五版(英語:Message-Digest Algorithm 5,縮寫為MD5),是當前電腦領域用於確保資訊傳輸完整一致而廣泛使用的雜湊演算法之一',
@@ -83,33 +73,43 @@
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': [], 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': [],
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103], '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103],
'16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8': [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55] '16ee1b101fe0e0d8dd156d598931ec19d75b0f8dc0a0455733c168c8': [48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55, 56, 48, 49, 50, 51, 52, 53, 54, 55]
},
'Uint8Array': {
'e17541396a3ecd1cd5a2b968b84e597e8eae3b0ea3127963bf48dd3b': new Uint8Array([211, 212]),
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
},
'Int8Array': {
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
},
'ArrayBuffer': {
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': new ArrayBuffer(0),
'fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073': new ArrayBuffer(1),
} }
} }
}; };
var errorTestCases = [null, undefined, { length: 0 }, 0, 1, false, true, NaN, Infinity, function () {}]; testCases.sha256.Uint8Array = {
'182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': new Uint8Array([211, 212]),
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
};
testCases.sha256.Int8Array = {
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
};
testCases.sha256.ArrayBuffer = {
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': new ArrayBuffer(0),
'6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d': new ArrayBuffer(1)
};
testCases.sha224.Uint8Array = {
'e17541396a3ecd1cd5a2b968b84e597e8eae3b0ea3127963bf48dd3b': new Uint8Array([211, 212]),
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
};
testCases.sha224.Int8Array = {
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Int8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])
};
testCases.sha224.ArrayBuffer = {
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': new ArrayBuffer(0),
'fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073': new ArrayBuffer(1),
};
if (typeof process == 'object') { testCases.sha256.Buffer = {
testCases.sha256['Buffer'] = { 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': Buffer.from([]),
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': new Buffer(0), 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': Buffer.from(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]))
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': new Buffer(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])) };
}; testCases.sha224.Buffer = {
testCases.sha224['Buffer'] = { 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': Buffer.from([]),
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': new Buffer(0), '730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': Buffer.from(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]))
'730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525': new Buffer(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])) };
};
} var errorTestCases = [null, undefined, { length: 0 }, 0, 1, false, true, NaN, Infinity, function () {}];
function runTestCases(name, algorithm) { function runTestCases(name, algorithm) {
var methods = [ var methods = [
@@ -183,7 +183,6 @@
call: function (message) { call: function (message) {
var hash = algorithm.update(message); var hash = algorithm.update(message);
hash.hex(); hash.hex();
hash.update(message);
return hash.hex(); return hash.hex();
} }
} }
@@ -201,7 +200,7 @@
for (var hash in testCase) { for (var hash in testCase) {
(function (message, hash) { (function (message, hash) {
it('should be equal', function () { it('should be equal', function () {
expect(method.call(message)).to.be(hash); assert.equal(method.call(message), hash);
}); });
})(testCase[hash], hash); })(testCase[hash], hash);
} }
@@ -220,7 +219,7 @@
for (var hash in testCase) { for (var hash in testCase) {
(function (message, hash) { (function (message, hash) {
it('should be equal', function () { it('should be equal', function () {
expect(method.call(message)).to.be(hash); assert.equal(method.call(message), hash);
}); });
})(testCase[hash], hash); })(testCase[hash], hash);
} }
@@ -234,19 +233,31 @@
errorTestCases.forEach(function (testCase) { errorTestCases.forEach(function (testCase) {
context('when ' + testCase, function () { context('when ' + testCase, function () {
it('should throw error', function () { it('should throw error', function () {
expect(function () { assert.throws(function () {
algorithm(testCase); algorithm(testCase);
}).to.throwError(/input is invalid type/); }, /input is invalid type/);
}); });
}); });
}); });
context('when large size', function () { context('when update after finalize', function () {
var hash = algorithm.create(); it('should throw error', function () {
hash.bytes = 4294967295; assert.throws(function () {
hash.update('any'); var hash = algorithm.update('any');
expect(hash.hBytes).to.be(1); hash.hex();
hash.update('any');
}, /finalize already called/);
});
}); });
if (TEST_INTERNALS) {
context('when large size', function () {
var hash = algorithm.create();
hash.bytes = 4294967295;
hash.update('any');
assert.equal(hash.hBytes, 1);
});
}
}); });
}); });
} }