Initial project import

This commit is contained in:
XM
2026-09-18 03:46:58 +08:00
commit b600da4b76
209 changed files with 45904 additions and 0 deletions
+207
View File
@@ -0,0 +1,207 @@
import hashlib
import json
import random
import re
import time
from datetime import datetime, timedelta, timezone
from html.parser import HTMLParser
from typing import Any, Sequence
import pybase64
DEFAULT_POW_SCRIPT = "https://chatgpt.com/backend-api/sentinel/sdk.js"
from utils.helper import new_uuid
CORES = [8, 16, 24, 32]
DOCUMENT_KEYS = ["__reactContainer$fzelfjyxej8", "_reactListening5dehydibo78", "location"]
SCREEN_RESOLUTIONS = [[1920, 1080], [1440, 900], [2560, 1440], [3840, 2160]]
class ScriptSrcParser(HTMLParser):
def __init__(self) -> None:
super().__init__()
self.script_sources: list[str] = []
self.data_build = ""
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
if tag != "script":
return
attrs_dict = dict(attrs)
src = attrs_dict.get("src")
if not src:
return
self.script_sources.append(src)
match = re.search(r"c/[^/]*/_", src)
if match:
self.data_build = match.group(0)
def parse_pow_resources(html_content: str) -> tuple[list[str], str]:
parser = ScriptSrcParser()
parser.feed(html_content)
script_sources = parser.script_sources or [DEFAULT_POW_SCRIPT]
data_build = parser.data_build
if not data_build:
match = re.search(r'<html[^>]*data-build="([^"]*)"', html_content)
if match:
data_build = match.group(1)
return script_sources, data_build
def _legacy_parse_time() -> str:
now = datetime.now(timezone(timedelta(hours=-5)))
return now.strftime("%a %b %d %Y %H:%M:%S") + " GMT-0500 (Eastern Standard Time)"
def build_pow_config(
user_agent: str,
script_sources: Sequence[str] | None = None,
data_build: str = "",
) -> list[Any]:
navigator_key = random.choice([
"registerProtocolHandler−function registerProtocolHandler() { [native code] }",
"storage−[object StorageManager]",
"locks−[object LockManager]",
"appCodeName−Mozilla",
"permissions−[object Permissions]",
"share−function share() { [native code] }",
"webdriver−false",
"managed−[object NavigatorManagedData]",
"canShare−function canShare() { [native code] }",
"vendor−Google Inc.",
"mediaDevices−[object MediaDevices]",
"vibrate−function vibrate() { [native code] }",
"storageBuckets−[object StorageBucketManager]",
"mediaCapabilities−[object MediaCapabilities]",
"cookieEnabled−true",
"virtualKeyboard−[object VirtualKeyboard]",
"product−Gecko",
"presentation−[object Presentation]",
"onLine−true",
"mimeTypes−[object MimeTypeArray]",
"credentials−[object CredentialsContainer]",
"serviceWorker−[object ServiceWorkerContainer]",
"keyboard−[object Keyboard]",
"gpu−[object GPU]",
"doNotTrack",
"serial−[object Serial]",
"pdfViewerEnabled−true",
"language−zh-CN",
"geolocation−[object Geolocation]",
"userAgentData−[object NavigatorUAData]",
"getUserMedia−function getUserMedia() { [native code] }",
"sendBeacon−function sendBeacon() { [native code] }",
"hardwareConcurrency−32",
"windowControlsOverlay−[object WindowControlsOverlay]",
])
window_key = random.choice([
"0",
"window",
"self",
"document",
"name",
"location",
"customElements",
"history",
"navigation",
"innerWidth",
"innerHeight",
"scrollX",
"scrollY",
"visualViewport",
"screenX",
"screenY",
"outerWidth",
"outerHeight",
"devicePixelRatio",
"screen",
"chrome",
"navigator",
"onresize",
"performance",
"crypto",
"indexedDB",
"sessionStorage",
"localStorage",
"scheduler",
"alert",
"atob",
"btoa",
"fetch",
"matchMedia",
"postMessage",
"queueMicrotask",
"requestAnimationFrame",
"setInterval",
"setTimeout",
"caches",
"__NEXT_DATA__",
"__BUILD_MANIFEST",
"__NEXT_PRELOADREADY",
])
script_source = random.choice(list(script_sources)) if script_sources else DEFAULT_POW_SCRIPT
return [
sum(random.choices(SCREEN_RESOLUTIONS, k=1)[0]),
_legacy_parse_time(),
4294705152,
1,
user_agent,
script_source,
data_build,
"en-US",
"en-US,es-US,en,es",
random.random(),
navigator_key,
random.choice(DOCUMENT_KEYS),
window_key,
time.perf_counter() * 1000,
new_uuid(),
"",
random.choice(CORES),
time.time() * 1000 - (time.perf_counter() * 1000),
0, 0, 0, 0, 0, 0,
0, # 0 = edge/chrome, 1 = firefox
]
def _pow_generate(seed: str, difficulty: str, config: list[Any], limit: int = 500000) -> tuple[str, bool]:
target = bytes.fromhex(difficulty)
diff_len = len(difficulty) // 2
seed_bytes = seed.encode()
static_1 = (json.dumps(config[:3], separators=(",", ":"), ensure_ascii=False)[:-1] + ",").encode()
static_2 = ("," + json.dumps(config[4:9], separators=(",", ":"), ensure_ascii=False)[1:-1] + ",").encode()
static_3 = ("," + json.dumps(config[10:], separators=(",", ":"), ensure_ascii=False)[1:]).encode()
for i in range(limit):
final_json = static_1 + str(i).encode() + static_2 + str(i >> 1).encode() + static_3
encoded = pybase64.b64encode(final_json)
digest = hashlib.sha3_512(seed_bytes + encoded).digest()
if digest[:diff_len] <= target:
return encoded.decode(), True
fallback = "wQ8Lk5FbGpA2NcR9dShT6gYjU7VxZ4D" + pybase64.b64encode(f'"{seed}"'.encode()).decode()
return fallback, False
def build_legacy_requirements_token(
user_agent: str,
script_sources: Sequence[str] | None = None,
data_build: str = "",
) -> str:
config = build_pow_config(user_agent, script_sources=script_sources, data_build=data_build)
return "gAAAAAC" + pybase64.b64encode(
json.dumps(config, separators=(",", ":"), ensure_ascii=False).encode()
).decode()
def build_proof_token(
seed: str,
difficulty: str,
user_agent: str,
script_sources: Sequence[str] | None = None,
data_build: str = "",
) -> str:
config = build_pow_config(user_agent, script_sources=script_sources, data_build=data_build)
answer, solved = _pow_generate(seed, difficulty, config)
if not solved:
raise RuntimeError(f"failed to solve proof token: difficulty={difficulty}")
return "gAAAAAB" + answer