Published source
Download source ZIP
CH-J Server Manager
Browse directories and files for a specific application release.
Source is provided under the CH-J Proprietary Software License 1.14. Its availability does not change the license terms or grant additional rights.
1
"use strict";3
const Tiger = require("./vendor/fbTiger/Tiger");5
const MASK64 = 0xffffffffffffffffn;6
const u64 = (value) => BigInt.asUintN(64, value);7
const rotl32 = (value, bits) => ((value << bits) | (value >>> (32 - bits))) >>> 0;8
const rotl64 = (value, bits) => u64((value << BigInt(bits)) | (value >> BigInt(64 - bits)));10
class BlockHash {11
constructor(blockSize) {12
this.blockSize = blockSize;13
this.tail = Buffer.alloc(0);14
this.length = 0n;15
}17
update(value) {18
const input = Buffer.isBuffer(value) ? value : Buffer.from(value);19
this.length += BigInt(input.length);20
let data = this.tail.length ? Buffer.concat([this.tail, input]) : input;21
let offset = 0;22
while (offset + this.blockSize <= data.length) {23
this._block(data, offset);24
offset += this.blockSize;25
}26
this.tail = Buffer.from(data.subarray(offset));27
return this;28
}29
}31
class TigerHash extends BlockHash {32
constructor(tiger2 = false) {33
super(64);34
this.tiger2 = tiger2;35
this.engine = new Tiger(Tiger.L192);36
this.engine._a = { value: 0x0123456789abcdefn };37
this.engine._b = { value: 0xfedcba9876543210n };38
this.engine._c = { value: 0xf096a5b4c3b2e187n };39
}41
_block(data, offset) {42
const words = [];43
for (let index = 0; index < 8; index += 1) words.push(data.readBigUInt64LE(offset + index * 8));44
this.engine._split(words, 0);45
this.engine._compress();46
}48
digest() {49
const bitLength = u64(this.length * 8n);50
const used = this.tail.length;51
const padLength = used < 56 ? 64 - used : 128 - used;52
const padding = Buffer.alloc(padLength);53
padding[0] = this.tiger2 ? 0x80 : 0x01;54
padding.writeBigUInt64LE(bitLength, padLength - 8);55
const final = Buffer.concat([this.tail, padding]);56
for (let offset = 0; offset < final.length; offset += 64) this._block(final, offset);57
const output = Buffer.alloc(24);58
output.writeBigUInt64LE(this.engine._a.value, 0);59
output.writeBigUInt64LE(this.engine._b.value, 8);60
output.writeBigUInt64LE(this.engine._c.value, 16);61
return output;62
}63
}65
class FnvHash {66
constructor(bits, variant) {67
this.bits = bits;68
this.variant = variant;69
this.mask = bits === 32 ? 0xffffffffn : MASK64;70
this.prime = bits === 32 ? 0x01000193n : 0x100000001b3n;71
this.value = bits === 32 ? 0x811c9dc5n : 0xcbf29ce484222325n;72
}74
update(input) {75
for (const byte of input) {76
if (this.variant === "1a") this.value ^= BigInt(byte);77
this.value = (this.value * this.prime) & this.mask;78
if (this.variant === "1") this.value ^= BigInt(byte);79
}80
return this;81
}83
digest() {84
const output = Buffer.alloc(this.bits / 8);85
if (this.bits === 32) output.writeUInt32BE(Number(this.value), 0);86
else output.writeBigUInt64BE(this.value, 0);87
return output;88
}89
}91
class Crc16CcittFalse {92
constructor() { this.value = 0xffff; }93
update(input) {94
for (const byte of input) {95
this.value ^= byte << 8;96
for (let bit = 0; bit < 8; bit += 1) this.value = ((this.value & 0x8000) ? ((this.value << 1) ^ 0x1021) : (this.value << 1)) & 0xffff;97
}98
return this;99
}100
digest() { const output = Buffer.alloc(2); output.writeUInt16BE(this.value); return output; }101
}103
class Crc64 {104
constructor(reflected) {105
this.reflected = reflected;106
this.value = reflected ? MASK64 : 0n;107
this.polynomial = reflected ? 0xc96c5795d7870f42n : 0x42f0e1eba9ea3693n;108
}109
update(input) {110
for (const byte of input) {111
if (this.reflected) {112
this.value ^= BigInt(byte);113
for (let bit = 0; bit < 8; bit += 1) this.value = (this.value & 1n) ? ((this.value >> 1n) ^ this.polynomial) : (this.value >> 1n);114
} else {115
this.value ^= BigInt(byte) << 56n;116
for (let bit = 0; bit < 8; bit += 1) this.value = u64((this.value & (1n << 63n)) ? ((this.value << 1n) ^ this.polynomial) : (this.value << 1n));117
}118
}119
return this;120
}121
digest() {122
const output = Buffer.alloc(8);123
output.writeBigUInt64BE(this.reflected ? (this.value ^ MASK64) : this.value);124
return output;125
}126
}128
function fmix32(value) {129
value ^= value >>> 16;130
value = Math.imul(value, 0x85ebca6b) >>> 0;131
value ^= value >>> 13;132
value = Math.imul(value, 0xc2b2ae35) >>> 0;133
return (value ^ (value >>> 16)) >>> 0;134
}136
function fmix64(value) {137
value ^= value >> 33n;138
value = u64(value * 0xff51afd7ed558ccdn);139
value ^= value >> 33n;140
value = u64(value * 0xc4ceb9fe1a85ec53n);141
return u64(value ^ (value >> 33n));142
}144
class MurmurX86_32 extends BlockHash {145
constructor(seed = 0) { super(4); this.h1 = Number(BigInt(seed) & 0xffffffffn); }146
_block(data, offset) {147
let k1 = data.readUInt32LE(offset);148
k1 = Math.imul(k1, 0xcc9e2d51) >>> 0;149
k1 = rotl32(k1, 15);150
k1 = Math.imul(k1, 0x1b873593) >>> 0;151
this.h1 ^= k1;152
this.h1 = rotl32(this.h1, 13);153
this.h1 = (Math.imul(this.h1, 5) + 0xe6546b64) >>> 0;154
}155
digest() {156
let k1 = 0;157
if (this.tail.length === 3) k1 ^= this.tail[2] << 16;158
if (this.tail.length >= 2) k1 ^= this.tail[1] << 8;159
if (this.tail.length >= 1) {160
k1 ^= this.tail[0];161
k1 = Math.imul(k1, 0xcc9e2d51) >>> 0;162
k1 = rotl32(k1, 15);163
k1 = Math.imul(k1, 0x1b873593) >>> 0;164
this.h1 ^= k1;165
}166
this.h1 = fmix32((this.h1 ^ Number(this.length & 0xffffffffn)) >>> 0);167
const output = Buffer.alloc(4); output.writeUInt32BE(this.h1); return output;168
}169
}171
class MurmurX86_128 extends BlockHash {172
constructor(seed = 0) {173
super(16);174
const value = Number(BigInt(seed) & 0xffffffffn);175
this.h1 = value; this.h2 = value; this.h3 = value; this.h4 = value;176
}177
_block(data, offset) {178
let k1 = data.readUInt32LE(offset); let k2 = data.readUInt32LE(offset + 4); let k3 = data.readUInt32LE(offset + 8); let k4 = data.readUInt32LE(offset + 12);179
k1 = Math.imul(rotl32(Math.imul(k1, 0x239b961b) >>> 0, 15), 0xab0e9789) >>> 0; this.h1 ^= k1;180
this.h1 = (Math.imul(rotl32(this.h1, 19), 5) + 0x561ccd1b) >>> 0; this.h1 = (this.h1 + this.h2) >>> 0;181
k2 = Math.imul(rotl32(Math.imul(k2, 0xab0e9789) >>> 0, 16), 0x38b34ae5) >>> 0; this.h2 ^= k2;182
this.h2 = (Math.imul(rotl32(this.h2, 17), 5) + 0x0bcaa747) >>> 0; this.h2 = (this.h2 + this.h3) >>> 0;183
k3 = Math.imul(rotl32(Math.imul(k3, 0x38b34ae5) >>> 0, 17), 0xa1e38b93) >>> 0; this.h3 ^= k3;184
this.h3 = (Math.imul(rotl32(this.h3, 15), 5) + 0x96cd1c35) >>> 0; this.h3 = (this.h3 + this.h4) >>> 0;185
k4 = Math.imul(rotl32(Math.imul(k4, 0xa1e38b93) >>> 0, 18), 0x239b961b) >>> 0; this.h4 ^= k4;186
this.h4 = (Math.imul(rotl32(this.h4, 13), 5) + 0x32ac3b17) >>> 0; this.h4 = (this.h4 + this.h1) >>> 0;187
}188
digest() {189
const tail = this.tail; let k1 = 0; let k2 = 0; let k3 = 0; let k4 = 0;190
for (let index = tail.length - 1; index >= 12; index -= 1) k4 ^= tail[index] << ((index - 12) * 8);191
if (tail.length > 12) { k4 = Math.imul(rotl32(Math.imul(k4, 0xa1e38b93) >>> 0, 18), 0x239b961b) >>> 0; this.h4 ^= k4; }192
for (let index = Math.min(tail.length - 1, 11); index >= 8; index -= 1) k3 ^= tail[index] << ((index - 8) * 8);193
if (tail.length > 8) { k3 = Math.imul(rotl32(Math.imul(k3, 0x38b34ae5) >>> 0, 17), 0xa1e38b93) >>> 0; this.h3 ^= k3; }194
for (let index = Math.min(tail.length - 1, 7); index >= 4; index -= 1) k2 ^= tail[index] << ((index - 4) * 8);195
if (tail.length > 4) { k2 = Math.imul(rotl32(Math.imul(k2, 0xab0e9789) >>> 0, 16), 0x38b34ae5) >>> 0; this.h2 ^= k2; }196
for (let index = Math.min(tail.length - 1, 3); index >= 0; index -= 1) k1 ^= tail[index] << (index * 8);197
if (tail.length) { k1 = Math.imul(rotl32(Math.imul(k1, 0x239b961b) >>> 0, 15), 0xab0e9789) >>> 0; this.h1 ^= k1; }198
const length = Number(this.length & 0xffffffffn);199
this.h1 ^= length; this.h2 ^= length; this.h3 ^= length; this.h4 ^= length;200
this.h1 = (this.h1 + this.h2 + this.h3 + this.h4) >>> 0;201
this.h2 = (this.h2 + this.h1) >>> 0; this.h3 = (this.h3 + this.h1) >>> 0; this.h4 = (this.h4 + this.h1) >>> 0;202
this.h1 = fmix32(this.h1); this.h2 = fmix32(this.h2); this.h3 = fmix32(this.h3); this.h4 = fmix32(this.h4);203
this.h1 = (this.h1 + this.h2 + this.h3 + this.h4) >>> 0;204
this.h2 = (this.h2 + this.h1) >>> 0; this.h3 = (this.h3 + this.h1) >>> 0; this.h4 = (this.h4 + this.h1) >>> 0;205
const output = Buffer.alloc(16); output.writeUInt32BE(this.h1, 0); output.writeUInt32BE(this.h2, 4); output.writeUInt32BE(this.h3, 8); output.writeUInt32BE(this.h4, 12); return output;206
}207
}209
class MurmurX64_128 extends BlockHash {210
constructor(seed = 0) { super(16); this.h1 = BigInt(seed) & MASK64; this.h2 = this.h1; }211
_block(data, offset) {212
let k1 = data.readBigUInt64LE(offset); let k2 = data.readBigUInt64LE(offset + 8);213
k1 = u64(rotl64(u64(k1 * 0x87c37b91114253d5n), 31) * 0x4cf5ad432745937fn); this.h1 ^= k1;214
this.h1 = u64(rotl64(this.h1, 27) + this.h2); this.h1 = u64(this.h1 * 5n + 0x52dce729n);215
k2 = u64(rotl64(u64(k2 * 0x4cf5ad432745937fn), 33) * 0x87c37b91114253d5n); this.h2 ^= k2;216
this.h2 = u64(rotl64(this.h2, 31) + this.h1); this.h2 = u64(this.h2 * 5n + 0x38495ab5n);217
}218
digest() {219
let k1 = 0n; let k2 = 0n;220
for (let index = this.tail.length - 1; index >= 8; index -= 1) k2 ^= BigInt(this.tail[index]) << BigInt((index - 8) * 8);221
if (this.tail.length > 8) { k2 = u64(rotl64(u64(k2 * 0x4cf5ad432745937fn), 33) * 0x87c37b91114253d5n); this.h2 ^= k2; }222
for (let index = Math.min(this.tail.length - 1, 7); index >= 0; index -= 1) k1 ^= BigInt(this.tail[index]) << BigInt(index * 8);223
if (this.tail.length) { k1 = u64(rotl64(u64(k1 * 0x87c37b91114253d5n), 31) * 0x4cf5ad432745937fn); this.h1 ^= k1; }224
this.h1 ^= this.length; this.h2 ^= this.length;225
this.h1 = u64(this.h1 + this.h2); this.h2 = u64(this.h2 + this.h1);226
this.h1 = fmix64(this.h1); this.h2 = fmix64(this.h2);227
this.h1 = u64(this.h1 + this.h2); this.h2 = u64(this.h2 + this.h1);228
const output = Buffer.alloc(16); output.writeBigUInt64BE(this.h1, 0); output.writeBigUInt64BE(this.h2, 8); return output;229
}230
}232
class SipHash24 extends BlockHash {233
constructor(key) {234
super(8);235
const k0 = key.readBigUInt64LE(0); const k1 = key.readBigUInt64LE(8);236
this.v0 = 0x736f6d6570736575n ^ k0; this.v1 = 0x646f72616e646f6dn ^ k1;237
this.v2 = 0x6c7967656e657261n ^ k0; this.v3 = 0x7465646279746573n ^ k1;238
}239
_round() {240
this.v0 = u64(this.v0 + this.v1); this.v1 = rotl64(this.v1, 13); this.v1 ^= this.v0; this.v0 = rotl64(this.v0, 32);241
this.v2 = u64(this.v2 + this.v3); this.v3 = rotl64(this.v3, 16); this.v3 ^= this.v2;242
this.v0 = u64(this.v0 + this.v3); this.v3 = rotl64(this.v3, 21); this.v3 ^= this.v0;243
this.v2 = u64(this.v2 + this.v1); this.v1 = rotl64(this.v1, 17); this.v1 ^= this.v2; this.v2 = rotl64(this.v2, 32);244
}245
_compress(message) { this.v3 ^= message; this._round(); this._round(); this.v0 ^= message; }246
_block(data, offset) { this._compress(data.readBigUInt64LE(offset)); }247
digest() {248
let final = (this.length & 0xffn) << 56n;249
for (let index = 0; index < this.tail.length; index += 1) final |= BigInt(this.tail[index]) << BigInt(index * 8);250
this._compress(final); this.v2 ^= 0xffn;251
this._round(); this._round(); this._round(); this._round();252
const output = Buffer.alloc(8); output.writeBigUInt64BE(u64(this.v0 ^ this.v1 ^ this.v2 ^ this.v3)); return output;253
}254
}256
function createPortableHash(request) {257
const seed = BigInt(request.seed || "0");258
switch (request.id) {259
case "tiger": return new TigerHash(false);260
case "tiger2": return new TigerHash(true);261
case "murmur3-x86-32": return new MurmurX86_32(seed);262
case "murmur3-x86-128": return new MurmurX86_128(seed);263
case "murmur3-x64-128": return new MurmurX64_128(seed);264
case "siphash-2-4": return new SipHash24(Buffer.from(request.keyHex, "hex"));265
case "fnv1-32": return new FnvHash(32, "1");266
case "fnv1-64": return new FnvHash(64, "1");267
case "fnv1a-32": return new FnvHash(32, "1a");268
case "fnv1a-64": return new FnvHash(64, "1a");269
case "crc16-ccitt-false": return new Crc16CcittFalse();270
case "crc64-ecma": return new Crc64(false);271
case "crc64-xz": return new Crc64(true);272
default: return null;273
}274
}276
module.exports = {277
Crc16CcittFalse,278
Crc64,279
FnvHash,280
MurmurX64_128,281
MurmurX86_32,282
MurmurX86_128,283
SipHash24,284
TigerHash,285
createPortableHash286
};SHA-256: ea6fda1d22d3adc3f286388d465e34421850bdacfddb47106553eb122ff67fd9
Archive SHA-256: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0