Files
autoPlus/reference/pow_solver.py
2026-01-26 15:04:02 +08:00

115 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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")