-
Notifications
You must be signed in to change notification settings - Fork 621
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
169246f
commit 3b67bd1
Showing
6 changed files
with
223 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,6 @@ | ||
#!/usr/bin/env -S deno bench | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
import { | ||
crypto as stdCrypto, | ||
DIGEST_ALGORITHM_NAMES, | ||
} from "https://deno.land/std@$STD_VERSION/crypto/mod.ts"; | ||
import { crypto as stdCrypto, DIGEST_ALGORITHM_NAMES } from "../mod.ts"; | ||
|
||
import { crypto as oldCrypto } from "https://deno.land/[email protected]/crypto/mod.ts"; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Ported from Go: | ||
// https://github.com/golang/go/tree/go1.13.10/src/hash/fnv/fnv.go | ||
// Copyright 2011 The Go Authors. All rights reserved. BSD license. | ||
// https://github.com/golang/go/blob/master/LICENSE | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
// This module is browser compatible. | ||
|
||
import { mul32, swap32 } from "./util.ts"; | ||
|
||
const prime32 = 16777619; | ||
|
||
export const fnv32 = (data: Uint8Array): ArrayBuffer => { | ||
let hash = 2166136261; | ||
|
||
data.forEach((c) => { | ||
hash = mul32(hash, prime32); | ||
hash ^= c; | ||
}); | ||
|
||
return Uint32Array.from([swap32(hash)]).buffer; | ||
}; | ||
|
||
export const fnv32a = (data: Uint8Array): ArrayBuffer => { | ||
let hash = 2166136261; | ||
|
||
data.forEach((c) => { | ||
hash ^= c; | ||
hash = mul32(hash, prime32); | ||
}); | ||
|
||
return Uint32Array.from([swap32(hash)]).buffer; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Ported from Go: | ||
// https://github.com/golang/go/tree/go1.13.10/src/hash/fnv/fnv.go | ||
// Copyright 2011 The Go Authors. All rights reserved. BSD license. | ||
// https://github.com/golang/go/blob/master/LICENSE | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
// This module is browser compatible. | ||
|
||
import { mul64, swap32 } from "./util.ts"; | ||
|
||
const prime64Lo = 435; | ||
const prime64Hi = 256; | ||
|
||
export const fnv64 = (data: Uint8Array): ArrayBuffer => { | ||
let hashLo = 2216829733; | ||
let hashHi = 3421674724; | ||
|
||
data.forEach((c) => { | ||
[hashHi, hashLo] = mul64([hashHi, hashLo], [prime64Hi, prime64Lo]); | ||
hashLo ^= c; | ||
}); | ||
|
||
return new Uint32Array([swap32(hashHi >>> 0), swap32(hashLo >>> 0)]).buffer; | ||
}; | ||
|
||
export const fnv64a = (data: Uint8Array): ArrayBuffer => { | ||
let hashLo = 2216829733; | ||
let hashHi = 3421674724; | ||
|
||
data.forEach((c) => { | ||
hashLo ^= c; | ||
[hashHi, hashLo] = mul64([hashHi, hashLo], [prime64Hi, prime64Lo]); | ||
}); | ||
|
||
return new Uint32Array([swap32(hashHi >>> 0), swap32(hashLo >>> 0)]).buffer; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
// This module is browser compatible. | ||
|
||
import { fnv32, fnv32a } from "./fnv32.ts"; | ||
import { fnv64, fnv64a } from "./fnv64.ts"; | ||
|
||
export function fnv(name: string, buf?: Uint8Array): ArrayBuffer { | ||
if (!buf) { | ||
throw new TypeError("no data provided for hashing"); | ||
} | ||
|
||
switch (name) { | ||
case "FNV32": | ||
return fnv32(buf); | ||
case "FNV64": | ||
return fnv64(buf); | ||
case "FNV32A": | ||
return fnv32a(buf); | ||
case "FNV64A": | ||
return fnv64a(buf); | ||
default: | ||
throw new TypeError(`unsupported fnv digest: ${name}`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
// This module is browser compatible. | ||
|
||
export function swap32(val: number): number { | ||
return ( | ||
((val & 0xff) << 24) | | ||
((val & 0xff00) << 8) | | ||
((val >> 8) & 0xff00) | | ||
((val >> 24) & 0xff) | ||
); | ||
} | ||
|
||
function n16(n: number): number { | ||
return n & 0xffff; | ||
} | ||
|
||
function n32(n: number): number { | ||
return n >>> 0; | ||
} | ||
|
||
function add32WithCarry(a: number, b: number): [number, number] { | ||
const added = n32(a) + n32(b); | ||
return [n32(added), added > 0xffffffff ? 1 : 0]; | ||
} | ||
|
||
function mul32WithCarry(a: number, b: number): [number, number] { | ||
const al = n16(a); | ||
const ah = n16(a >>> 16); | ||
const bl = n16(b); | ||
const bh = n16(b >>> 16); | ||
|
||
const [t, tc] = add32WithCarry(al * bh, ah * bl); | ||
const [n, nc] = add32WithCarry(al * bl, n32(t << 16)); | ||
const carry = nc + (tc << 16) + n16(t >>> 16) + ah * bh; | ||
|
||
return [n, carry]; | ||
} | ||
|
||
/** | ||
* mul32 performs 32-bit multiplication, a * b | ||
* @param a | ||
* @param b | ||
*/ | ||
export function mul32(a: number, b: number): number { | ||
// https://stackoverflow.com/a/28151933 | ||
const al = n16(a); | ||
const ah = a - al; | ||
return n32(n32(ah * b) + al * b); | ||
} | ||
|
||
/** | ||
* mul64 performs 64-bit multiplication with two 32-bit words | ||
* @param [ah, al] | ||
* @param [bh, bl] | ||
*/ | ||
export function mul64( | ||
[ah, al]: [number, number], | ||
[bh, bl]: [number, number], | ||
): [number, number] { | ||
const [n, c] = mul32WithCarry(al, bl); | ||
return [n32(mul32(al, bh) + mul32(ah, bl) + c), n]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
import { assertEquals } from "../../assert/mod.ts"; | ||
import { mul32, mul64 } from "./util.ts"; | ||
|
||
Deno.test("mul32()", () => { | ||
assertEquals(mul32(0xffffffff, 0xffffffff), 1); | ||
assertEquals(mul32(0x12345678, 0xdeadbeef), 0x5621ca08); | ||
assertEquals(mul32(0xf626f430, 0xff7469f1), 0x2a939130); | ||
assertEquals(mul32(0x543f9412, 0x8a4aa84f), 0x39fe818e); | ||
assertEquals(mul32(0x8ee170d1, 0x2fbbb9ec), 0x6a0609ac); | ||
assertEquals(mul32(0xea3b3a14, 0xa397bd0a), 0xddfd08c8); | ||
assertEquals(mul32(0x93f8536b, 0xa79e3c04), 0xcc7861ac); | ||
assertEquals(mul32(0xf97dab98, 0xed526241), 0x2348c198); | ||
assertEquals(mul32(0x35500191, 0xd5012447), 0xaff9d337); | ||
assertEquals(mul32(0x471dde47, 0xaaa4950c), 0x4341be54); | ||
assertEquals(mul32(0xd633970d, 0xa9bc2bcd), 0xb43b2469); | ||
assertEquals(mul32(0xc60898cc, 0xbfe7dcc4), 0x15f84c30); | ||
}); | ||
|
||
Deno.test("mul64()", () => { | ||
assertEquals(mul64([0xffffffff, 0xffffffff], [0xffffffff, 0xffffffff]), [ | ||
0, | ||
1, | ||
]); | ||
assertEquals(mul64([0x12345678, 0xdeadbeef], [0xcafebabe, 0xbaadf00d]), [ | ||
0xc801c86b, | ||
0xdf55c223, | ||
]); | ||
assertEquals(mul64([0xdc479aed, 0x24bc71a3], [0x543717c1, 0x4b6056b9]), [ | ||
0x56c7ec8f, | ||
0x387ae0cb, | ||
]); | ||
assertEquals(mul64([0xb84936ae, 0xb84becd2], [0x2864edd1, 0x14ee13cc]), [ | ||
0xd87e9171, | ||
0x12504d58, | ||
]); | ||
assertEquals(mul64([0xb0b73e95, 0x3f5cc701], [0x6c7b30b8, 0xcd7f0f9e]), [ | ||
0x570551ee, | ||
0x116ae19e, | ||
]); | ||
assertEquals(mul64([0xc237b433, 0x160b50bf], [0x3f937c23, 0xf26175f7]), [ | ||
0x48a1d118, | ||
0x97313349, | ||
]); | ||
assertEquals(mul64([0x386242fd, 0x6baa0fc0], [0xf81f7e23, 0xbe172381]), [ | ||
0x4799f2a3, | ||
0x6b192fc0, | ||
]); | ||
assertEquals(mul64([0x5afc8714, 0x902180d1], [0xa7068c96, 0xb859bb4d]), [ | ||
0xb4589d29, | ||
0xd3d569dd, | ||
]); | ||
assertEquals(mul64([0xb4e86a68, 0x619bee92], [0xd67560fa, 0x736982a7]), [ | ||
0x72c73b5d, | ||
0x4bc0c53e, | ||
]); | ||
assertEquals(mul64([0xfc8b5561, 0xbf91d6d5], [0x2bcb029a, 0xa144ead3]), [ | ||
0x2da439a7, | ||
0x3926c38f, | ||
]); | ||
assertEquals(mul64([0x47b62fae, 0xffe8cb4c], [0xbda77111, 0x6cad4968]), [ | ||
0x9d9b7832, | ||
0xcae742e0, | ||
]); | ||
assertEquals(mul64([0xc9160fc1, 0xd96e085b], [0x3adfd031, 0x3f75e557]), [ | ||
0xe4d0bf23, | ||
0x88753ded, | ||
]); | ||
}); |