Compare commits

..
Author SHA1 Message Date
dependabot[bot]andGitHub 86932642aa Bump picomatch from 2.3.1 to 2.3.2
Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-27 06:31:49 +00: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
39 changed files with 3123 additions and 1936 deletions
+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
+2
View File
@@ -1,3 +1,5 @@
/node_modules/ /node_modules/
/coverage/ /coverage/
/.nyc_output/ /.nyc_output/
/playwright-report/
/test-results/
+1
View File
@@ -1,6 +1,7 @@
/node_modules/ /node_modules/
/coverage/ /coverage/
/.nyc_output/ /.nyc_output/
/test-results/
/tests/ /tests/
.covignore .covignore
.travis.yml .travis.yml
-10
View File
@@ -1,10 +0,0 @@
language: node_js
node_js:
- "6.11.4"
- "8.6.0"
before_install:
- npm install coveralls
after_success: npm run coveralls
branches:
only:
- master
+30
View File
@@ -1,5 +1,35 @@
# 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 ## v0.11.1 / 2025-05-24
### Fixed ### Fixed
- Fix NodeJS check for electron renderer #49 - Fix NodeJS check for electron renderer #49
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2014-2025 Chen, Yi-Cyuan Copyright (c) 2014-2026 Chen, Yi-Cyuan
MIT License MIT License
+38 -18
View File
@@ -1,5 +1,5 @@
# 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/) [![CDNJS](https://img.shields.io/cdnjs/v/js-sha256.svg)](https://cdnjs.com/libraries/js-sha256/)
[![NPM](https://nodei.co/npm/js-sha256.png?stars&downloads)](https://nodei.co/npm/js-sha256/) [![NPM](https://nodei.co/npm/js-sha256.png?stars&downloads)](https://nodei.co/npm/js-sha256/)
@@ -9,23 +9,45 @@ A simple SHA-256 / SHA-224 hash function for JavaScript supports UTF-8 encoding.
[SHA256 Online](https://emn178.github.io/online-tools/sha256.html) [SHA256 Online](https://emn178.github.io/online-tools/sha256.html)
[SHA224 Online](https://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) [SHA256 File Online](https://emn178.github.io/online-tools/sha256_checksum.html)
[SHA225 File Online](https://emn178.github.io/online-tools/sha224_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 = require('js-sha256');
const { sha224 } = sha256;
```
### API
```JavaScript ```JavaScript
sha256('Message to hash'); sha256('Message to hash');
sha224('Message to hash'); sha224('Message to hash');
@@ -52,28 +74,26 @@ hash2.array();
``` ```
### Node.js ### Node.js
If you use node.js, you should require the module first: 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';
```
or const hash = sha256.create();
```JavaScript hash.update('Message');
var sha256 = require('js-sha256').sha256; hash.update(' to hash');
var sha224 = require('js-sha256').sha224; console.log(hash.hex());
```
or
```JavaScript
const { sha256, sha224 } = require('js-sha256');
``` ```
### TypeScript ### TypeScript
If you use TypeScript, you can import like this: If you use TypeScript, you can import like this:
```TypeScript ```TypeScript
import { sha256, sha224 } from 'js-sha256'; import { sha256, sha224 } from 'js-sha256';
``` ```
### RequireJS ### RequireJS
It supports AMD: The UMD browser build supports AMD:
```JavaScript ```JavaScript
require(['your/path/sha256.js'], function(sha256) { require(['your/path/sha256.min.js'], function(sha256) {
// ... // ...
}); });
``` ```
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "js-sha256", "name": "js-sha256",
"version": "0.11.1", "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;
+59 -121
View File
@@ -1,31 +1,40 @@
/** /**
* [js-sha256]{@link https://github.com/emn178/js-sha256} * [js-sha256]{@link https://github.com/emn178/js-sha256}
* *
* @version 0.11.1 * @version 1.0.0
* @author Chen, Yi-Cyuan [emn178@gmail.com] * @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2014-2025 * @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 ERROR = 'input is invalid type'; var INPUT_ERROR = 'input is invalid type';
var WINDOW = typeof window === 'object'; var FINALIZE_ERROR = 'finalize already called';
var root = WINDOW ? window : {};
if (root.JS_SHA256_NO_WINDOW) { var ARRAY_BUFFER = typeof ArrayBuffer !== 'undefined';
WINDOW = false;
var formatMessage = function (message) {
var type = typeof message;
if (type === 'string') {
return [message, true];
} }
var WEB_WORKER = !WINDOW && typeof self === 'object'; if (Array.isArray(message)) {
var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node && process.type != 'renderer'; return [message, false];
if (NODE_JS) {
root = global;
} else if (WEB_WORKER) {
root = self;
} }
var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports; if (ARRAY_BUFFER && message) {
var AMD = typeof define === 'function' && define.amd; if (message.constructor === ArrayBuffer) {
var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined'; 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];
@@ -43,18 +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]';
};
}
if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
ArrayBuffer.isView = function (obj) {
return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
};
}
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]();
@@ -63,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);
}; };
@@ -79,38 +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 bufferFrom;
if (Buffer.from && !root.JS_SHA256_NO_BUFFER_FROM) {
bufferFrom = Buffer.from;
} else {
bufferFrom = function (message) {
return new Buffer(message);
};
}
var nodeMethod = function (message) {
if (typeof message === 'string') {
return crypto.createHash(algorithm).update(message, 'utf8').digest('hex');
} else {
if (message === null || message === undefined) {
throw new Error(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(bufferFrom(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]();
@@ -171,25 +133,11 @@
Sha256.prototype.update = function (message) { Sha256.prototype.update = function (message) {
if (this.finalized) { if (this.finalized) {
return; throw new Error(FINALIZE_ERROR);
}
var notString, type = typeof message;
if (type !== 'string') {
if (type === 'object') {
if (message === null) {
throw new Error(ERROR);
} else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
message = new Uint8Array(message);
} else if (!Array.isArray(message)) {
if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
throw new Error(ERROR);
}
}
} else {
throw new Error(ERROR);
}
notString = true;
} }
var result = formatMessage(message);
message = result[0];
var isString = result[1];
var code, index = 0, i, length = message.length, blocks = this.blocks; var code, index = 0, i, length = message.length, blocks = this.blocks;
while (index < length) { while (index < length) {
if (this.hashed) { if (this.hashed) {
@@ -201,11 +149,7 @@
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) {
@@ -225,6 +169,10 @@
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;
@@ -435,8 +383,9 @@
}; };
function HmacSha256(key, is224, sharedMemory) { function HmacSha256(key, is224, sharedMemory) {
var i, type = typeof key; var i, result = formatMessage(key);
if (type === 'string') { key = result[0];
if (result[1]) {
var bytes = [], length = key.length, index = 0, code; var bytes = [], length = key.length, index = 0, code;
for (i = 0; i < length; ++i) { for (i = 0; i < length; ++i) {
code = key.charCodeAt(i); code = key.charCodeAt(i);
@@ -458,20 +407,6 @@
} }
} }
key = bytes; key = bytes;
} else {
if (type === 'object') {
if (key === null) {
throw new Error(ERROR);
} else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) {
key = new Uint8Array(key);
} else if (!Array.isArray(key)) {
if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) {
throw new Error(ERROR);
}
}
} else {
throw new Error(ERROR);
}
} }
if (key.length > 64) { if (key.length > 64) {
@@ -506,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
+1
View File
@@ -147,3 +147,4 @@ interface Hash {
export var sha256: Hash; export var sha256: Hash;
export var sha224: Hash; export var sha224: Hash;
export default sha256;
+1286 -1450
View File
File diff suppressed because it is too large Load Diff
+36 -19
View File
@@ -1,20 +1,45 @@
{ {
"name": "js-sha256", "name": "js-sha256",
"version": "0.11.1", "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",
"@rollup/plugin-terser": "^1.0.0",
"c8": "^8.0.1",
"mocha": "~10.8.2", "mocha": "~10.8.2",
"nyc": "^15.1.0", "rollup": "^4.43.0"
"tiny-worker": "^2.3.0",
"uglify-js": "^3.1.9"
}, },
"scripts": { "scripts": {
"test": "nyc mocha tests/node-test.js", "test": "npm run build && npm run test:coverage",
"report": "nyc --reporter=html --reporter=text mocha tests/node-test.js", "test:unit": "mocha tests/core-test.mjs && mocha tests/node-test.mjs",
"coveralls": "nyc report --reporter=text-lcov | coveralls", "test:dist": "node tests/dist-test.mjs",
"build": "uglifyjs src/sha256.js -c -m eval --comments -o 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",
@@ -36,13 +61,5 @@
"bugs": { "bugs": {
"url": "https://github.com/emn178/js-sha256/issues" "url": "https://github.com/emn178/js-sha256/issues"
}, },
"nyc": { "browser": "build/sha256.cjs"
"exclude": [
"tests"
]
},
"browser": {
"crypto": false,
"buffer": false
}
} }
+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');
+4 -7
View File
@@ -78,7 +78,6 @@
} }
}; };
if (!(typeof JS_SHA256_NO_ARRAY_BUFFER === 'boolean' && JS_SHA256_NO_ARRAY_BUFFER)) {
testCases.sha256_hmac.Uint8Array = { testCases.sha256_hmac.Uint8Array = {
'e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b': [ 'e48411262715c8370cd5e7bf8e82bef53bd53712d007f3429351843b77c7bb9b': [
new Uint8Array(0), new Uint8Array(0),
@@ -103,7 +102,6 @@
'Hi There' '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 () {}];
@@ -179,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();
} }
} }
@@ -197,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);
} }
@@ -216,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);
} }
@@ -230,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>
-117
View File
@@ -1,117 +0,0 @@
expect = require('expect.js');
Worker = require("tiny-worker");
function unset() {
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;
BUFFER = undefined;
JS_SHA256_NO_WINDOW = undefined;
JS_SHA256_NO_NODE_JS = undefined;
JS_SHA256_NO_COMMON_JS = undefined;
JS_SHA256_NO_ARRAY_BUFFER = undefined;
JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW = undefined;
window = undefined;
}
function requireToGlobal() {
sha256 = require('../src/sha256.js').sha256;
sha224 = require('../src/sha256.js').sha224;
}
function runCommonJsTest() {
requireToGlobal();
require('./test.js');
require('./hmac-test.js');
unset();
}
function runWindowTest() {
window = global;
require('../src/sha256.js');
require('./test.js');
require('./hmac-test.js');
unset();
}
// Node.js env
BUFFER = true;
runCommonJsTest();
// Node.js env, no Buffer.from
JS_SHA256_NO_BUFFER_FROM = true
runCommonJsTest();
// Webpack browser env
JS_SHA256_NO_NODE_JS = true;
window = global;
runCommonJsTest();
// browser env
JS_SHA256_NO_NODE_JS = true;
JS_SHA256_NO_COMMON_JS = true;
runWindowTest();
// browser env and no array buffer
JS_SHA256_NO_NODE_JS = true;
JS_SHA256_NO_COMMON_JS = true;
JS_SHA256_NO_ARRAY_BUFFER = true;
runWindowTest();
// browser env and no isView
JS_SHA256_NO_NODE_JS = true;
JS_SHA256_NO_COMMON_JS = true;
JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW = true;
runWindowTest();
// browser AMD
JS_SHA256_NO_NODE_JS = true;
JS_SHA256_NO_COMMON_JS = true;
JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW = false;
window = global;
define = function (func) {
sha256 = func();
sha224 = sha256.sha224;
require('./test.js');
require('./hmac-test.js');
};
define.amd = true;
require('../src/sha256.js');
unset();
// webworker
WORKER = 'tests/worker.js';
SOURCE = 'src/sha256.js';
require('./worker-test.js');
delete require.cache[require.resolve('./worker-test.js')];
// cover webworker
JS_SHA256_NO_WINDOW = true;
JS_SHA256_NO_NODE_JS = true;
WORKER = './worker.js';
SOURCE = '../src/sha256.js';
window = global;
self = global;
Worker = function (file) {
require(file);
currentWorker = this;
this.postMessage = function (data) {
onmessage({data: data});
};
}
postMessage = function (data) {
currentWorker.onmessage({data: data});
}
importScripts = function () {};
requireToGlobal();
require('./worker-test.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');
+17 -10
View File
@@ -77,7 +77,6 @@
} }
}; };
if (!(typeof JS_SHA256_NO_ARRAY_BUFFER === 'boolean' && JS_SHA256_NO_ARRAY_BUFFER)) {
testCases.sha256.Uint8Array = { testCases.sha256.Uint8Array = {
'182889f925ae4e5cc37118ded6ed87f7bdc7cab5ec5e78faef2e50048999473f': new Uint8Array([211, 212]), '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]) '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])
@@ -100,9 +99,7 @@
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': new ArrayBuffer(0), 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': new ArrayBuffer(0),
'fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073': new ArrayBuffer(1), 'fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073': new ArrayBuffer(1),
}; };
}
if (typeof BUFFER === 'boolean' && BUFFER) {
testCases.sha256.Buffer = { testCases.sha256.Buffer = {
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': Buffer.from([]), 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': Buffer.from([]),
'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': 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]))
@@ -111,7 +108,6 @@
'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': Buffer.from([]), 'd14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f': Buffer.from([]),
'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': 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]))
}; };
}
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 () {}];
@@ -187,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();
} }
} }
@@ -205,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);
} }
@@ -224,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);
} }
@@ -238,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 update after finalize', function () {
it('should throw error', function () {
assert.throws(function () {
var hash = algorithm.update('any');
hash.hex();
hash.update('any');
}, /finalize already called/);
});
});
if (TEST_INTERNALS) {
context('when large size', function () { context('when large size', function () {
var hash = algorithm.create(); var hash = algorithm.create();
hash.bytes = 4294967295; hash.bytes = 4294967295;
hash.update('any'); hash.update('any');
expect(hash.hBytes).to.be(1); assert.equal(hash.hBytes, 1);
}); });
}
}); });
}); });
} }
-24
View File
@@ -1,24 +0,0 @@
(function (Worker, WORKER, SOURCE) {
var cases = {
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855': '',
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592': 'The quick brown fox jumps over the lazy dog',
'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c': 'The quick brown fox jumps over the lazy dog.'
};
describe('#sha256', function () {
Object.keys(cases).forEach(function (hash) {
it('should be equal', function (done) {
var worker = new Worker(WORKER);
worker.onmessage = function(event) {
expect(event.data).to.be(hash);
if (worker.terminate) {
worker.terminate();
}
done();
};
worker.postMessage(SOURCE);
worker.postMessage(cases[hash]);
});
});
});
})(Worker, WORKER, SOURCE);
-26
View File
@@ -1,26 +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>
WORKER = 'worker.js';
SOURCE = '../src/sha256.js';
mocha.setup('bdd');
</script>
<script src="worker-test.js"></script>
<script>
mocha.checkLeaks();
mocha.run();
</script>
<script>
</script>
</body>
</html>
-12
View File
@@ -1,12 +0,0 @@
var imported = false;
onmessage = function(e) {
if (imported) {
postMessage(sha256(e.data));
if (typeof exports !== 'undefined') {
imported = false;
}
} else {
imported = true;
importScripts(e.data);
}
}