import random
import os
import json
import argparse
# 可复现随机种子(想每次都不一样,直接删除下面这行)
random.seed(42)
# ==================== UA 列表(62 个,2026 年最新真实风格) ====================
user_agents = [
# Windows (Windows 10/11)
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
# Windows 11 专属
"Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
# macOS (Intel + Apple Silicon)
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
# macOS Sequoia 专属
"Mozilla/5.0 (Macintosh; Intel Mac OS X 15_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
# Linux
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64; rv:126.0) Gecko/20100101 Firefox/126.0",
"Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0",
"Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0",
# Android (14/15)
"Mozilla/5.0 (Linux; Android 14; SM-S928B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36",
"Mozilla/5.0 (Linux; Android 14; Pixel 8 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Mobile Safari/537.36",
"Mozilla/5.0 (Linux; Android 14; SM-G998B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36",
"Mozilla/5.0 (Linux; Android 15; Pixel 9 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Mobile Safari/537.36",
"Mozilla/5.0 (Linux; Android 14; SM-F946B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Mobile Safari/537.36", # Foldable
# iOS (iPhone / iPad 17/18)
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
"Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
"Mozilla/5.0 (iPad; CPU OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
"Mozilla/5.0 (iPad; CPU OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
"Mozilla/5.0 (iPhone16,2; CPU iPhone OS 18_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1 Mobile/15E148 Safari/604.1",
# 其他高仿真浏览器
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Brave/128.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Brave/129.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 OPR/115.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Vivaldi/7.0.1234.55",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Vivaldi/7.0.1234.55",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Vivaldi/7.0.1234.55",
]
resolutions = [
(1920, 1080, 1040, 1.0), (1366, 768, 728, 1.0), (2560, 1440, 1400, 1.0),
(3840, 2160, 2120, 1.0), (5120, 2880, 2840, 1.0), (1512, 982, 942, 2.0),
(3440, 1440, 1400, 1.0), (1728, 1117, 1077, 2.0), # MacBook Pro
(375, 667, 627, 3.0), (360, 640, 600, 2.0), (414, 896, 856, 3.0),
(390, 844, 804, 3.0), (430, 932, 892, 3.0), (393, 852, 812, 3.0), # iPhone 16
(412, 915, 875, 2.75), # Android Fold
]
timezones = [
{"offset": -480, "name": "America/Los_Angeles", "dst": True},
{"offset": 480, "name": "Asia/Shanghai", "dst": False},
{"offset": 0, "name": "UTC", "dst": False},
{"offset": -300, "name": "America/New_York", "dst": True},
{"offset": 60, "name": "Europe/Paris", "dst": True},
{"offset": 540, "name": "Asia/Tokyo", "dst": False},
{"offset": 330, "name": "Asia/Kolkata", "dst": False},
]
webgl_options = [
{"vendor": "Google Inc. (Intel)", "renderer": "ANGLE (Intel, Intel(R) UHD Graphics, Direct3D11 vs_5_0 ps_5_0)", "unmaskedVendor": "Intel Inc.", "unmaskedRenderer": "Intel(R) UHD Graphics"},
{"vendor": "Google Inc. (NVIDIA)", "renderer": "ANGLE (NVIDIA, NVIDIA GeForce RTX 4060, Direct3D11 vs_5_0 ps_5_0)", "unmaskedVendor": "NVIDIA Corporation", "unmaskedRenderer": "NVIDIA GeForce RTX 4060"},
{"vendor": "Apple Inc.", "renderer": "Apple GPU", "unmaskedVendor": "Apple Inc.", "unmaskedRenderer": "Apple M3 GPU"},
{"vendor": "Google Inc. (AMD)", "renderer": "ANGLE (AMD, AMD Radeon RX 7600, Direct3D11 vs_5_0 ps_5_0)", "unmaskedVendor": "AMD", "unmaskedRenderer": "AMD Radeon RX 7600"},
{"vendor": "Google Inc. (Intel)", "renderer": "ANGLE (Intel, Intel(R) Arc A770, Direct3D11 vs_5_0 ps_5_0)", "unmaskedVendor": "Intel Inc.", "unmaskedRenderer": "Intel(R) Arc A770"},
{"vendor": "Google Inc. (NVIDIA)", "renderer": "ANGLE (NVIDIA, NVIDIA GeForce RTX 5090, Direct3D11 vs_5_0 ps_5_0)", "unmaskedVendor": "NVIDIA Corporation", "unmaskedRenderer": "NVIDIA GeForce RTX 5090"},
]
base_fonts = ["Arial", "Arial Black", "Calibri", "Helvetica", "Segoe UI", "Tahoma", "Times New Roman", "Verdana", "Microsoft YaHei", "SimSun"]
def rand_hash(length=64):
return ''.join(random.choices('0123456789abcdef', k=length))
# ==================== 平台过滤(更精准) ====================
def filter_by_platform(ua_list, target_platform):
if target_platform == 'all':
return ua_list
filtered = []
for ua in ua_list:
lower = ua.lower()
if target_platform == 'windows' and 'windows' in lower:
filtered.append(ua)
elif target_platform == 'macos' and 'macintosh' in lower:
filtered.append(ua)
elif target_platform == 'linux' and 'linux' in lower and 'android' not in lower:
filtered.append(ua)
elif target_platform == 'android' and 'android' in lower:
filtered.append(ua)
elif target_platform == 'ios' and ('iphone' in lower or 'ipad' in lower):
filtered.append(ua)
return filtered if filtered else ua_list # 兜底
# ==================== 鼠标轨迹模拟函数(保持不变) ====================
def generate_human_mouse_trajectory(width: int, height: int, num_points: int = 40):
"""生成类人鼠标移动轨迹:贝塞尔曲线 + 高斯噪声 + 速度/加速度模拟"""
points = []
x = random.randint(100, 300)
y = random.randint(100, 300)
points.append((x, y))
for i in range(1, num_points):
target_x = int(width * 0.7 + random.gauss(0, width * 0.12))
target_y = int(height * 0.7 + random.gauss(0, height * 0.12))
ctrl_x = x + (target_x - x) * 0.4 + random.gauss(0, 80)
ctrl_y = y + (target_y - y) * 0.3 + random.gauss(0, 60)
t = i / (num_points - 1)
new_x = int((1-t)**3 * x + 3*(1-t)**2*t*ctrl_x + 3*(1-t)*t**2*target_x + t**3 * target_x)
new_y = int((1-t)**3 * y + 3*(1-t)**2*t*ctrl_y + 3*(1-t)*t**2*target_y + t**3 * target_y)
noise = 12 * (1 - t)
new_x += int(random.gauss(0, noise))
new_y += int(random.gauss(0, noise))
x = max(0, min(width, new_x))
y = max(0, min(height, new_y))
points.append((x, y))
return points
# ==================== WebRTC 完整伪装 JS(保持不变) ====================
WEBRTC_SPOOF_JS = """// WebRTC 完整伪装函数(2026最新版)
// 使用方法:在 Playwright / Puppeteer 中:await page.evaluate(() => spoofWebRTC('192.168.1.100', 54321));
function spoofWebRTC(fakeIP = '192.168.1.100', fakePort = 54321) {
const OriginalRTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection;
if (!OriginalRTCPeerConnection) return console.log('WebRTC 已不存在,无需伪装');
window.RTCPeerConnection = function(config) {
const pc = new OriginalRTCPeerConnection(config);
const originalAddIce = pc.addIceCandidate;
pc.addIceCandidate = function(candidate) {
if (candidate && candidate.candidate) {
candidate.candidate = candidate.candidate
.replace(/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/g, fakeIP)
.replace(/raddr \\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/g, `raddr ${fakeIP}`)
.replace(/rport \\d+/g, `rport ${fakePort}`);
}
return originalAddIce.apply(this, [candidate]);
};
const originalOnIce = pc.onicecandidate;
pc.onicecandidate = function(event) {
if (event.candidate) {
event.candidate.candidate = event.candidate.candidate
.replace(/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/g, fakeIP)
.replace(/raddr \\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/g, `raddr ${fakeIP}`);
}
if (originalOnIce) originalOnIce.call(this, event);
};
const originalCreateOffer = pc.createOffer;
pc.createOffer = function(options) {
return originalCreateOffer.call(this, options).then(offer => {
offer.sdp = offer.sdp.replace(/c=IN IP4 \\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/g, `c=IN IP4 ${fakeIP}`);
return offer;
});
};
console.log(`✅ WebRTC 已完全伪装 | 假IP: ${fakeIP}:${fakePort}`);
return pc;
};
Object.defineProperty(navigator, 'webRTCEnabled', { value: false, configurable: true });
console.log('WebRTC 伪装完成');
}
"""
# ==================== 生成单个指纹 ====================
def generate_fingerprint(i, target_platform, ua_list):
ua = random.choice(ua_list)
res = random.choice(resolutions)
width, height, avail_height, dpr = res
tz = random.choice(timezones)
wg = random.choice(webgl_options)
device_mem = random.choice([4, 8, 16, 32])
hw_conc = random.choice([4, 6, 8, 12, 16, 24])
is_mobile = any(x in ua.lower() for x in ["mobile", "iphone", "android", "ipad"])
max_touch = random.randint(5, 10) if is_mobile else 0
canvas_fp = rand_hash(64)
audio_fp = rand_hash(64)
fonts_hash = rand_hash(32)
lang = random.choice(["zh-CN", "en-US", "zh-TW", "ja-JP"])
languages = [lang, lang.split('-')[0], "en-US", "en"]
color_scheme = random.choice(["light", "dark"])
lower_ua = ua.lower()
if "macintosh" in lower_ua:
platform = "macos"; nav_platform = "MacIntel"; vendor = "Apple Inc."
elif "linux" in lower_ua and "android" not in lower_ua:
platform = "linux"; nav_platform = "Linux x86_64"; vendor = "Google Inc."
elif "android" in lower_ua:
platform = "android"; nav_platform = "Linux armv81"; vendor = "Google Inc."
elif "iphone" in lower_ua or "ipad" in lower_ua:
platform = "ios"; nav_platform = "iPhone"; vendor = "Apple Inc."
else:
platform = "windows"; nav_platform = "Win32"; vendor = "Google Inc."
fp_data = {
"version": "1.0",
"description": f"顶级高级浏览器指纹 {i:03d} - {platform.upper()} 平台 (v4.0)",
"platform": platform,
"fingerprint": {
"navigator": {
"userAgent": ua,
"platform": nav_platform,
"vendor": vendor,
"appVersion": "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
"appName": "Netscape",
"appCodeName": "Mozilla",
"product": "Gecko",
"productSub": "20030107",
"language": lang,
"languages": languages,
"deviceMemory": device_mem,
"hardwareConcurrency": hw_conc,
"maxTouchPoints": max_touch,
"cookieEnabled": True,
"onLine": True,
"pdfViewerEnabled": True
},
"screen": {
"width": width, "height": height, "availWidth": width, "availHeight": avail_height,
"colorDepth": 24, "pixelDepth": 24, "devicePixelRatio": dpr,
"orientation": {"type": "landscape-primary", "angle": 0}
},
"window": {
"outerWidth": width, "outerHeight": height,
"innerWidth": width - 16, "innerHeight": height - 117,
"devicePixelRatio": dpr
},
"timezone": {"offset": tz["offset"], "name": tz["name"], "dst": tz["dst"]},
"webgl": {
"vendor": wg["vendor"], "renderer": wg["renderer"],
"unmaskedVendor": wg["unmaskedVendor"], "unmaskedRenderer": wg["unmaskedRenderer"]
},
"canvas": {"fingerprint": canvas_fp},
"audio": {"fingerprint": audio_fp},
"fonts": {
"list": base_fonts + random.sample(["Impact", "Courier New", "Georgia", "Palatino", "Lucida Grande"], 3),
"hash": fonts_hash
},
"webrtc": {"enabled": False, "iceServers": []},
"battery": {"charging": True, "level": 0.85},
"plugins": [] if not is_mobile else ["Shockwave Flash", "Widevine Content Decryption Module"],
"mimeTypes": [],
"doNotTrack": random.choice(["1", "unspecified"]),
"colorScheme": color_scheme,
"reducedMotion": random.choice([True, False]),
"reducedTransparency": False,
"invertedColors": False,
"forcedColors": False
}
}
yaml_str = f"""# =============================================
# 顶级高级浏览器指纹 - YAML 格式 (v4.0)
# ID: {i:03d} | 平台: {platform.upper()} | UA: {ua[:70]}...
# 生成时间: 2026-04-21
# =============================================
version: "1.0"
description: "{fp_data['description']}"
platform: "{platform}"
fingerprint:
"""
for section, data in fp_data["fingerprint"].items():
yaml_str += f" {section}:\n"
if isinstance(data, dict):
for k, v in data.items():
if isinstance(v, (list, dict)):
yaml_str += f" {k}: {json.dumps(v, ensure_ascii=False)}\n"
else:
yaml_str += f" {k}: {v}\n"
else:
yaml_str += f" {section}: {data}\n"
return fp_data, yaml_str
# ==================== 主程序 ====================
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="顶级高级浏览器指纹生成器 v4.0(62个UA + 更多平台变体)")
parser.add_argument('--num', type=int, default=100, help='生成指纹数量 (默认 100)')
parser.add_argument('--platform', type=str, default='all', choices=['all', 'windows', 'macos', 'linux', 'android', 'ios'], help='指定平台 (默认 all)')
args = parser.parse_args()
print(f"🚀 开始生成 {args.num} 个【v4.0 顶级版】浏览器指纹 | 平台: {args.platform.upper()}")
filtered_ua = filter_by_platform(user_agents, args.platform)
print(f" 已过滤 UA:{len(filtered_ua)} 个可用(总库 62 个)")
output_dir = f"advanced_fingerprints_{args.platform}_v4"
os.makedirs(output_dir, exist_ok=True)
for i in range(1, args.num + 1):
fp_data, yaml_content = generate_fingerprint(i, args.platform, filtered_ua)
base_name = os.path.join(output_dir, f"browser_fingerprint_{i:03d}")
with open(f"{base_name}.yaml", "w", encoding="utf-8") as f:
f.write(yaml_content)
with open(f"{base_name}.json", "w", encoding="utf-8") as f:
json.dump(fp_data, f, indent=2, ensure_ascii=False)
if i % 10 == 0 or i == args.num:
print(f"✅ 已生成 {i:03d}/{args.num} 个指纹")
# 生成辅助文件
with open(os.path.join(output_dir, "mouse_trajectory_simulator.py"), "w", encoding="utf-8") as f:
f.write('''# ==================== 鼠标轨迹模拟器 ====================
def generate_human_mouse_trajectory(width: int, height: int, num_points: int = 40):
"""生成类人鼠标移动轨迹:贝塞尔曲线 + 高斯噪声 + 速度/加速度模拟"""
import random
points = []
x = random.randint(100, 300)
y = random.randint(100, 300)
points.append((x, y))
for i in range(1, num_points):
target_x = int(width * 0.7 + random.gauss(0, width * 0.12))
target_y = int(height * 0.7 + random.gauss(0, height * 0.12))
ctrl_x = x + (target_x - x) * 0.4 + random.gauss(0, 80)
ctrl_y = y + (target_y - y) * 0.3 + random.gauss(0, 60)
t = i / (num_points - 1)
new_x = int((1-t)**3 * x + 3*(1-t)**2*t*ctrl_x + 3*(1-t)*t**2*target_x + t**3 * target_x)
new_y = int((1-t)**3 * y + 3*(1-t)**2*t*ctrl_y + 3*(1-t)*t**2*target_y + t**3 * target_y)
noise = 12 * (1 - t)
new_x += int(random.gauss(0, noise))
new_y += int(random.gauss(0, noise))
x = max(0, min(width, new_x))
y = max(0, min(height, new_y))
points.append((x, y))
return points
print("✅ 鼠标轨迹函数已加载")
''')
with open(os.path.join(output_dir, "webrtc_spoof.js"), "w", encoding="utf-8") as f:
f.write(WEBRTC_SPOOF_JS)
print(f"\n🎉 生成完成!共 {args.num} 个指纹(v4.0)")
print(f"📁 保存路径:{os.path.abspath(output_dir)}")
print(" • *.yaml / *.json → 指纹文件")
print(" • mouse_trajectory_simulator.py → 鼠标轨迹代码")
print(" • webrtc_spoof.js → WebRTC 伪装 JS")
print("\n运行示例:")
print(" python generate_fingerprints.py --num 300 --platform ios")
print(" python generate_fingerprints.py --num 500 --platform all")