import random
import time
import base64
import hashlib
from typing import Dict, List, Any, Optional
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import json
# =========================
# DEFAULT TEMPLATE
# =========================
DEFAULT_TEMPLATE: Dict[str, Any] = {
"deviceId": "84985177a19a010dea49",
"sdkVersion": "websdk-2.3.15d",
"initTimestamp": "1765348410850",
"field3": "91",
"field4": "1|15",
"language": "zh-CN",
"timezoneOffset": "-480",
"colorDepth": "16705151|12791",
"screenInfo": "1470|956|283|797|158|0|1470|956|1470|798|0|0",
"field9": "5",
"platform": "MacIntel",
"field11": "10",
"webglRenderer": (
"ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)"
"|Google Inc. (Apple)"
),
"field13": "30|30",
"field14": "0",
"field15": "28",
"pluginCount": "5",
"vendor": "Google Inc.",
"field29": "8",
"touchInfo": "-1|0|0|0|0",
"field32": "11",
"field35": "0",
"mode": "P",
}
# =========================
# BX-UA GENERATOR
# =========================
class BXUAGenerator:
def __init__(self):
self.version = "231"
self.aes_key = None
self.aes_iv = None
def _generate_key_iv(self, seed_data: str) -> tuple:
"""Generate AES key and IV from seed data"""
# Create deterministic key/IV from seed
seed_hash = hashlib.sha256(seed_data.encode()).digest()
key = seed_hash[:16] # 128-bit key
iv = seed_hash[16:32] # 128-bit IV
return key, iv
def _encrypt_aes_cbc(self, data: bytes, key: bytes, iv: bytes) -> bytes:
"""Encrypt data using AES-CBC"""
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_data = pad(data, AES.block_size)
encrypted = cipher.encrypt(padded_data)
return encrypted
def _create_payload(self, fingerprint: str, timestamp: Optional[int] = None) -> Dict[str, Any]:
"""Create the payload structure to be encrypted"""
if timestamp is None:
timestamp = int(time.time() * 1000)
# Extract components from fingerprint
fields = fingerprint.split("^")
payload = {
"v": self.version,
"ts": timestamp,
"fp": fingerprint,
"d": {
"deviceId": fields[0],
"sdkVer": fields[1],
"lang": fields[5],
"tz": fields[6],
"platform": fields[10],
"renderer": fields[12],
"mode": fields[23],
"vendor": fields[28],
},
"rnd": random.randint(1000, 9999),
"seq": 1,
}
# Add checksum
checksum_str = f"{fingerprint}{timestamp}{payload['rnd']}"
payload["cs"] = hashlib.md5(checksum_str.encode()).hexdigest()[:8]
return payload
def generate(self, fingerprint: str, options: Optional[Dict[str, Any]] = None) -> str:
"""
Generate bx-ua header value
Args:
fingerprint: The fingerprint string generated by generate_fingerprint()
options: Optional configuration
- timestamp: Custom timestamp (default: current time)
- seed: Custom seed for key generation
"""
if options is None:
options = {}
# Get timestamp
timestamp = options.get("timestamp")
if timestamp is None:
timestamp = int(time.time() * 1000)
# Create payload
payload = self._create_payload(fingerprint, timestamp)
# Convert to JSON
payload_json = json.dumps(payload, separators=(',', ':'))
# Generate key and IV
seed = options.get("seed", fingerprint)
key, iv = self._generate_key_iv(seed)
# Encrypt
encrypted = self._encrypt_aes_cbc(payload_json.encode(), key, iv)
# Base64 encode
encrypted_b64 = base64.b64encode(encrypted).decode()
# Return in format: version!base64_encoded_data
return f"{self.version}!{encrypted_b64}"
def batch_generate(self, fingerprints: List[str], options: Optional[Dict[str, Any]] = None) -> List[str]:
"""Generate multiple bx-ua values"""
return [self.generate(fp, options) for fp in fingerprints]
# =========================
# FINGERPRINT GENERATOR (From your code)
# =========================
def generate_device_id() -> str:
"""Generate a 20-character hex device ID"""
return "".join(random.choice("0123456789abcdef") for _ in range(20))
def generate_hash() -> int:
"""Generate a 32-bit unsigned random hash"""
return random.randint(0, 0xFFFFFFFF)
def generate_fingerprint(options: Dict[str, Any] = None) -> str:
if options is None:
options = {}
config = DEFAULT_TEMPLATE.copy()
# platform preset
platform = options.get("platform")
if platform:
# Handle platform presets if needed
pass
# screen preset
screen = options.get("screen")
if screen:
# Handle screen presets if needed
pass
# language preset
locale = options.get("locale")
if locale:
# Handle language presets if needed
pass
# custom overrides
if "custom" in options and isinstance(options["custom"], dict):
config.update(options["custom"])
device_id = options.get("deviceId") or generate_device_id()
current_timestamp = int(time.time() * 1000)
plugin_hash = generate_hash()
canvas_hash = generate_hash()
ua_hash1 = generate_hash()
ua_hash2 = generate_hash()
url_hash = generate_hash()
doc_hash = random.randint(10, 100)
fields: List[Any] = [
device_id,
config["sdkVersion"],
config["initTimestamp"],
config["field3"],
config["field4"],
config["language"],
config["timezoneOffset"],
config["colorDepth"],
config["screenInfo"],
config["field9"],
config["platform"],
config["field11"],
config["webglRenderer"],
config["field13"],
config["field14"],
config["field15"],
f'{config["pluginCount"]}|{plugin_hash}',
canvas_hash,
ua_hash1,
"1",
"0",
"1",
"0",
config["mode"],
"0",
"0",
"0",
"416",
config["vendor"],
config["field29"],
config["touchInfo"],
ua_hash2,
config["field32"],
current_timestamp,
url_hash,
config["field35"],
doc_hash,
]
return "^".join(map(str, fields))
# =========================
# USAGE EXAMPLE
# =========================
def example_usage():
"""Example of how to generate bx-ua headers"""
# Initialize generators
fp_gen = BXUAGenerator()
# Generate a fingerprint
fingerprint = generate_fingerprint({
"deviceId": "84985177a19a010dea49",
"custom": {
"language": "zh-CN",
"platform": "MacIntel",
}
})
print("Generated Fingerprint:")
print(fingerprint[:100] + "...")
print()
# Generate bx-ua header
bx_ua = fp_gen.generate(fingerprint, {
"timestamp": int(time.time() * 1000),
"seed": "consistent_seed_for_deterministic_output"
})
print(bx_ua)
print("Generated bx-ua header:")
print(bx_ua[:100] + "...")
print(f"Total length: {len(bx_ua)}")
print()
# Parse the fingerprint (for debugging)
fields = fingerprint.split("^")
parsed = {
"deviceId": fields[0],
"sdkVersion": fields[1],
"language": fields[5],
"timezoneOffset": fields[6],
"platform": fields[10],
"webglRenderer": fields[12],
"mode": fields[23],
"vendor": fields[28],
"timestamp": fields[33],
}
print("Parsed fingerprint info:")
for key, value in parsed.items():
print(f" {key}: {value}")
return bx_ua
def batch_example():
"""Example of batch generation"""
fp_gen = BXUAGenerator()
# Generate multiple fingerprints
fingerprints = [
generate_fingerprint({"deviceId": generate_device_id()})
for _ in range(3)
]
# Generate bx-ua for each
bx_ua_values = fp_gen.batch_generate(fingerprints, {
"seed": "batch_seed"
})
print("Batch Generation Results:")
for i, (fp, bx_ua) in enumerate(zip(fingerprints, bx_ua_values)):
print(f"\n{i + 1}. Device ID: {fp.split('^')[0]}")
print(f" bx-ua: {bx_ua[:80]}...")
return bx_ua_values
if __name__ == "__main__":
print("=" * 60)
print("BX-UA Header Generator")
print("=" * 60)
# Run single example
print("\n1. Single Generation Example:")
print("-" * 40)
example_ua = example_usage()
print("\n" + "=" * 60)
# Run batch example
print("\n2. Batch Generation Example:")
print("-" * 40)
batch_ua = batch_example()
print("\n" + "=" * 60)
print("\nTo use in requests:")
print("```python")
print("import requests")
print("")
print("headers = {")
print(' "bx-ua": f"{example_ua}",')
print(' "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...",')
print(' "Accept": "application/json, text/plain, */*",')
print(' "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",')
print(' "Accept-Encoding": "gzip, deflate, br",')
print(' "Connection": "keep-alive",')
print("}")
print('')
print('response = requests.get("https://example.com/api", headers=headers)')
print("```")
import random
import time
import base64
import hashlib
from typing import Dict, List, Any, Optional
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import json
# =========================
# DEFAULT TEMPLATE
# =========================
DEFAULT_TEMPLATE: Dict[str, Any] = {
"deviceId": "84985177a19a010dea49",
"sdkVersion": "websdk-2.3.15d",
"initTimestamp": "1765348410850",
"field3": "91",
"field4": "1|15",
"language": "zh-CN",
"timezoneOffset": "-480",
"colorDepth": "16705151|12791",
"screenInfo": "1470|956|283|797|158|0|1470|956|1470|798|0|0",
"field9": "5",
"platform": "MacIntel",
"field11": "10",
"webglRenderer": (
"ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)"
"|Google Inc. (Apple)"
),
"field13": "30|30",
"field14": "0",
"field15": "28",
"pluginCount": "5",
"vendor": "Google Inc.",
"field29": "8",
"touchInfo": "-1|0|0|0|0",
"field32": "11",
"field35": "0",
"mode": "P",
}
# =========================
# BX-UA GENERATOR
# =========================
class BXUAGenerator:
def __init__(self):
self.version = "231"
self.aes_key = None
self.aes_iv = None
def _generate_key_iv(self, seed_data: str) -> tuple:
"""Generate AES key and IV from seed data"""
# Create deterministic key/IV from seed
seed_hash = hashlib.sha256(seed_data.encode()).digest()
key = seed_hash[:16] # 128-bit key
iv = seed_hash[16:32] # 128-bit IV
return key, iv
def _encrypt_aes_cbc(self, data: bytes, key: bytes, iv: bytes) -> bytes:
"""Encrypt data using AES-CBC"""
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_data = pad(data, AES.block_size)
encrypted = cipher.encrypt(padded_data)
return encrypted
def _create_payload(self, fingerprint: str, timestamp: Optional[int] = None) -> Dict[str, Any]:
"""Create the payload structure to be encrypted"""
if timestamp is None:
timestamp = int(time.time() * 1000)
# Extract components from fingerprint
fields = fingerprint.split("^")
payload = {
"v": self.version,
"ts": timestamp,
"fp": fingerprint,
"d": {
"deviceId": fields[0],
"sdkVer": fields[1],
"lang": fields[5],
"tz": fields[6],
"platform": fields[10],
"renderer": fields[12],
"mode": fields[23],
"vendor": fields[28],
},
"rnd": random.randint(1000, 9999),
"seq": 1,
}
# Add checksum
checksum_str = f"{fingerprint}{timestamp}{payload['rnd']}"
payload["cs"] = hashlib.md5(checksum_str.encode()).hexdigest()[:8]
return payload
def generate(self, fingerprint: str, options: Optional[Dict[str, Any]] = None) -> str:
"""
Generate bx-ua header value
Args:
fingerprint: The fingerprint string generated by generate_fingerprint()
options: Optional configuration
- timestamp: Custom timestamp (default: current time)
- seed: Custom seed for key generation
"""
if options is None:
options = {}
# Get timestamp
timestamp = options.get("timestamp")
if timestamp is None:
timestamp = int(time.time() * 1000)
# Create payload
payload = self._create_payload(fingerprint, timestamp)
# Convert to JSON
payload_json = json.dumps(payload, separators=(',', ':'))
# Generate key and IV
seed = options.get("seed", fingerprint)
key, iv = self._generate_key_iv(seed)
# Encrypt
encrypted = self._encrypt_aes_cbc(payload_json.encode(), key, iv)
# Base64 encode
encrypted_b64 = base64.b64encode(encrypted).decode()
# Return in format: version!base64_encoded_data
return f"{self.version}!{encrypted_b64}"
def batch_generate(self, fingerprints: List[str], options: Optional[Dict[str, Any]] = None) -> List[str]:
"""Generate multiple bx-ua values"""
return [self.generate(fp, options) for fp in fingerprints]
# =========================
# FINGERPRINT GENERATOR (From your code)
# =========================
def generate_device_id() -> str:
"""Generate a 20-character hex device ID"""
return "".join(random.choice("0123456789abcdef") for _ in range(20))
def generate_hash() -> int:
"""Generate a 32-bit unsigned random hash"""
return random.randint(0, 0xFFFFFFFF)
def generate_fingerprint(options: Dict[str, Any] = None) -> str:
if options is None:
options = {}
config = DEFAULT_TEMPLATE.copy()
# platform preset
platform = options.get("platform")
if platform:
# Handle platform presets if needed
pass
# screen preset
screen = options.get("screen")
if screen:
# Handle screen presets if needed
pass
# language preset
locale = options.get("locale")
if locale:
# Handle language presets if needed
pass
# custom overrides
if "custom" in options and isinstance(options["custom"], dict):
config.update(options["custom"])
device_id = options.get("deviceId") or generate_device_id()
current_timestamp = int(time.time() * 1000)
plugin_hash = generate_hash()
canvas_hash = generate_hash()
ua_hash1 = generate_hash()
ua_hash2 = generate_hash()
url_hash = generate_hash()
doc_hash = random.randint(10, 100)
fields: List[Any] = [
device_id,
config["sdkVersion"],
config["initTimestamp"],
config["field3"],
config["field4"],
config["language"],
config["timezoneOffset"],
config["colorDepth"],
config["screenInfo"],
config["field9"],
config["platform"],
config["field11"],
config["webglRenderer"],
config["field13"],
config["field14"],
config["field15"],
f'{config["pluginCount"]}|{plugin_hash}',
canvas_hash,
ua_hash1,
"1",
"0",
"1",
"0",
config["mode"],
"0",
"0",
"0",
"416",
config["vendor"],
config["field29"],
config["touchInfo"],
ua_hash2,
config["field32"],
current_timestamp,
url_hash,
config["field35"],
doc_hash,
]
return "^".join(map(str, fields))
# =========================
# USAGE EXAMPLE
# =========================
def example_usage():
"""Example of how to generate bx-ua headers"""
# Initialize generators
fp_gen = BXUAGenerator()
# Generate a fingerprint
fingerprint = generate_fingerprint({
"deviceId": "84985177a19a010dea49",
"custom": {
"language": "zh-CN",
"platform": "MacIntel",
}
})
print("Generated Fingerprint:")
print(fingerprint[:100] + "...")
print()
# Generate bx-ua header
bx_ua = fp_gen.generate(fingerprint, {
"timestamp": int(time.time() * 1000),
"seed": "consistent_seed_for_deterministic_output"
})
print(bx_ua)
print("Generated bx-ua header:")
print(bx_ua[:100] + "...")
print(f"Total length: {len(bx_ua)}")
print()
# Parse the fingerprint (for debugging)
fields = fingerprint.split("^")
parsed = {
"deviceId": fields[0],
"sdkVersion": fields[1],
"language": fields[5],
"timezoneOffset": fields[6],
"platform": fields[10],
"webglRenderer": fields[12],
"mode": fields[23],
"vendor": fields[28],
"timestamp": fields[33],
}
print("Parsed fingerprint info:")
for key, value in parsed.items():
print(f" {key}: {value}")
return bx_ua
def batch_example():
"""Example of batch generation"""
fp_gen = BXUAGenerator()
# Generate multiple fingerprints
fingerprints = [
generate_fingerprint({"deviceId": generate_device_id()})
for _ in range(3)
]
# Generate bx-ua for each
bx_ua_values = fp_gen.batch_generate(fingerprints, {
"seed": "batch_seed"
})
print("Batch Generation Results:")
for i, (fp, bx_ua) in enumerate(zip(fingerprints, bx_ua_values)):
print(f"\n{i + 1}. Device ID: {fp.split('^')[0]}")
print(f" bx-ua: {bx_ua[:80]}...")
return bx_ua_values
if __name__ == "__main__":
print("=" * 60)
print("BX-UA Header Generator")
print("=" * 60)
# Run single example
print("\n1. Single Generation Example:")
print("-" * 40)
example_ua = example_usage()
print("\n" + "=" * 60)
# Run batch example
print("\n2. Batch Generation Example:")
print("-" * 40)
batch_ua = batch_example()
print("\n" + "=" * 60)
print("\nTo use in requests:")
print("```python")
print("import requests")
print("")
print("headers = {")
print(' "bx-ua": f"{example_ua}",')
print(' "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...",')
print(' "Accept": "application/json, text/plain, */*",')
print(' "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",')
print(' "Accept-Encoding": "gzip, deflate, br",')
print(' "Connection": "keep-alive",')
print("}")
print('')
print('response = requests.get("https://example.com/api", headers=headers)')
print("```")