Compare commits
No commits in common. "e712333a7974849b2ef667ae7ba3d5ed8457875b" and "d5acb0a27c058d3f0e7d6ee822fcc476f21f2ab5" have entirely different histories.
e712333a79
...
d5acb0a27c
|
|
@ -5,7 +5,7 @@ import router from '@/router'
|
||||||
import WHITELIST from "./whiteList"
|
import WHITELIST from "./whiteList"
|
||||||
import moment from 'moment-timezone';
|
import moment from 'moment-timezone';
|
||||||
import { encryptConfig } from "@/utils/encrypt"
|
import { encryptConfig } from "@/utils/encrypt"
|
||||||
import SystemInfo from "@/utils/systemInfo";
|
import { customAgent } from './fingerprint'
|
||||||
const ROUTER = require('@/router');
|
const ROUTER = require('@/router');
|
||||||
axios.defaults.withCredentials = false
|
axios.defaults.withCredentials = false
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
|
|
@ -27,41 +27,8 @@ service.interceptors.request.use(
|
||||||
var language = zzSessionStorage.getItem('lang')
|
var language = zzSessionStorage.getItem('lang')
|
||||||
config.headers['Accept-Language'] = language === 'en' ? 'en-US,en;q=0.5' : 'zh-CN,zh;q=0.9'
|
config.headers['Accept-Language'] = language === 'en' ? 'en-US,en;q=0.5' : 'zh-CN,zh;q=0.9'
|
||||||
config.headers['TimeZoneId'] = moment.tz.guess()
|
config.headers['TimeZoneId'] = moment.tz.guess()
|
||||||
const systemInfo = new SystemInfo();
|
let fingerprint = await customAgent()
|
||||||
const allInfo = systemInfo.getAllInfo();
|
config.headers['BrowserFingerprint'] = fingerprint.visitorId
|
||||||
let obj = {
|
|
||||||
browser: {
|
|
||||||
name: allInfo.browser.name,
|
|
||||||
version: allInfo.browser.version,
|
|
||||||
},
|
|
||||||
platform: allInfo.platform,
|
|
||||||
os: {
|
|
||||||
name: allInfo.os.name,
|
|
||||||
version: allInfo.os.version
|
|
||||||
},
|
|
||||||
hardware: {
|
|
||||||
logicalCores: allInfo.hardware.logicalCores,
|
|
||||||
deviceMemory: allInfo.hardware.deviceMemory
|
|
||||||
},
|
|
||||||
webgl: {
|
|
||||||
version: allInfo.webgl.version,
|
|
||||||
renderer: allInfo.webgl.renderer,
|
|
||||||
vendor: allInfo.webgl.vendor,
|
|
||||||
shadingLanguage: allInfo.webgl.shadingLanguage,
|
|
||||||
gpuType: {
|
|
||||||
type: allInfo.webgl.gpuType.type,
|
|
||||||
discrete: allInfo.webgl.gpuType.discrete,
|
|
||||||
},
|
|
||||||
performance: {
|
|
||||||
tier: allInfo.webgl.performance.tier,
|
|
||||||
},
|
|
||||||
extensions: {
|
|
||||||
length: allInfo.webgl.extensions.length,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let guid = await systemInfo.generateGuid(obj)
|
|
||||||
config.headers['BrowserFingerprint'] = guid
|
|
||||||
if (config.ENCRYPT) {
|
if (config.ENCRYPT) {
|
||||||
try {
|
try {
|
||||||
config = await encryptConfig(config)
|
config = await encryptConfig(config)
|
||||||
|
|
|
||||||
|
|
@ -466,217 +466,6 @@ class SystemInfo {
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
deepSortObject(obj) {
|
|
||||||
if (obj === null || typeof obj !== 'object') {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(obj)) {
|
|
||||||
return obj.map(deepSortObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sorted = {};
|
|
||||||
Object.keys(obj).sort().forEach(key => {
|
|
||||||
sorted[key] = this.deepSortObject(obj[key]);
|
|
||||||
});
|
|
||||||
|
|
||||||
return sorted;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCanonicalString(obj) {
|
|
||||||
if (typeof obj !== 'object' || obj === null) {
|
|
||||||
return JSON.stringify(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sorted = this.deepSortObject(obj);
|
|
||||||
return JSON.stringify(sorted);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 简单哈希函数
|
|
||||||
simpleHash(str) {
|
|
||||||
let hash = 0;
|
|
||||||
for (let i = 0; i < str.length; i++) {
|
|
||||||
const char = str.charCodeAt(i);
|
|
||||||
hash = ((hash << 5) - hash) + char;
|
|
||||||
hash = hash & hash;
|
|
||||||
}
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 简单SHA-256模拟
|
|
||||||
simpleSHA256(str) {
|
|
||||||
let hash = 0;
|
|
||||||
for (let i = 0; i < str.length; i++) {
|
|
||||||
const char = str.charCodeAt(i);
|
|
||||||
hash = ((hash << 5) - hash) + char;
|
|
||||||
hash = hash & hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
const hashArray = [];
|
|
||||||
for (let i = 0; i < 8; i++) {
|
|
||||||
hashArray[i] = (hash + i * 2654435761) >>> 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 格式化哈希为GUID
|
|
||||||
formatHashAsGuid(hashArray) {
|
|
||||||
const hexParts = hashArray.map(h => h.toString(16).padStart(8, '0'));
|
|
||||||
return `${hexParts[0]}${hexParts[1].substring(0, 4)}-${hexParts[1].substring(4)}-${hexParts[2].substring(0, 4)}-${hexParts[3].substring(0, 4)}-${hexParts[3].substring(4)}${hexParts[4]}${hexParts[5]}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 确定性哈希算法
|
|
||||||
objectToGuidDeterministic(obj) {
|
|
||||||
const canonicalString = this.getCanonicalString(obj);
|
|
||||||
const hash = this.simpleSHA256(canonicalString);
|
|
||||||
return this.formatHashAsGuid(hash).toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 伪随机算法
|
|
||||||
getSeedFromObject(obj) {
|
|
||||||
const str = JSON.stringify(obj);
|
|
||||||
return this.simpleHash(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
createSeededRandom(seed) {
|
|
||||||
let state = seed;
|
|
||||||
return function () {
|
|
||||||
state = (state * 1664525 + 1013904223) >>> 0;
|
|
||||||
return (state & 0x3FFFFFFF) / 0x3FFFFFFF;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
generateVersion4Guid(randomFn) {
|
|
||||||
let guid = '';
|
|
||||||
|
|
||||||
for (let i = 0; i < 32; i++) {
|
|
||||||
if (i === 8 || i === 12 || i === 16 || i === 20) {
|
|
||||||
guid += '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i === 12) {
|
|
||||||
guid += '4';
|
|
||||||
} else if (i === 16) {
|
|
||||||
const variant = Math.floor(randomFn() * 4);
|
|
||||||
guid += (8 + variant).toString(16).toUpperCase();
|
|
||||||
} else {
|
|
||||||
const randomHex = Math.floor(randomFn() * 16).toString(16);
|
|
||||||
guid += randomHex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return guid.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
objectToGuidPseudorandom(obj) {
|
|
||||||
const seed = this.getSeedFromObject(obj);
|
|
||||||
const prng = this.createSeededRandom(seed);
|
|
||||||
return this.generateVersion4Guid(prng);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Crypto API算法(同步版本)
|
|
||||||
objectToGuidCryptoSync(obj) {
|
|
||||||
try {
|
|
||||||
const str = this.getCanonicalString(obj);
|
|
||||||
let hash = 0;
|
|
||||||
for (let i = 0; i < str.length; i++) {
|
|
||||||
const char = str.charCodeAt(i);
|
|
||||||
hash = ((hash << 5) - hash) + char;
|
|
||||||
hash = hash & hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bytes = new Array(16);
|
|
||||||
for (let i = 0; i < 16; i++) {
|
|
||||||
bytes[i] = (hash + i * 2654435761) & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes[6] = (bytes[6] & 0x0F) | 0x40;
|
|
||||||
bytes[8] = (bytes[8] & 0x3F) | 0x80;
|
|
||||||
|
|
||||||
return bytes.map(b => b.toString(16).padStart(2, '0'))
|
|
||||||
.join('')
|
|
||||||
.replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, '$1-$2-$3-$4-$5')
|
|
||||||
.toUpperCase();
|
|
||||||
} catch (error) {
|
|
||||||
return this.objectToGuidDeterministic(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 组合算法
|
|
||||||
combineComponents(deterministicHash, namespaceHash, timestamp, randomComponent) {
|
|
||||||
const hashDigits = deterministicHash.replace(/-/g, '');
|
|
||||||
const bytes = new Array(16);
|
|
||||||
|
|
||||||
for (let i = 0; i < 16; i++) {
|
|
||||||
const hashByte = parseInt(hashDigits.substr(i * 2, 2), 16) || 0;
|
|
||||||
const nsByte = (namespaceHash >> (i * 2)) & 0xFF;
|
|
||||||
const timeByte = (timestamp >> (i * 2)) & 0xFF;
|
|
||||||
const randomByte = parseInt(randomComponent.substr(i % 8, 1), 16) || 0;
|
|
||||||
|
|
||||||
bytes[i] = (hashByte ^ nsByte ^ timeByte ^ randomByte) & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes[6] = (bytes[6] & 0x0F) | 0x40;
|
|
||||||
bytes[8] = (bytes[8] & 0x3F) | 0x80;
|
|
||||||
|
|
||||||
return bytes.map(b => b.toString(16).padStart(2, '0'))
|
|
||||||
.join('')
|
|
||||||
.replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, '$1-$2-$3-$4-$5')
|
|
||||||
.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
objectToGuidCombined(obj, namespace = '') {
|
|
||||||
const deterministicHash = this.objectToGuidDeterministic(obj);
|
|
||||||
const namespaceHash = namespace ? this.simpleHash(namespace) : 0;
|
|
||||||
const timestamp = Date.now();
|
|
||||||
const randomComponent = Math.random().toString(16).substr(2, 8);
|
|
||||||
|
|
||||||
return this.combineComponents(deterministicHash, namespaceHash, timestamp, randomComponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 主生成函数
|
|
||||||
async generateGuid(inputText, inputType, algorithmType = 'deterministic') {
|
|
||||||
let obj;
|
|
||||||
try {
|
|
||||||
if (inputType === 'json') {
|
|
||||||
obj = JSON.parse(inputText);
|
|
||||||
} else {
|
|
||||||
obj = inputText
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
let guid;
|
|
||||||
let algorithmName;
|
|
||||||
try {
|
|
||||||
switch (algorithmType) {
|
|
||||||
case 'deterministic':
|
|
||||||
guid = this.objectToGuidDeterministic(obj);
|
|
||||||
algorithmName = '确定性哈希算法';
|
|
||||||
break;
|
|
||||||
case 'pseudorandom':
|
|
||||||
guid = this.objectToGuidPseudorandom(obj);
|
|
||||||
algorithmName = '伪随机算法';
|
|
||||||
break;
|
|
||||||
case 'crypto':
|
|
||||||
guid = this.objectToGuidCryptoSync(obj);
|
|
||||||
algorithmName = 'Crypto API算法';
|
|
||||||
break;
|
|
||||||
case 'combined':
|
|
||||||
guid = this.objectToGuidCombined(obj, 'example-namespace');
|
|
||||||
algorithmName = '组合算法';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
guid = '未知算法';
|
|
||||||
algorithmName = '未知';
|
|
||||||
}
|
|
||||||
return guid;
|
|
||||||
} catch (error) {
|
|
||||||
return error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
if (typeof module !== 'undefined' && module.exports) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue