0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-10-31 09:14:20 -04:00
denoland-deno/std/hash/_fnv/fnv64.ts
2020-05-15 09:42:19 -04:00

89 lines
2 KiB
TypeScript

// 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-2020 the Deno authors. All rights reserved. MIT license.
import { mul64 } from "./util.ts";
const offset64Lo = 2216829733;
const offset64Hi = 3421674724;
const prime64Lo = 435;
const prime64Hi = 256;
abstract class Fnv64Base<T> {
#stateHi: number;
#stateLo: number;
constructor() {
this.#stateHi = offset64Hi;
this.#stateLo = offset64Lo;
}
protected _updateState([newStateHi, newStateLo]: [number, number]): void {
this.#stateHi = newStateHi;
this.#stateLo = newStateLo;
}
reset(): void {
this.#stateHi = offset64Hi;
this.#stateLo = offset64Lo;
}
abstract write(data: Uint8Array): T;
size(): number {
return 8;
}
blockSize(): number {
return 1;
}
sum64(): [number, number] {
return [this.#stateHi, this.#stateLo];
}
sum(): Uint8Array {
return Uint8Array.from([
(this.#stateHi >> 24) & 0xff,
(this.#stateHi >> 16) & 0xff,
(this.#stateHi >> 8) & 0xff,
this.#stateHi & 0xff,
(this.#stateLo >> 24) & 0xff,
(this.#stateLo >> 16) & 0xff,
(this.#stateLo >> 8) & 0xff,
this.#stateLo & 0xff,
]);
}
}
/** Fnv64 hash */
export class Fnv64 extends Fnv64Base<Fnv64> {
write(data: Uint8Array): Fnv64 {
let [hashHi, hashLo] = this.sum64();
data.forEach((c) => {
[hashHi, hashLo] = mul64([hashHi, hashLo], [prime64Hi, prime64Lo]);
hashLo ^= c;
});
this._updateState([hashHi, hashLo]);
return this;
}
}
/** Fnv64a hash */
export class Fnv64a extends Fnv64Base<Fnv64a> {
write(data: Uint8Array): Fnv64 {
let [hashHi, hashLo] = this.sum64();
data.forEach((c) => {
hashLo ^= c;
[hashHi, hashLo] = mul64([hashHi, hashLo], [prime64Hi, prime64Lo]);
});
this._updateState([hashHi, hashLo]);
return this;
}
}