Spaces:
Running
Running
github-actions[bot]
Sync from GitHub Viciy2023/Qwen2API-A@ae093476e9bc5b0a599620b5925df3a20057038e
f120063 | // 导入指纹生成器 | |
| const { generateFingerprint } = require('./fingerprint'); | |
| // 自定义Base64字符表 | |
| const CUSTOM_BASE64_CHARS = "DGi0YA7BemWnQjCl4_bR3f8SKIF9tUz/xhr2oEOgPpac=61ZqwTudLkM5vHyNXsVJ"; | |
| // 哈希字段位置(这些字段需要随机生成) | |
| const HASH_FIELDS = { | |
| 16: 'split', // 插件哈希(格式: count|hash,只替换hash部分) | |
| 17: 'full', // Canvas指纹哈希 | |
| 18: 'full', // UserAgent哈希 | |
| 31: 'full', // UserAgent哈希2 | |
| 34: 'full', // 文档URL哈希 | |
| 36: 'full' // 文档属性哈希 | |
| }; | |
| // ==================== LZW压缩算法 ==================== | |
| function lzwCompress(data, bits, charFunc) { | |
| if (data == null) return ''; | |
| let dict = {}; | |
| let dictToCreate = {}; | |
| let c = ''; | |
| let wc = ''; | |
| let w = ''; | |
| let enlargeIn = 2; | |
| let dictSize = 3; | |
| let numBits = 2; | |
| let result = []; | |
| let value = 0; | |
| let position = 0; | |
| for (let i = 0; i < data.length; i++) { | |
| c = data.charAt(i); | |
| if (!Object.prototype.hasOwnProperty.call(dict, c)) { | |
| dict[c] = dictSize++; | |
| dictToCreate[c] = true; | |
| } | |
| wc = w + c; | |
| if (Object.prototype.hasOwnProperty.call(dict, wc)) { | |
| w = wc; | |
| } else { | |
| if (Object.prototype.hasOwnProperty.call(dictToCreate, w)) { | |
| if (w.charCodeAt(0) < 256) { | |
| for (let j = 0; j < numBits; j++) { | |
| value = (value << 1); | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| } | |
| let charCode = w.charCodeAt(0); | |
| for (let j = 0; j < 8; j++) { | |
| value = (value << 1) | (charCode & 1); | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| charCode >>= 1; | |
| } | |
| } else { | |
| let charCode = 1; | |
| for (let j = 0; j < numBits; j++) { | |
| value = (value << 1) | charCode; | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| charCode = 0; | |
| } | |
| charCode = w.charCodeAt(0); | |
| for (let j = 0; j < 16; j++) { | |
| value = (value << 1) | (charCode & 1); | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| charCode >>= 1; | |
| } | |
| } | |
| enlargeIn--; | |
| if (enlargeIn === 0) { | |
| enlargeIn = Math.pow(2, numBits); | |
| numBits++; | |
| } | |
| delete dictToCreate[w]; | |
| } else { | |
| let charCode = dict[w]; | |
| for (let j = 0; j < numBits; j++) { | |
| value = (value << 1) | (charCode & 1); | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| charCode >>= 1; | |
| } | |
| } | |
| enlargeIn--; | |
| if (enlargeIn === 0) { | |
| enlargeIn = Math.pow(2, numBits); | |
| numBits++; | |
| } | |
| dict[wc] = dictSize++; | |
| w = String(c); | |
| } | |
| } | |
| if (w !== '') { | |
| if (Object.prototype.hasOwnProperty.call(dictToCreate, w)) { | |
| if (w.charCodeAt(0) < 256) { | |
| for (let j = 0; j < numBits; j++) { | |
| value = (value << 1); | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| } | |
| let charCode = w.charCodeAt(0); | |
| for (let j = 0; j < 8; j++) { | |
| value = (value << 1) | (charCode & 1); | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| charCode >>= 1; | |
| } | |
| } else { | |
| let charCode = 1; | |
| for (let j = 0; j < numBits; j++) { | |
| value = (value << 1) | charCode; | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| charCode = 0; | |
| } | |
| charCode = w.charCodeAt(0); | |
| for (let j = 0; j < 16; j++) { | |
| value = (value << 1) | (charCode & 1); | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| charCode >>= 1; | |
| } | |
| } | |
| enlargeIn--; | |
| if (enlargeIn === 0) { | |
| enlargeIn = Math.pow(2, numBits); | |
| numBits++; | |
| } | |
| delete dictToCreate[w]; | |
| } else { | |
| let charCode = dict[w]; | |
| for (let j = 0; j < numBits; j++) { | |
| value = (value << 1) | (charCode & 1); | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| charCode >>= 1; | |
| } | |
| } | |
| enlargeIn--; | |
| if (enlargeIn === 0) { | |
| enlargeIn = Math.pow(2, numBits); | |
| numBits++; | |
| } | |
| } | |
| let charCode = 2; | |
| for (let j = 0; j < numBits; j++) { | |
| value = (value << 1) | (charCode & 1); | |
| if (position === bits - 1) { | |
| position = 0; | |
| result.push(charFunc(value)); | |
| value = 0; | |
| } else { | |
| position++; | |
| } | |
| charCode >>= 1; | |
| } | |
| while (true) { | |
| value = (value << 1); | |
| if (position === bits - 1) { | |
| result.push(charFunc(value)); | |
| break; | |
| } | |
| position++; | |
| } | |
| return result.join(''); | |
| } | |
| // ==================== 编码函数 ==================== | |
| function customEncode(data, urlSafe) { | |
| if (data == null) return ''; | |
| const base64Chars = CUSTOM_BASE64_CHARS; | |
| let compressed = lzwCompress(data, 6, function(index) { | |
| return base64Chars.charAt(index); | |
| }); | |
| if (!urlSafe) { | |
| switch (compressed.length % 4) { | |
| case 1: return compressed + '==='; | |
| case 2: return compressed + '=='; | |
| case 3: return compressed + '='; | |
| default: return compressed; | |
| } | |
| } | |
| return compressed; | |
| } | |
| // ==================== 辅助函数 ==================== | |
| function randomHash() { | |
| return Math.floor(Math.random() * 4294967296); | |
| } | |
| function generateDeviceId() { | |
| return Array.from({ length: 20 }, () => | |
| Math.floor(Math.random() * 16).toString(16) | |
| ).join(''); | |
| } | |
| // ==================== 数据解析和处理 ==================== | |
| function parseRealData(realData) { | |
| const fields = realData.split('^'); | |
| return fields; | |
| } | |
| function processFields(fields) { | |
| const processed = [...fields]; | |
| const currentTimestamp = Date.now(); | |
| // 替换哈希字段 | |
| for (const [index, type] of Object.entries(HASH_FIELDS)) { | |
| const idx = parseInt(index); | |
| if (type === 'split') { | |
| // 字段16: 格式为 "count|hash",只替换hash部分 | |
| const parts = processed[idx].split('|'); | |
| if (parts.length === 2) { | |
| processed[idx] = `${parts[0]}|${randomHash()}`; | |
| } | |
| } else if (type === 'full') { | |
| // 完全替换为随机哈希 | |
| if (idx === 36) { | |
| // 字段36: 文档属性哈希(10-100的随机整数) | |
| processed[idx] = Math.floor(Math.random() * 91) + 10; | |
| } else { | |
| processed[idx] = randomHash(); | |
| } | |
| } | |
| } | |
| processed[33] = currentTimestamp; // 字段33: 当前时间戳 | |
| return processed; | |
| } | |
| // ==================== Cookie生成 ==================== | |
| function generateCookies(realData = null, fingerprintOptions = {}) { | |
| // 使用传入的指纹或生成新的随机指纹 | |
| const fingerprint = realData || generateFingerprint(fingerprintOptions); | |
| // 解析指纹数据 | |
| const fields = parseRealData(fingerprint); | |
| // 处理字段(随机化哈希,更新时间戳) | |
| const processedFields = processFields(fields); | |
| // 生成 ssxmod_itna (37字段) | |
| const ssxmod_itna_data = processedFields.join('^'); | |
| const ssxmod_itna = '1-' + customEncode(ssxmod_itna_data, true); | |
| // 生成 ssxmod_itna2 (18字段) | |
| // 只使用: 字段0, 字段1, 字段23, 字段32, 字段33 | |
| const ssxmod_itna2_data = [ | |
| processedFields[0], // 设备ID | |
| processedFields[1], // SDK版本 | |
| processedFields[23], // 模式 (P/M) | |
| 0, '', 0, '', '', 0, // 事件相关(P模式下为空) | |
| 0, 0, | |
| processedFields[32], // 常量 (11) | |
| processedFields[33], // 当前时间戳 | |
| 0, 0, 0, 0, 0 | |
| ].join('^'); | |
| const ssxmod_itna2 = '1-' + customEncode(ssxmod_itna2_data, true); | |
| return { | |
| ssxmod_itna, | |
| ssxmod_itna2, | |
| timestamp: parseInt(processedFields[33]), | |
| rawData: ssxmod_itna_data, | |
| rawData2: ssxmod_itna2_data | |
| }; | |
| } | |
| function generateBatch(count = 10, realData = null, fingerprintOptions = {}) { | |
| const results = []; | |
| for (let i = 0; i < count; i++) { | |
| results.push(generateCookies(realData, fingerprintOptions)); | |
| } | |
| return results; | |
| } | |
| // ==================== 主程序 ==================== | |
| if (require.main === module) { | |
| const result = generateCookies(); | |
| console.log('ssxmod_itna:', result.ssxmod_itna); | |
| console.log('ssxmod_itna2:', result.ssxmod_itna2); | |
| } | |
| // ==================== 导出 ==================== | |
| module.exports = { | |
| generateCookies, | |
| generateBatch, | |
| customEncode, | |
| randomHash, | |
| generateDeviceId, | |
| parseRealData, | |
| generateFingerprint | |
| }; | |