/** * 跨浏览器硬件指纹采集器 * * 原理:采集不受浏览器影响的硬件/系统特征,生成统一设备ID * 同一台电脑无论Chrome/Edge/Firefox,生成的ID完全一致 * * 采集特征(跨浏览器稳定不变): * 1. 操作系统平台 (Win32/MacIntel/Linux) * 2. 屏幕分辨率 + 颜色深度 * 3. CPU 核心数 * 4. 时区偏移 * 5. WebGL 显卡渲染特征(底层硬件驱动生成,跨浏览器一致) * * 隐私合规:仅采集硬件特征,不获取MAC地址、不读取文件、不收集敏感信息 */ (function() { 'use strict'; // SHA-256 哈希实现(纯JS,无外部依赖) var SHA256 = (function() { var K = [ 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 ]; function R(x,n){return(x>>>n)|(x<<(32-n));} function Ch(x,y,z){return(x&y)^(~x&z);} function Maj(x,y,z){return(x&y)^(x&z)^(y&z);} function Sigma0(x){return R(x,2)^R(x,13)^R(x,22);} function Sigma1(x){return R(x,6)^R(x,11)^R(x,25);} function sigma0(x){return R(x,7)^R(x,18)^(x>>>3);} function sigma1(x){return R(x,17)^R(x,19)^(x>>>10);} function toBytes(s){ var b=[],l=s.length; for(var i=0;i>>(56-i*8))&0xff); return b; } function hash(s){ var bytes=toBytes(s); var H=[0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19]; for(var i=0;i>>28)&0xf]+hex[(v>>>24)&0xf]+hex[(v>>>20)&0xf]+hex[(v>>>16)&0xf]+hex[(v>>>12)&0xf]+hex[(v>>>8)&0xf]+hex[(v>>>4)&0xf]+hex[v&0xf];} return r; } return {hash: hash}; })(); function getHardwareFingerprint() { var parts = []; // 1. 操作系统平台(跨浏览器一致) parts.push(navigator.platform || 'unknown'); // 2. 屏幕分辨率 + 颜色深度(硬件固定) parts.push(screen.width + 'x' + screen.height); parts.push(String(screen.colorDepth || screen.pixelDepth)); // 3. CPU 核心数(硬件固定) var cores = navigator.hardwareConcurrency || 0; parts.push(String(cores)); // 4. 时区偏移(系统固定) parts.push(String(new Date().getTimezoneOffset())); // 5. 语言设置(系统级,跨浏览器一致) parts.push(navigator.language || navigator.userLanguage || ''); // 6. WebGL 显卡信息(关键!底层硬件驱动,跨浏览器一致) try { var canvas = document.createElement('canvas'); var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (gl) { var debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); if (debugInfo) { var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) || ''; var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) || ''; parts.push(vendor); parts.push(renderer); } else { // fallback: use basic WebGL parameters parts.push(gl.getParameter(gl.VENDOR) || ''); parts.push(gl.getParameter(gl.RENDERER) || ''); } } else { parts.push('no_webgl'); } } catch(e) { parts.push('webgl_error'); } // 7. 设备内存(如果可用,硬件固定) if (navigator.deviceMemory) { parts.push(String(navigator.deviceMemory)); } // 8. 触摸支持(硬件固定) parts.push(navigator.maxTouchPoints > 0 ? 'touch' : 'no_touch'); // 拼接后做 SHA-256 哈希 var raw = parts.join('|||'); var hash = SHA256.hash(raw); // 返回格式化的设备ID return 'hw_' + hash.substring(0, 16) + '_' + (navigator.platform || 'x').substring(0, 8); } // 暴露到全局 window.getDeviceFingerprint = getHardwareFingerprint; // 自动填充隐藏字段 document.addEventListener('DOMContentLoaded', function() { var el = document.getElementById('deviceFingerprint'); if (el && !el.value) { el.value = getHardwareFingerprint(); } }); })();