ai项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

113 lines
4.1 KiB

// ds.js —— 无需 fs-extra 的版本(CommonJS)
const fs = require('fs').promises; // 用内置 fs.promises
class DeepSeekHash {
constructor() {
this.wasmInstance = null;
this.offset = 0;
this.cachedUint8Memory = null;
this.cachedTextEncoder = new TextEncoder();
this._lastBufferRef = null; // 记录上次的 buffer,内存增长时刷新
}
_refreshIfNeeded() {
const buf = this.wasmInstance.memory.buffer;
if (this._lastBufferRef !== buf) {
this.cachedUint8Memory = new Uint8Array(buf);
this._lastBufferRef = buf;
}
}
getCachedUint8Memory() {
if (!this.wasmInstance || !this.wasmInstance.memory) {
throw new Error('WASM instance not initialized');
}
this._refreshIfNeeded();
return this.cachedUint8Memory;
}
encodeString(text, allocate, reallocate) {
if (!reallocate) {
const encoded = this.cachedTextEncoder.encode(text);
const ptr = allocate(encoded.length, 1) >>> 0;
const memory = this.getCachedUint8Memory();
memory.subarray(ptr, ptr + encoded.length).set(encoded);
this.offset = encoded.length;
return ptr;
}
const strLength = text.length;
let ptr = allocate(strLength, 1) >>> 0;
const memory = this.getCachedUint8Memory();
let asciiLength = 0;
for (; asciiLength < strLength; asciiLength++) {
const cc = text.charCodeAt(asciiLength);
if (cc > 127) break;
memory[ptr + asciiLength] = cc;
}
if (asciiLength !== strLength) {
if (asciiLength > 0) text = text.slice(asciiLength);
ptr = reallocate(ptr, strLength, asciiLength + text.length * 3, 1) >>> 0;
const view = this.getCachedUint8Memory().subarray(
ptr + asciiLength,
ptr + asciiLength + text.length * 3
);
const res = this.cachedTextEncoder.encodeInto(text, view);
asciiLength += res.written;
ptr = reallocate(ptr, asciiLength + text.length * 3, asciiLength, 1) >>> 0;
}
this.offset = asciiLength;
return ptr;
}
calculateHash(algorithm, challenge, salt, difficulty, expireAt) {
if (algorithm !== 'DeepSeekHashV1') {
throw new Error('Unsupported algorithm: ' + algorithm);
}
const prefix = `${salt}_${expireAt}_`;
let retptr;
try {
retptr = this.wasmInstance.__wbindgen_add_to_stack_pointer(-16);
const ptr0 = this.encodeString(
challenge,
this.wasmInstance.__wbindgen_export_0,
this.wasmInstance.__wbindgen_export_1
);
const len0 = this.offset;
const ptr1 = this.encodeString(
prefix,
this.wasmInstance.__wbindgen_export_0,
this.wasmInstance.__wbindgen_export_1
);
const len1 = this.offset;
this.wasmInstance.wasm_solve(retptr, ptr0, len0, ptr1, len1, difficulty);
// 读取返回(注意内存可能增长,先刷新)
this._refreshIfNeeded();
const dv = new DataView(this.wasmInstance.memory.buffer);
const status = dv.getInt32(retptr + 0, true);
const value = dv.getFloat64(retptr + 8, true);
if (status === 0) return undefined;
return value;
} finally {
if (retptr !== undefined) {
this.wasmInstance.__wbindgen_add_to_stack_pointer(16);
}
}
}
async init(wasmPath) {
const imports = { wbg: {} }; // 若报缺少导入,需改用对应的 glue JS
const wasmBuffer = await fs.readFile(wasmPath);
const { instance } = await WebAssembly.instantiate(wasmBuffer, imports);
this.wasmInstance = instance.exports;
this._lastBufferRef = this.wasmInstance.memory.buffer;
this.cachedUint8Memory = new Uint8Array(this._lastBufferRef);
return this.wasmInstance;
}
}
module.exports = DeepSeekHash;