26 包 monorepo(TS 全源码): - snowcat-core: NT 内核 API 封装 + listener(含 9.9.37 六回调适配)+ Packet 发包 - snowcat-onebot: OneBot v11 全动作 + MCP Streamable HTTP 适配器 + 稳定线 - snowcat-webui-frontend/backend: 雪猫控制台(React+HeroUI) - snowcat-shell: 单文件 bundle 出口(vite inlineDynamicImports) - snowcat-native: napi2native / MoeHoo / ffmpeg / pty 运行时 - 56 项 SnowLuma 独门动作移植(qzone 全家桶/群相册/装扮/闪照/收藏) - 工具件: 解包器/启动器/便携制作器/doctor GitHub 关联已全量指向 DandanLLab/SnowCatQQ
126 lines
3.6 KiB
TypeScript
126 lines
3.6 KiB
TypeScript
// @ts-nocheck
|
|
export class Sha1Stream {
|
|
readonly Sha1BlockSize = 64;
|
|
readonly Sha1DigestSize = 20;
|
|
private readonly _padding = Buffer.concat([Buffer.from([0x80]), Buffer.alloc(63)]);
|
|
private readonly _state = new Uint32Array(5);
|
|
private readonly _count = new Uint32Array(2);
|
|
private readonly _buffer = Buffer.allocUnsafe(this.Sha1BlockSize);
|
|
private readonly _w = new Uint32Array(80);
|
|
|
|
constructor () {
|
|
this.reset();
|
|
}
|
|
|
|
private reset (): void {
|
|
this._state[0] = 0x67452301;
|
|
this._state[1] = 0xEFCDAB89;
|
|
this._state[2] = 0x98BADCFE;
|
|
this._state[3] = 0x10325476;
|
|
this._state[4] = 0xC3D2E1F0;
|
|
this._count[0] = 0;
|
|
this._count[1] = 0;
|
|
this._buffer.fill(0);
|
|
}
|
|
|
|
private rotateLeft (v: number, o: number): number {
|
|
return ((v << o) | (v >>> (32 - o))) >>> 0;
|
|
}
|
|
|
|
private transform (chunk: Buffer, offset: number): void {
|
|
const w = this._w;
|
|
const view = new DataView(chunk.buffer, chunk.byteOffset + offset, 64);
|
|
|
|
for (let i = 0; i < 16; i++) {
|
|
w[i] = view.getUint32(i * 4, false);
|
|
}
|
|
|
|
for (let i = 16; i < 80; i++) {
|
|
w[i] = this.rotateLeft(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1) >>> 0;
|
|
}
|
|
|
|
let a = this._state[0];
|
|
let b = this._state[1];
|
|
let c = this._state[2];
|
|
let d = this._state[3];
|
|
let e = this._state[4];
|
|
|
|
for (let i = 0; i < 80; i++) {
|
|
let temp;
|
|
if (i < 20) {
|
|
temp = ((b & c) | (~b & d)) + 0x5A827999;
|
|
} else if (i < 40) {
|
|
temp = (b ^ c ^ d) + 0x6ED9EBA1;
|
|
} else if (i < 60) {
|
|
temp = ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC;
|
|
} else {
|
|
temp = (b ^ c ^ d) + 0xCA62C1D6;
|
|
}
|
|
temp += ((this.rotateLeft(a, 5) + e + w[i]) >>> 0);
|
|
e = d;
|
|
d = c;
|
|
c = this.rotateLeft(b, 30) >>> 0;
|
|
b = a;
|
|
a = temp;
|
|
}
|
|
|
|
this._state[0] = (this._state[0] + a) >>> 0;
|
|
this._state[1] = (this._state[1] + b) >>> 0;
|
|
this._state[2] = (this._state[2] + c) >>> 0;
|
|
this._state[3] = (this._state[3] + d) >>> 0;
|
|
this._state[4] = (this._state[4] + e) >>> 0;
|
|
}
|
|
|
|
public update (data: Buffer, len?: number): void {
|
|
let index = ((this._count[0] >>> 3) & 0x3F) >>> 0;
|
|
const dataLen = len ?? data.length;
|
|
this._count[0] = (this._count[0] + (dataLen << 3)) >>> 0;
|
|
|
|
if (this._count[0] < (dataLen << 3)) this._count[1] = (this._count[1] + 1) >>> 0;
|
|
|
|
this._count[1] = (this._count[1] + (dataLen >>> 29)) >>> 0;
|
|
|
|
const partLen = (this.Sha1BlockSize - index) >>> 0;
|
|
let i = 0;
|
|
|
|
if (dataLen >= partLen) {
|
|
data.copy(this._buffer, index, 0, partLen);
|
|
this.transform(this._buffer, 0);
|
|
for (i = partLen; (i + this.Sha1BlockSize) <= dataLen; i = (i + this.Sha1BlockSize) >>> 0) {
|
|
this.transform(data, i);
|
|
}
|
|
index = 0;
|
|
}
|
|
|
|
data.copy(this._buffer, index, i, dataLen);
|
|
}
|
|
|
|
public hash (bigEndian: boolean = true): Buffer {
|
|
const digest = Buffer.allocUnsafe(this.Sha1DigestSize);
|
|
if (bigEndian) {
|
|
for (let i = 0; i < 5; i++) digest.writeUInt32BE(this._state[i], i * 4);
|
|
} else {
|
|
for (let i = 0; i < 5; i++) digest.writeUInt32LE(this._state[i], i * 4);
|
|
}
|
|
return digest;
|
|
}
|
|
|
|
public final (): Buffer {
|
|
const digest = Buffer.allocUnsafe(this.Sha1DigestSize);
|
|
const bits = Buffer.allocUnsafe(8);
|
|
bits.writeUInt32BE(this._count[1], 0);
|
|
bits.writeUInt32BE(this._count[0], 4);
|
|
|
|
const index = ((this._count[0] >>> 3) & 0x3F) >>> 0;
|
|
const padLen = ((index < 56) ? (56 - index) : (120 - index)) >>> 0;
|
|
this.update(this._padding, padLen);
|
|
this.update(bits);
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
digest.writeUInt32BE(this._state[i], i * 4);
|
|
}
|
|
|
|
return digest;
|
|
}
|
|
}
|