mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
feat(std/hash): reimplement all hashes in WASM (#6292)
This commit is contained in:
parent
b8872cd303
commit
b3c72d1e45
15 changed files with 1301 additions and 43 deletions
|
@ -6,3 +6,4 @@ cli/tests/swc_syntax_error.ts
|
|||
std/**/testdata
|
||||
std/**/vendor
|
||||
std/node_modules
|
||||
std/hash/_wasm
|
||||
|
|
|
@ -6,3 +6,6 @@ members = [
|
|||
"deno_typescript",
|
||||
"test_plugin"
|
||||
]
|
||||
exclude = [
|
||||
"std/hash/_wasm"
|
||||
]
|
||||
|
|
62
cli/tests/hash.ts
Normal file
62
cli/tests/hash.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* eslint-disable @typescript-eslint/camelcase, @typescript-eslint/no-explicit-any */
|
||||
|
||||
const { args } = Deno;
|
||||
import { createHash, SupportedAlgorithm } from "../../std/hash/mod.ts";
|
||||
import { Md5 } from "../../std/hash/md5.ts";
|
||||
import { Sha1 } from "../../std/hash/sha1.ts";
|
||||
import { Sha256 } from "../../std/hash/sha256.ts";
|
||||
import { Sha512 } from "../../std/hash/sha512.ts";
|
||||
import { Sha3_224, Sha3_256, Sha3_384, Sha3_512 } from "../../std/hash/sha3.ts";
|
||||
|
||||
if (args.length < 3) Deno.exit(0);
|
||||
|
||||
const method = args[0];
|
||||
const alg = args[1];
|
||||
const inputFile = args[2];
|
||||
|
||||
function getJsHash(alg: string): any {
|
||||
switch (alg) {
|
||||
case "md5":
|
||||
return new Md5();
|
||||
case "sha1":
|
||||
return new Sha1();
|
||||
case "sha224":
|
||||
return new Sha256(true);
|
||||
case "sha256":
|
||||
return new Sha256();
|
||||
case "sha3-224":
|
||||
return new Sha3_224();
|
||||
case "sha3-256":
|
||||
return new Sha3_256();
|
||||
case "sha3-384":
|
||||
return new Sha3_384();
|
||||
case "sha3-512":
|
||||
return new Sha3_512();
|
||||
case "sha512":
|
||||
return new Sha512();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const f = Deno.openSync(inputFile, { read: true });
|
||||
const buffer = Deno.readAllSync(f);
|
||||
f.close();
|
||||
|
||||
let hash = null;
|
||||
|
||||
console.time("hash");
|
||||
if (method === "rust") {
|
||||
hash = createHash(alg as SupportedAlgorithm);
|
||||
} else if (method === "js") {
|
||||
hash = getJsHash(alg);
|
||||
}
|
||||
|
||||
if (hash === null) {
|
||||
console.log(`unknown hash: ${alg}`);
|
||||
Deno.exit(1);
|
||||
}
|
||||
|
||||
hash.update(buffer);
|
||||
hash.digest();
|
||||
console.timeEnd("hash");
|
|
@ -1,66 +1,83 @@
|
|||
# std/hash
|
||||
|
||||
## MD5
|
||||
## Usage
|
||||
|
||||
**Uses:**
|
||||
### Creating new hash instance
|
||||
|
||||
You can create a new Hasher instance by calling `createHash` defined in mod.ts.
|
||||
|
||||
```ts
|
||||
import { Md5 } from "https://deno.land/std/hash/md5.ts";
|
||||
import { createHash } from "https://deno.land/std/hash/mod.ts";
|
||||
|
||||
const md5 = new Md5();
|
||||
const md5Instance = md5.update("中文"); // return instance of `Md5`
|
||||
console.log(md5Instance instanceof Md5); // true
|
||||
console.log(md5Instance.toString()); // a7bac2239fcdcb3a067903d8077c4a07
|
||||
const hash = createHash("md5");
|
||||
// ...
|
||||
```
|
||||
|
||||
Calling `update` method, It will update internal state based on the input
|
||||
provided. Once you call `md5Instance.toString()`, it will return the
|
||||
`hash string`. You can provide format as `hash` or `base64`. The default format
|
||||
is `hex`.
|
||||
### Using hash instance
|
||||
|
||||
**sample:**
|
||||
You can use `update` method to feed data into your hash instance. Call `digest`
|
||||
method to retrive final hash value in ArrayBuffer.
|
||||
|
||||
```ts
|
||||
console.log(md5Instance.toString("base64")); // MNgWOD+FHGO3Fff/HDCY2w==
|
||||
import { createHash } from "https://deno.land/std/hash/mod.ts";
|
||||
|
||||
const hash = createHash("md5");
|
||||
hash.update("Your data here");
|
||||
const final = hash.digest(); // returns ArrayBuffer
|
||||
```
|
||||
|
||||
## SHA1
|
||||
|
||||
**Uses:**
|
||||
|
||||
Creating `sha1` hash is simple. You can use `Sha1` class instance and update the
|
||||
digest. Calling `hex` method will return the sha1 in hex value. You can also use
|
||||
`toString` method.
|
||||
Please note that `digest` invalidates the hash instance's internal state.
|
||||
Calling `digest` more than once will throw an Error.
|
||||
|
||||
```ts
|
||||
import { Sha1 } from "https://deno.land/std/hash/sha1.ts";
|
||||
import { createHash } from "https://deno.land/std/hash/mod.ts";
|
||||
|
||||
const sha1 = new Sha1().update("中文");
|
||||
console.log(sha1.hex()); // 7be2d2d20c106eee0836c9bc2b939890a78e8fb3
|
||||
console.log(sha1.toString()); // same as above
|
||||
const hash = createHash("md5");
|
||||
hash.update("Your data here");
|
||||
const final1 = hash.digest(); // returns ArrayBuffer
|
||||
const final2 = hash.digest(); // throws Error
|
||||
```
|
||||
|
||||
## Sha256 and HmacSha256
|
||||
If you need final hash in string formats, call `toString` method with output
|
||||
format.
|
||||
|
||||
**Uses:**
|
||||
|
||||
Creating `Sha256` hash is simple. You can use `Sha256` class instance and update
|
||||
the digest. Calling the `hex` method will return the sha256 in `hex` value. You
|
||||
can also use the `toString` method.
|
||||
|
||||
**Note:** For `HmacSha256`, you can pass the secret `key` while creating an
|
||||
instance of the object.
|
||||
Supported formats are `hex` and `base64` and default format is `hex`.
|
||||
|
||||
```ts
|
||||
import { Sha256, HmacSha256 } from "https://deno.land/std/hash/sha256.ts";
|
||||
import { createHash } from "https://deno.land/std/hash/mod.ts";
|
||||
|
||||
const sha256 = new Sha256().update("中文");
|
||||
console.log(sha256.hex());
|
||||
console.log(sha256.toString()); // Same as above
|
||||
|
||||
const key = "Hi There";
|
||||
const hmac = new HmacSha256(key).update("中文");
|
||||
|
||||
console.log(hmac.hex());
|
||||
console.log(hmac.toString()); // Same as above
|
||||
const hash = createHash("md5");
|
||||
hash.update("Your data here");
|
||||
const hashInHex = hash.toString(); // returns 5fe084ee423ff7e0c7709e9437cee89d
|
||||
```
|
||||
|
||||
```ts
|
||||
import { createHash } from "https://deno.land/std/hash/mod.ts";
|
||||
|
||||
const hash = createHash("md5");
|
||||
hash.update("Your data here");
|
||||
const hashInBase64 = hash.toString("base64"); // returns X+CE7kI/9+DHcJ6UN87onQ==
|
||||
```
|
||||
|
||||
### Supported algorithms
|
||||
|
||||
Following algorithms are supported.
|
||||
|
||||
- md2
|
||||
- md4
|
||||
- md5
|
||||
- ripemd160
|
||||
- ripemd320
|
||||
- sha1
|
||||
- sha224
|
||||
- sha256
|
||||
- sha384
|
||||
- sha512
|
||||
- sha3-224
|
||||
- sha3-256
|
||||
- sha3-384
|
||||
- sha3-512
|
||||
- keccak224
|
||||
- keccak256
|
||||
- keccak384
|
||||
- keccak512
|
||||
|
|
301
std/hash/_wasm/Cargo.lock
generated
Normal file
301
std/hash/_wasm/Cargo.lock
generated
Normal file
|
@ -0,0 +1,301 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "deno-hash"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"md-5",
|
||||
"md2",
|
||||
"md4",
|
||||
"ripemd160",
|
||||
"ripemd320",
|
||||
"sha-1",
|
||||
"sha2",
|
||||
"sha3",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "keccak"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "md2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f130b74b5f0b05ffd405280ed1a9c2e4539fc3ca01f37b9ea947cd64922116e9"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "md4"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4030c65cf2aab7ada769cae7d1e7159f8d034d6ded4f39afba037f094bfd9a1"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ripemd160"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ripemd320"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d1df357078db685e0a2d14b0eac053da79878026bb205da7050d8a5168e208b"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha3"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"byte-tools",
|
||||
"digest",
|
||||
"keccak",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c2dc4aa152834bc334f506c1a06b866416a8b6697d5c9f75b9a689c8486def0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded84f06e0ed21499f6184df0e0cb3494727b0c5da89534e0fcc55c51d812101"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "838e423688dac18d73e31edce74ddfac468e37b1506ad163ffaf0a46f703ffe3"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3156052d8ec77142051a533cdd686cba889537b213f948cd1d20869926e68e92"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9ba19973a58daf4db6f352eda73dc0e289493cd29fb2632eb172085b6521acd"
|
26
std/hash/_wasm/Cargo.toml
Normal file
26
std/hash/_wasm/Cargo.toml
Normal file
|
@ -0,0 +1,26 @@
|
|||
[package]
|
||||
name = "deno-hash"
|
||||
version = "0.1.0"
|
||||
authors = ["the Deno authors"]
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/denoland/deno"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
digest = "0.8.1"
|
||||
md2 = "0.8"
|
||||
md4 = "0.8"
|
||||
md-5 = "0.8"
|
||||
ripemd160 = "0.8.0"
|
||||
ripemd320 = "0.8.0"
|
||||
sha-1 = "0.8.2"
|
||||
sha2 = "0.8.2"
|
||||
sha3 = "0.8.2"
|
||||
wasm-bindgen = "0.2.63"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
opt-level = "z"
|
17
std/hash/_wasm/README.md
Normal file
17
std/hash/_wasm/README.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# How to build
|
||||
|
||||
## Prerequisite
|
||||
|
||||
`wasm-pack` is required.
|
||||
|
||||
```sh
|
||||
cargo install wasm-pack
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
deno run --allow-read --allow-write --allow-run ./build.ts
|
||||
```
|
||||
|
||||
`wasm.js` will be generated.
|
48
std/hash/_wasm/build.ts
Normal file
48
std/hash/_wasm/build.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { encode as base64Encode } from "../../encoding/base64.ts";
|
||||
|
||||
// 1. build wasm
|
||||
async function buildWasm(path: string): Promise<void> {
|
||||
const cmd = [
|
||||
"wasm-pack",
|
||||
"build",
|
||||
"--target",
|
||||
"web",
|
||||
"--release",
|
||||
"-d",
|
||||
path,
|
||||
];
|
||||
const builder = Deno.run({ cmd });
|
||||
const status = await builder.status();
|
||||
|
||||
if (!status.success) {
|
||||
console.error(`Failed to build wasm: ${status.code}`);
|
||||
Deno.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. encode wasm
|
||||
async function encodeWasm(wasmPath: string): Promise<string> {
|
||||
const wasm = await Deno.readFile(`${wasmPath}/deno_hash_bg.wasm`);
|
||||
return base64Encode(wasm);
|
||||
}
|
||||
|
||||
// 3. generate script
|
||||
async function generate(wasm: string, output: string): Promise<void> {
|
||||
const initScript = await Deno.readTextFile(`${output}/deno_hash.js`);
|
||||
const denoHashScript =
|
||||
"/* eslint-disable */\n" +
|
||||
"//deno-fmt-ignore-file\n" +
|
||||
`import * as base64 from "../../encoding/base64.ts";` +
|
||||
`export const source = base64.decode("${wasm}");` +
|
||||
initScript;
|
||||
|
||||
await Deno.writeFile("wasm.js", new TextEncoder().encode(denoHashScript));
|
||||
}
|
||||
|
||||
const OUTPUT_DIR = "./out";
|
||||
|
||||
await buildWasm(OUTPUT_DIR);
|
||||
const wasm = await encodeWasm(OUTPUT_DIR);
|
||||
await generate(wasm, OUTPUT_DIR);
|
76
std/hash/_wasm/hash.ts
Normal file
76
std/hash/_wasm/hash.ts
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import init, {
|
||||
source,
|
||||
create_hash as createHash,
|
||||
update_hash as updateHash,
|
||||
digest_hash as digestHash,
|
||||
DenoHash,
|
||||
} from "./wasm.js";
|
||||
|
||||
import * as hex from "../../encoding/hex.ts";
|
||||
import * as base64 from "../../encoding/base64.ts";
|
||||
import { Hasher, Message, OutputFormat } from "../hasher.ts";
|
||||
|
||||
await init(source);
|
||||
|
||||
const TYPE_ERROR_MSG = "hash: `data` is invalid type";
|
||||
|
||||
export class Hash implements Hasher {
|
||||
#hash: DenoHash;
|
||||
#digested: boolean;
|
||||
|
||||
constructor(algorithm: string) {
|
||||
this.#hash = createHash(algorithm);
|
||||
this.#digested = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update internal state
|
||||
* @param data data to update
|
||||
*/
|
||||
update(data: Message): this {
|
||||
let msg: Uint8Array;
|
||||
|
||||
if (typeof data === "string") {
|
||||
msg = new TextEncoder().encode(data as string);
|
||||
} else if (typeof data === "object") {
|
||||
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
||||
msg = new Uint8Array(data);
|
||||
} else {
|
||||
throw new Error(TYPE_ERROR_MSG);
|
||||
}
|
||||
} else {
|
||||
throw new Error(TYPE_ERROR_MSG);
|
||||
}
|
||||
|
||||
updateHash(this.#hash, msg);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Returns final hash */
|
||||
digest(): ArrayBuffer {
|
||||
if (this.#digested) throw new Error("hash: already digested");
|
||||
|
||||
this.#digested = true;
|
||||
return digestHash(this.#hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns hash as a string of given format
|
||||
* @param format format of output string (hex or base64). Default is hex
|
||||
*/
|
||||
toString(format: OutputFormat = "hex"): string {
|
||||
const finalized = new Uint8Array(this.digest());
|
||||
|
||||
switch (format) {
|
||||
case "hex":
|
||||
return hex.encodeToString(finalized);
|
||||
case "base64":
|
||||
return base64.encode(finalized);
|
||||
default:
|
||||
throw new Error("hash: invalid format");
|
||||
}
|
||||
}
|
||||
}
|
51
std/hash/_wasm/src/lib.rs
Normal file
51
std/hash/_wasm/src/lib.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use digest::{Digest, DynDigest};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct DenoHash {
|
||||
inner: Box<dyn DynDigest>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn create_hash(algorithm: &str) -> Result<DenoHash, JsValue> {
|
||||
let hash: Option<Box<dyn DynDigest>> = match algorithm {
|
||||
"md2" => Some(Box::new(md2::Md2::new())),
|
||||
"md4" => Some(Box::new(md4::Md4::new())),
|
||||
"md5" => Some(Box::new(md5::Md5::new())),
|
||||
"ripemd160" => Some(Box::new(ripemd160::Ripemd160::new())),
|
||||
"ripemd320" => Some(Box::new(ripemd320::Ripemd320::new())),
|
||||
"sha1" => Some(Box::new(sha1::Sha1::new())),
|
||||
"sha224" => Some(Box::new(sha2::Sha224::new())),
|
||||
"sha256" => Some(Box::new(sha2::Sha256::new())),
|
||||
"sha384" => Some(Box::new(sha2::Sha384::new())),
|
||||
"sha512" => Some(Box::new(sha2::Sha512::new())),
|
||||
"sha3-224" => Some(Box::new(sha3::Sha3_224::new())),
|
||||
"sha3-256" => Some(Box::new(sha3::Sha3_256::new())),
|
||||
"sha3-384" => Some(Box::new(sha3::Sha3_384::new())),
|
||||
"sha3-512" => Some(Box::new(sha3::Sha3_512::new())),
|
||||
"keccak224" => Some(Box::new(sha3::Keccak224::new())),
|
||||
"keccak256" => Some(Box::new(sha3::Keccak256::new())),
|
||||
"keccak384" => Some(Box::new(sha3::Keccak384::new())),
|
||||
"keccak512" => Some(Box::new(sha3::Keccak512::new())),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(h) = hash {
|
||||
Ok(DenoHash { inner: h })
|
||||
} else {
|
||||
let err_msg = format!("unsupported hash algorithm: {}", algorithm);
|
||||
Err(JsValue::from_str(&err_msg))
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn update_hash(hash: &mut DenoHash, data: &[u8]) {
|
||||
hash.inner.input(data)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn digest_hash(hash: &mut DenoHash) -> Box<[u8]> {
|
||||
hash.inner.result_reset()
|
||||
}
|
247
std/hash/_wasm/wasm.js
Normal file
247
std/hash/_wasm/wasm.js
Normal file
File diff suppressed because one or more lines are too long
316
std/hash/hash_test.ts
Normal file
316
std/hash/hash_test.ts
Normal file
|
@ -0,0 +1,316 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { assertEquals, assertThrows } from "../testing/asserts.ts";
|
||||
import { createHash, SupportedAlgorithm } from "./mod.ts";
|
||||
|
||||
const millionAs = "a".repeat(1000000);
|
||||
|
||||
const testSetHex: Record<string, string[][]> = {
|
||||
md5: [
|
||||
["", "d41d8cd98f00b204e9800998ecf8427e"],
|
||||
["abc", "900150983cd24fb0d6963f7d28e17f72"],
|
||||
["deno", "c8772b401bc911da102a5291cc4ec83b"],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"9e107d9d372bb6826bd81d3542a419d6",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"3b0c8ac703f828b04c6c197006d17218",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"014842d480b571495a4a0363793f7367",
|
||||
],
|
||||
[millionAs, "7707d6ae4e027c70eea2a935c2296f21"],
|
||||
],
|
||||
sha1: [
|
||||
["", "da39a3ee5e6b4b0d3255bfef95601890afd80709"],
|
||||
["abc", "a9993e364706816aba3e25717850c26c9cd0d89d"],
|
||||
["deno", "bb3d8e712d9e7ad4af08d4a38f3f52d9683d58eb"],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"c2db330f6083854c99d4b5bfb6e8f29f201be699",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"0098ba824b5c16427bd7a1122a5a442a25ec644d",
|
||||
],
|
||||
[millionAs, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"],
|
||||
],
|
||||
sha256: [
|
||||
["", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"],
|
||||
["abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"],
|
||||
[
|
||||
"deno",
|
||||
"e872e7bd2ae6abcf13a4c834029a342c882c1162ebf77b6720968b2000312ffb",
|
||||
],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"b35439a4ac6f0948b6d6f9e3c6af0f5f590ce20f1bde7090ef7970686ec6738a",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"ffe054fe7ae0cb6dc65c3af9b61d5209f439851db43d0ba5997337df154668eb",
|
||||
],
|
||||
[
|
||||
millionAs,
|
||||
"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0",
|
||||
],
|
||||
],
|
||||
sha512: [
|
||||
[
|
||||
"",
|
||||
"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
|
||||
],
|
||||
[
|
||||
"abc",
|
||||
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
|
||||
],
|
||||
[
|
||||
"deno",
|
||||
"05b6ef7b13673c57c455d968cb7acbdd4fe10e24f25520763d69025d768d14124987b14e3aff8ff1565aaeba1c405fc89cc435938ff46a426f697b0f509e3799",
|
||||
],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"962b64aae357d2a4fee3ded8b539bdc9d325081822b0bfc55583133aab44f18bafe11d72a7ae16c79ce2ba620ae2242d5144809161945f1367f41b3972e26e04",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"01d35c10c6c38c2dcf48f7eebb3235fb5ad74a65ec4cd016e2354c637a8fb49b695ef3c1d6f7ae4cd74d78cc9c9bcac9d4f23a73019998a7f73038a5c9b2dbde",
|
||||
],
|
||||
[
|
||||
millionAs,
|
||||
"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b",
|
||||
],
|
||||
],
|
||||
"sha3-256": [
|
||||
["", "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"],
|
||||
["abc", "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"],
|
||||
[
|
||||
"deno",
|
||||
"74a6286af90f8775d74080f864cf80b11eecf6f14d325c5ef8c9f7ccc8055517",
|
||||
],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"f6fe8de5c8f5014786f07e9f7b08130f920dd55e587d47021686b26cf2323deb",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"043d104b5480439c7acff8831ee195183928d9b7f8fcb0c655a086a87923ffee",
|
||||
],
|
||||
[
|
||||
millionAs,
|
||||
"5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1",
|
||||
],
|
||||
],
|
||||
"sha3-512": [
|
||||
[
|
||||
"",
|
||||
"a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26",
|
||||
],
|
||||
[
|
||||
"abc",
|
||||
"b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0",
|
||||
],
|
||||
[
|
||||
"deno",
|
||||
"9e248199d744a8d810e7fda8207f98f27453bd6cb5a02965b5477d3d07516bbac6831009eedddadc8901d742dbfe3fd4afa770230a84e4d51bf30a0c99efa03c",
|
||||
],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"302d75b7947aa354a54872df954dc0dfe673cf60faedebdea7e9b22263a3bdf39e346a4f2868639836955396f186a67b02ec8e3365bdf59867070f81849c2c35",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"2141e94c719955872c455c83eb83e7618a9b523a0ee9f118e794fbff8b148545c8e8caabef08d8cfdb1dfb36b4dd81cc48bfc77e7f85632197b882fd9c4384e0",
|
||||
],
|
||||
[
|
||||
millionAs,
|
||||
"3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87",
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
const testSetBase64: Record<string, string[][]> = {
|
||||
md5: [
|
||||
["", "1B2M2Y8AsgTpgAmY7PhCfg=="],
|
||||
["abc", "kAFQmDzST7DWlj99KOF/cg=="],
|
||||
["deno", "yHcrQBvJEdoQKlKRzE7IOw=="],
|
||||
["The quick brown fox jumps over the lazy dog", "nhB9nTcrtoJr2B01QqQZ1g=="],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"OwyKxwP4KLBMbBlwBtFyGA==",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"AUhC1IC1cUlaSgNjeT9zZw==",
|
||||
],
|
||||
[millionAs, "dwfWrk4CfHDuoqk1wilvIQ=="],
|
||||
],
|
||||
sha1: [
|
||||
["", "2jmj7l5rSw0yVb/vlWAYkK/YBwk="],
|
||||
["abc", "qZk+NkcGgWq6PiVxeFDCbJzQ2J0="],
|
||||
["deno", "uz2OcS2eetSvCNSjjz9S2Wg9WOs="],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"L9ThxnotKPzthJ7hu3bnORuT6xI=",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"wtszD2CDhUyZ1LW/tujynyAb5pk=",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"AJi6gktcFkJ716ESKlpEKiXsZE0=",
|
||||
],
|
||||
[millionAs, "NKqXPNTE2qT2Husr260nMWU0AW8="],
|
||||
],
|
||||
sha256: [
|
||||
["", "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="],
|
||||
["abc", "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="],
|
||||
["deno", "6HLnvSrmq88TpMg0Apo0LIgsEWLr93tnIJaLIAAxL/s="],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"16j7swfXgJRpypq8sAguT41WUeRtPNt2LQLQvzfJ5ZI=",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"s1Q5pKxvCUi21vnjxq8PX1kM4g8b3nCQ73lwaG7Gc4o=",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"/+BU/nrgy23GXDr5th1SCfQ5hR20PQulmXM33xVGaOs=",
|
||||
],
|
||||
[millionAs, "zcduXJkU+5KBocfihNc+Z/GAmkiklyAOBG05zMcRLNA="],
|
||||
],
|
||||
sha512: [
|
||||
[
|
||||
"",
|
||||
"z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==",
|
||||
],
|
||||
[
|
||||
"abc",
|
||||
"3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw==",
|
||||
],
|
||||
[
|
||||
"deno",
|
||||
"BbbvexNnPFfEVdloy3rL3U/hDiTyVSB2PWkCXXaNFBJJh7FOOv+P8VZarrocQF/InMQ1k4/0akJvaXsPUJ43mQ==",
|
||||
],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"B+VH2VhvanP3P7rAQ17XaVEhj7fQyNeIownXhUNru2Quk6JSqVTyORJUfR6KO17W4b/XCXghIz+gU489uFT+5g==",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"litkquNX0qT+497YtTm9ydMlCBgisL/FVYMTOqtE8Yuv4R1yp64Wx5ziumIK4iQtUUSAkWGUXxNn9Bs5cuJuBA==",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"AdNcEMbDjC3PSPfuuzI1+1rXSmXsTNAW4jVMY3qPtJtpXvPB1veuTNdNeMycm8rJ1PI6cwGZmKf3MDilybLb3g==",
|
||||
],
|
||||
[
|
||||
millionAs,
|
||||
"5xhIPQznaWROLkLHvBW0Y44fmLE7IEQoVjKoA6+pc+veD/JEh36mCkywQyzld8Mb6wCcXCxJqi5OrbIXrYzAmw==",
|
||||
],
|
||||
],
|
||||
"sha3-256": [
|
||||
["", "p//G+L8e12ZRwUdWoGHWYvWA/03kO0n6gtgKS4D4Q0o="],
|
||||
["abc", "Ophdp0/iJbIEXBcta9OQvYVfCG4+nVJbRr/iRRFDFTI="],
|
||||
["deno", "dKYoavkPh3XXQID4ZM+AsR7s9vFNMlxe+Mn3zMgFVRc="],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"aQcN2gGXXIwSDDqtobKCOU5/Ay+pzzL0yyJZoIl9/AQ=",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"9v6N5cj1AUeG8H6fewgTD5IN1V5YfUcCFoaybPIyPes=",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"BD0QS1SAQ5x6z/iDHuGVGDko2bf4/LDGVaCGqHkj/+4=",
|
||||
],
|
||||
[millionAs, "XIh1rkdKNjS6T9VeyFv/1mHzKsp1xtaZ0M3LbBFYkcE="],
|
||||
],
|
||||
"sha3-512": [
|
||||
[
|
||||
"",
|
||||
"pp9zzKI6msXItWfcGFp1bpfJghZP4lhZ4NHcwUdcgKYVshI68fX5TBHj6UAsOsVY9QAZnZW20+MBdYWGKB3NJg==",
|
||||
],
|
||||
[
|
||||
"abc",
|
||||
"t1GFCxpXFopWk82SS2sJbgj2IYJ0RPcNiE9dAkDScS4Q4RbpGSrzyRp+xXZH45NAVzQLTPQI1aVlkvgnTuxT8A==",
|
||||
],
|
||||
[
|
||||
"deno",
|
||||
"niSBmddEqNgQ5/2oIH+Y8nRTvWy1oClltUd9PQdRa7rGgxAJ7t3a3IkB10Lb/j/Ur6dwIwqE5NUb8woMme+gPA==",
|
||||
],
|
||||
[
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
"Ad7dXeTvFGQkRbpfW5fBXke5rZMTJuSwcnzZTO/ET/8j8Hv1QxOZObSRKMr0Ntwb3uVPyyQCOgjZQD+bS/DUUA==",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"MC11t5R6o1SlSHLflU3A3+Zzz2D67evep+myImOjvfOeNGpPKGhjmDaVU5bxhqZ7AuyOM2W99ZhnBw+BhJwsNQ==",
|
||||
],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"IUHpTHGZVYcsRVyD64PnYYqbUjoO6fEY55T7/4sUhUXI6Mqr7wjYz9sd+za03YHMSL/Hfn+FYyGXuIL9nEOE4A==",
|
||||
],
|
||||
[
|
||||
millionAs,
|
||||
"PDqHbaFANKtgYnwHe7mPfhIKKlNwIS3/szhaGNTziFntMR0KnVFBzpzFxm7mibJmqKoYrOgoKg4NtZbJCwp7hw==",
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
Deno.test("[hash/all/hex] testAllHex", () => {
|
||||
for (const algorithm in testSetHex) {
|
||||
for (const [input, output] of testSetHex[algorithm]) {
|
||||
const hash = createHash(algorithm as SupportedAlgorithm);
|
||||
assertEquals(hash.update(input).toString(), output);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Deno.test("[hash/all/base64] testAllHex", () => {
|
||||
for (const algorithm in testSetBase64) {
|
||||
for (const [input, output] of testSetBase64[algorithm]) {
|
||||
const hash = createHash(algorithm as SupportedAlgorithm);
|
||||
assertEquals(hash.update(input).toString("base64"), output);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Deno.test("[hash/double_digest] testDoubleDigest", () => {
|
||||
assertThrows(
|
||||
(): void => {
|
||||
const hash = createHash("md5");
|
||||
hash.update("test");
|
||||
const h1 = hash.digest();
|
||||
const h2 = hash.digest();
|
||||
assertEquals(h1, h2);
|
||||
},
|
||||
Error,
|
||||
"hash: already digested"
|
||||
);
|
||||
});
|
10
std/hash/hasher.ts
Normal file
10
std/hash/hasher.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
export type Message = string | ArrayBuffer;
|
||||
export type OutputFormat = "hex" | "base64";
|
||||
|
||||
export interface Hasher {
|
||||
update(data: Message): this;
|
||||
digest(): ArrayBuffer;
|
||||
toString(format?: OutputFormat): string;
|
||||
}
|
34
std/hash/mod.ts
Normal file
34
std/hash/mod.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { Hash } from "./_wasm/hash.ts";
|
||||
import { Hasher } from "./hasher.ts";
|
||||
|
||||
export { Hasher } from "./hasher.ts";
|
||||
export type SupportedAlgorithm =
|
||||
| "md2"
|
||||
| "md4"
|
||||
| "md5"
|
||||
| "ripemd160"
|
||||
| "ripemd320"
|
||||
| "sha1"
|
||||
| "sha224"
|
||||
| "sha256"
|
||||
| "sha384"
|
||||
| "sha512"
|
||||
| "sha3-224"
|
||||
| "sha3-256"
|
||||
| "sha3-384"
|
||||
| "sha3-512"
|
||||
| "keccak224"
|
||||
| "keccak256"
|
||||
| "keccak384"
|
||||
| "keccak512";
|
||||
|
||||
/**
|
||||
* Creates a new `Hash` instance.
|
||||
*
|
||||
* @param algorithm name of hash algorithm to use
|
||||
*/
|
||||
export function createHash(algorithm: SupportedAlgorithm): Hasher {
|
||||
return new Hash(algorithm as string);
|
||||
}
|
49
tools/hash_benchmark.py
Normal file
49
tools/hash_benchmark.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
# Performs benchmark on hash algorithms
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
algorithms = [
|
||||
"md5",
|
||||
"sha1",
|
||||
"sha224",
|
||||
"sha256",
|
||||
"sha512",
|
||||
"sha3-224",
|
||||
"sha3-256",
|
||||
"sha3-384",
|
||||
"sha3-512",
|
||||
]
|
||||
|
||||
|
||||
def run_benchmark(deno_exe, method, input_file):
|
||||
# compile
|
||||
subprocess.call([deno_exe, "run", "cli/tests/hash.ts"])
|
||||
|
||||
for alg in algorithms:
|
||||
args = [
|
||||
deno_exe, "run", "--allow-read", "cli/tests/hash.ts", method, alg,
|
||||
input_file
|
||||
]
|
||||
|
||||
p = subprocess.Popen(args, stdout=subprocess.PIPE)
|
||||
(out, _) = p.communicate()
|
||||
|
||||
elapsed = out.split(':')[1].strip()
|
||||
print "[{}] {}".format(alg, elapsed)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 4:
|
||||
print "Usage ./tools/hash_benchmark.py path/to/deno method input"
|
||||
sys.exit(1)
|
||||
|
||||
run_benchmark(sys.argv[1], sys.argv[2], sys.argv[3])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Add table
Reference in a new issue