import time import json import base64 from typing import List DEBUG = True class ProofOfWorkSolver: """解决 OpenAI Sentinel 的 Proof of Work challenge""" def __init__(self): # FNV-1a 常量 self.FNV_OFFSET = 2166136261 self.FNV_PRIME = 16777619 def fnv1a_hash(self, data: str) -> str: """FNV-1a hash 算法""" hash_value = self.FNV_OFFSET for char in data: hash_value ^= ord(char) hash_value = (hash_value * self.FNV_PRIME) & 0xFFFFFFFF # 额外的混合步骤(从 JS 代码复制) hash_value ^= hash_value >> 16 hash_value = (hash_value * 2246822507) & 0xFFFFFFFF hash_value ^= hash_value >> 13 hash_value = (hash_value * 3266489909) & 0xFFFFFFFF hash_value ^= hash_value >> 16 # 转为 8 位十六进制字符串 return format(hash_value, '08x') def serialize_array(self, arr: List) -> str: """模拟 JS 的 T() 函数:JSON.stringify + Base64""" json_str = json.dumps(arr, separators=(',', ':')) return base64.b64encode(json_str.encode()).decode() def build_fingerprint_array(self, nonce: int, elapsed_ms: int) -> List: """构建指纹数组(简化版)""" return [ 0, # [0] screen dimensions "", # [1] timestamp 0, # [2] memory nonce, # [3] nonce ← 关键 "", # [4] user agent "", # [5] random element "", # [6] script src "", # [7] language "", # [8] languages elapsed_ms, # [9] elapsed time ← 关键 "", # [10] random function "", # [11] keys "", # [12] window keys 0, # [13] performance.now() "", # [14] uuid "", # [15] URL params 0, # [16] hardware concurrency 0 # [17] timeOrigin ] def solve(self, seed: str, difficulty: str, max_iterations: int = 10000000) -> str: """ 解决 PoW challenge Args: seed: Challenge seed difficulty: 目标难度(十六进制字符串) max_iterations: 最大尝试次数 Returns: 序列化的答案(包含 nonce) """ if DEBUG: print(f"[PoW] Solving challenge:") print(f" Seed: {seed}") print(f" Difficulty: {difficulty}") start_time = time.time() for nonce in range(max_iterations): elapsed_ms = int((time.time() - start_time) * 1000) # 构建指纹数组 fingerprint = self.build_fingerprint_array(nonce, elapsed_ms) # 序列化 serialized = self.serialize_array(fingerprint) # 计算 hash(seed + serialized) hash_input = seed + serialized hash_result = self.fnv1a_hash(hash_input) # 检查是否满足难度要求 # 比较方式:hash 的前 N 位(作为整数)<= difficulty(作为整数) difficulty_len = len(difficulty) hash_prefix = hash_result[:difficulty_len] if hash_prefix <= difficulty: elapsed = time.time() - start_time if DEBUG: print(f"[PoW] ✓ Found solution in {elapsed:.2f}s") print(f" Nonce: {nonce}") print(f" Hash: {hash_result}") print(f" Serialized: {serialized[:100]}...") # 返回 serialized + "~S" (表示成功) return serialized + "~S" # 每 100k 次迭代打印进度 if DEBUG and nonce > 0 and nonce % 100000 == 0: print(f"[PoW] Tried {nonce:,} iterations...") raise Exception(f"Failed to solve PoW after {max_iterations:,} iterations")