清理代码
This commit is contained in:
@@ -1,81 +1,175 @@
|
||||
"""
|
||||
浏览器指纹生成模块
|
||||
|
||||
用于生成符合 OpenAI Sentinel 要求的浏览器指纹配置数组
|
||||
"""
|
||||
# modules/fingerprint.py
|
||||
"""浏览器指纹生成器"""
|
||||
|
||||
import uuid
|
||||
import random
|
||||
import time
|
||||
from typing import List
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Any
|
||||
|
||||
from config import load_config
|
||||
|
||||
|
||||
class BrowserFingerprint:
|
||||
"""
|
||||
浏览器指纹生成器
|
||||
|
||||
生成 Sentinel SDK 所需的配置数组(18 个元素)
|
||||
"""
|
||||
"""生成符合 SDK 期望的浏览器指纹"""
|
||||
|
||||
def __init__(self, session_id: str = None):
|
||||
"""
|
||||
初始化浏览器指纹
|
||||
|
||||
参数:
|
||||
session_id: 会话 ID(oai-did),如果不提供则自动生成
|
||||
"""
|
||||
self.session_id = session_id or str(uuid.uuid4())
|
||||
self.start_time = time.time()
|
||||
|
||||
def get_config_array(self) -> List:
|
||||
# 新增: 使用确定性方法从 session_id 派生 Stripe 指纹
|
||||
import hashlib
|
||||
seed = hashlib.sha256(self.session_id.encode()).hexdigest()
|
||||
# seed 是64个hex字符,我们需要确保切片正确
|
||||
|
||||
# 从 seed 生成一致的 guid/muid/sid
|
||||
# UUID需要32个hex字符(去掉连字符),额外部分直接拼接
|
||||
self.stripe_guid = seed[:8] + '-' + seed[8:12] + '-' + seed[12:16] + '-' + seed[16:20] + '-' + seed[20:32] + seed[32:40]
|
||||
self.stripe_muid = seed[:8] + '-' + seed[8:12] + '-' + seed[12:16] + '-' + seed[16:20] + '-' + seed[20:32] + seed[40:46]
|
||||
self.stripe_sid = seed[:8] + '-' + seed[8:12] + '-' + seed[12:16] + '-' + seed[16:20] + '-' + seed[20:32] + seed[46:52]
|
||||
|
||||
# 从配置加载指纹参数
|
||||
config = load_config()
|
||||
fingerprint_cfg = config.fingerprint_config
|
||||
|
||||
self.user_agent = fingerprint_cfg['user_agent']
|
||||
self.screen_width = fingerprint_cfg['screen_width']
|
||||
self.screen_height = fingerprint_cfg['screen_height']
|
||||
self.languages = fingerprint_cfg['languages']
|
||||
self.hardware_concurrency = fingerprint_cfg['hardware_concurrency']
|
||||
|
||||
def get_config_array(self) -> List[Any]:
|
||||
"""
|
||||
获取 Sentinel SDK 配置数组
|
||||
生成 SDK getConfig() 函数返回的 18 元素数组
|
||||
|
||||
返回:
|
||||
包含 18 个元素的指纹数组
|
||||
|
||||
数组结构(从 JS 逆向):
|
||||
[0] screen dimensions (width*height)
|
||||
[1] timestamp
|
||||
[2] memory (hardwareConcurrency)
|
||||
[3] nonce (动态值,PoW 时会修改)
|
||||
[4] user agent
|
||||
[5] random element
|
||||
[6] script src
|
||||
[7] language
|
||||
[8] languages (joined)
|
||||
[9] elapsed time (ms)
|
||||
[10] random function test
|
||||
[11] keys
|
||||
[12] window keys
|
||||
[13] performance.now()
|
||||
[14] uuid (session_id)
|
||||
[15] URL params
|
||||
[16] hardware concurrency
|
||||
[17] timeOrigin
|
||||
对应 SDK 源码:
|
||||
[0]: screen.width + screen.height
|
||||
[1]: new Date().toString()
|
||||
[2]: performance.memory.jsHeapSizeLimit (可选)
|
||||
[3]: nonce (PoW 填充)
|
||||
[4]: navigator.userAgent
|
||||
[5]: 随机 script.src
|
||||
[6]: build ID
|
||||
[7]: navigator.language
|
||||
[8]: navigator.languages.join(',')
|
||||
[9]: 运行时间 (PoW 填充)
|
||||
[10]: 随机 navigator 属性
|
||||
[11]: 随机 document key
|
||||
[12]: 随机 window key
|
||||
[13]: performance.now()
|
||||
[14]: session UUID
|
||||
[15]: URL search params
|
||||
[16]: navigator.hardwareConcurrency
|
||||
[17]: performance.timeOrigin
|
||||
"""
|
||||
elapsed_ms = int((time.time() - self.start_time) * 1000)
|
||||
|
||||
# 模拟的 script sources
|
||||
fake_scripts = [
|
||||
"https://sentinel.openai.com/sentinel/97790f37/sdk.js",
|
||||
"https://chatgpt.com/static/js/main.abc123.js",
|
||||
"https://cdn.oaistatic.com/_next/static/chunks/main.js",
|
||||
]
|
||||
|
||||
# 模拟的 navigator 属性名
|
||||
navigator_props = [
|
||||
'hardwareConcurrency', 'language', 'languages',
|
||||
'platform', 'userAgent', 'vendor'
|
||||
]
|
||||
|
||||
# 模拟的 document keys
|
||||
document_keys = ['body', 'head', 'documentElement', 'scripts']
|
||||
|
||||
# 模拟的 window keys
|
||||
window_keys = ['performance', 'navigator', 'document', 'location']
|
||||
|
||||
current_time = time.time() * 1000
|
||||
|
||||
return [
|
||||
1920 * 1080, # [0] screen dimensions
|
||||
str(int(time.time() * 1000)), # [1] timestamp
|
||||
8, # [2] hardware concurrency
|
||||
0, # [3] nonce (placeholder)
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36", # [4] UA
|
||||
str(0.123456789), # [5] random element
|
||||
"https://chatgpt.com/_next/static/chunks/sentinel.js", # [6] script src
|
||||
"en-US", # [7] language
|
||||
"en-US,en", # [8] languages
|
||||
elapsed_ms, # [9] elapsed time
|
||||
"", # [10] random function
|
||||
"", # [11] keys
|
||||
"", # [12] window keys
|
||||
elapsed_ms, # [13] performance.now()
|
||||
self.session_id, # [14] uuid (oai-did)
|
||||
"", # [15] URL params
|
||||
8, # [16] hardware concurrency
|
||||
int(time.time() * 1000) - elapsed_ms, # [17] timeOrigin
|
||||
self.screen_width + self.screen_height, # [0]
|
||||
str(datetime.now()), # [1]
|
||||
None, # [2] memory
|
||||
None, # [3] nonce (placeholder)
|
||||
self.user_agent, # [4]
|
||||
random.choice(fake_scripts), # [5]
|
||||
"97790f37", # [6] build ID
|
||||
self.languages[0], # [7]
|
||||
",".join(self.languages), # [8]
|
||||
None, # [9] runtime (placeholder)
|
||||
f"{random.choice(navigator_props)}−{random.randint(1, 16)}", # [10]
|
||||
random.choice(document_keys), # [11]
|
||||
random.choice(window_keys), # [12]
|
||||
current_time, # [13]
|
||||
self.session_id, # [14]
|
||||
"", # [15] URL params
|
||||
self.hardware_concurrency, # [16]
|
||||
current_time - random.uniform(100, 1000), # [17] timeOrigin
|
||||
]
|
||||
|
||||
def get_cookies(self) -> Dict[str, str]:
|
||||
"""生成初始 cookies"""
|
||||
return {
|
||||
'oai-did': self.session_id,
|
||||
}
|
||||
|
||||
def get_stripe_fingerprint(self) -> Dict[str, str]:
|
||||
"""获取 Stripe 支付指纹(与 session_id 一致派生)"""
|
||||
return {
|
||||
'guid': self.stripe_guid,
|
||||
'muid': self.stripe_muid,
|
||||
'sid': self.stripe_sid,
|
||||
}
|
||||
|
||||
def get_headers(self, with_sentinel: str = None, host: str = 'auth.openai.com') -> Dict[str, str]:
|
||||
"""生成 HTTP headers(支持多域名)"""
|
||||
|
||||
# 基础 headers
|
||||
headers = {
|
||||
'User-Agent': self.user_agent,
|
||||
'Accept': 'application/json',
|
||||
'Accept-Language': f"{self.languages[0]},{self.languages[1]};q=0.5",
|
||||
# Note: urllib3/requests only auto-decompress brotli/zstd when optional
|
||||
# deps are installed; avoid advertising unsupported encodings.
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Connection': 'keep-alive',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Sec-Fetch-Site': 'same-origin',
|
||||
'Priority': 'u=1, i',
|
||||
'Pragma': 'no-cache',
|
||||
'Cache-Control': 'no-cache',
|
||||
}
|
||||
|
||||
# 根据域名设置特定 headers
|
||||
if 'chatgpt.com' in host:
|
||||
headers.update({
|
||||
'Origin': 'https://chatgpt.com',
|
||||
'Referer': 'https://chatgpt.com/',
|
||||
})
|
||||
else:
|
||||
headers.update({
|
||||
'Origin': 'https://auth.openai.com',
|
||||
'Referer': 'https://auth.openai.com/create-account/password',
|
||||
'Content-Type': 'application/json',
|
||||
})
|
||||
|
||||
# Sentinel token
|
||||
if with_sentinel:
|
||||
headers['openai-sentinel-token'] = with_sentinel
|
||||
|
||||
# Datadog RUM tracing
|
||||
trace_id = random.randint(10**18, 10**19 - 1)
|
||||
parent_id = random.randint(10**18, 10**19 - 1)
|
||||
|
||||
headers.update({
|
||||
'traceparent': f'00-0000000000000000{trace_id:016x}-{parent_id:016x}-01',
|
||||
'tracestate': 'dd=s:1;o:rum',
|
||||
'x-datadog-origin': 'rum',
|
||||
'x-datadog-parent-id': str(parent_id),
|
||||
'x-datadog-sampling-priority': '1',
|
||||
'x-datadog-trace-id': str(trace_id),
|
||||
})
|
||||
|
||||
return headers
|
||||
|
||||
|
||||
# 导出
|
||||
__all__ = ["BrowserFingerprint"]
|
||||
|
||||
Reference in New Issue
Block a user