Spaces:
Paused
Paused
| 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 = ["_reactListeningo743lnnpvdg", "location"] | |
| 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 [ | |
| random.choice([3000, 4000, 5000]), | |
| _legacy_parse_time(), | |
| 4294705152, | |
| 0, | |
| user_agent, | |
| script_source, | |
| data_build, | |
| "en-US", | |
| "en-US,es-US,en,es", | |
| 0, | |
| navigator_key, | |
| random.choice(DOCUMENT_KEYS), | |
| window_key, | |
| time.perf_counter() * 1000, | |
| new_uuid(), | |
| "", | |
| random.choice(CORES), | |
| time.time() * 1000 - (time.perf_counter() * 1000), | |
| ] | |
| 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: | |
| seed = format(random.random()) | |
| config = build_pow_config(user_agent, script_sources=script_sources, data_build=data_build) | |
| answer, _ = _pow_generate(seed, "0fffff", config) | |
| return "gAAAAAC" + answer | |
| 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 | |