-
Notifications
You must be signed in to change notification settings - Fork 2
/
mod.ts
89 lines (75 loc) · 1.93 KB
/
mod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
export function crc32(arr: Uint8Array | string): string {
if (typeof arr === "string") {
arr = new TextEncoder().encode(arr);
}
let crc = -1, i, j, l, temp, poly = 0xEDB88320;
for (i = 0, l = arr.length; i < l; i += 1) {
temp = (crc ^ arr[i]) & 0xff;
for (j = 0; j < 8; j += 1) {
if ((temp & 1) === 1) {
temp = (temp >>> 1) ^ poly;
} else {
temp = (temp >>> 1);
}
}
crc = (crc >>> 8) ^ temp;
}
return numberToHex(crc ^ -1);
}
export class Crc32Stream {
private bytes: number[] = [];
private poly = 0xEDB88320;
private crc = 0 ^ -1;
private encoder = new TextEncoder();
#crc32: string = "";
constructor() {
this.reset();
}
get crc32(): string {
return this.#crc32;
}
reset(): void {
this.#crc32 = "";
this.crc = 0 ^ -1;
for (let n = 0; n < 256; n += 1) {
let c = n;
for (let k = 0; k < 8; k += 1) {
if (c & 1) {
c = this.poly ^ (c >>> 1);
} else {
c = c >>> 1;
}
}
this.bytes[n] = c >>> 0;
}
}
append(arr: Uint8Array | string): string {
if (typeof arr === "string") {
arr = this.encoder.encode(arr);
}
let crc = this.crc;
for (let i = 0, l = arr.length; i < l; i += 1) {
crc = (crc >>> 8) ^ this.bytes[(crc ^ arr[i]) & 0xff];
}
this.crc = crc;
this.#crc32 = numberToHex(crc ^ -1);
return this.#crc32;
}
}
export function numberToHex(n: number): string {
return (n >>> 0).toString(16).padStart(8, "0");
}
export function hexToUint8Array(str: string): Uint8Array {
if (str.length === 0 || str.length % 2 !== 0) {
throw new Error(`The string "${str}" is not valid hex.`);
}
return new Uint8Array(
str.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)),
);
}
export function uint8ArrayToHex(bytes: Uint8Array): string {
return bytes.reduce(
(str, byte) => str + byte.toString(16).padStart(2, "0"),
"",
);
}