diff options
Diffstat (limited to 'std/hash/_fnv/fnv64.ts')
-rw-r--r-- | std/hash/_fnv/fnv64.ts | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/std/hash/_fnv/fnv64.ts b/std/hash/_fnv/fnv64.ts new file mode 100644 index 000000000..8a5b5187d --- /dev/null +++ b/std/hash/_fnv/fnv64.ts @@ -0,0 +1,89 @@ +// 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; + } +} |