import base64 import ctypes import json import logging import struct import time from wasmtime import Linker, Module, Store from . import constants, session as session_module from .account import choose_new_account, login_deepseek_via_account, release_account from .constants import get_account_identifier logger = logging.getLogger(__name__) # ---------------------------------------------------------------------- # 使用 WASM 模块计算 PoW 答案的辅助函数 # ---------------------------------------------------------------------- def compute_pow_answer( algorithm: str, challenge_str: str, salt: str, difficulty: int, expire_at: int, signature: str, target_path: str, wasm_path: str, ) -> int: """ 使用 WASM 模块计算 DeepSeekHash 答案(answer)。 根据 JS 逻辑: - 拼接前缀: "{salt}_{expire_at}_" - 将 challenge 与前缀写入 wasm 内存后调用 wasm_solve 进行求解, - 从 wasm 内存中读取状态与求解结果, - 若状态非 0,则返回整数形式的答案,否则返回 None。 """ if algorithm != "DeepSeekHashV1": raise ValueError(f"不支持的算法:{algorithm}") prefix = f"{salt}_{expire_at}_" # --- 加载 wasm 模块 --- store = Store() linker = Linker(store.engine) try: with open(wasm_path, "rb") as f: wasm_bytes = f.read() except Exception as e: raise RuntimeError(f"加载 wasm 文件失败: {wasm_path}, 错误: {e}") module = Module(store.engine, wasm_bytes) instance = linker.instantiate(store, module) exports = instance.exports(store) try: memory = exports["memory"] add_to_stack = exports["__wbindgen_add_to_stack_pointer"] alloc = exports["__wbindgen_export_0"] wasm_solve = exports["wasm_solve"] except KeyError as e: raise RuntimeError(f"缺少 wasm 导出函数: {e}") def write_memory(offset: int, data: bytes): size = len(data) base_addr = ctypes.cast(memory.data_ptr(store), ctypes.c_void_p).value ctypes.memmove(base_addr + offset, data, size) def read_memory(offset: int, size: int) -> bytes: base_addr = ctypes.cast(memory.data_ptr(store), ctypes.c_void_p).value return ctypes.string_at(base_addr + offset, size) def encode_string(text: str): data = text.encode("utf-8") length = len(data) ptr_val = alloc(store, length, 1) ptr = int(ptr_val.value) if hasattr(ptr_val, "value") else int(ptr_val) write_memory(ptr, data) return ptr, length # 1. 申请 16 字节栈空间 retptr = add_to_stack(store, -16) # 2. 编码 challenge 与 prefix 到 wasm 内存中 ptr_challenge, len_challenge = encode_string(challenge_str) ptr_prefix, len_prefix = encode_string(prefix) # 3. 调用 wasm_solve(注意:difficulty 以 float 形式传入) wasm_solve( store, retptr, ptr_challenge, len_challenge, ptr_prefix, len_prefix, float(difficulty), ) # 4. 从 retptr 处读取 4 字节状态和 8 字节求解结果 status_bytes = read_memory(retptr, 4) if len(status_bytes) != 4: add_to_stack(store, 16) raise RuntimeError("读取状态字节失败") status = struct.unpack("