65 lines
1.8 KiB
JavaScript
65 lines
1.8 KiB
JavaScript
|
|
/**
|
||
|
|
* 设备指纹生成 - 跨平台
|
||
|
|
* 基于: 主机名 + 用户名 + CPU ID + 磁盘序列号 + 架构
|
||
|
|
* 输出 SHA-256 hex (64 字符)
|
||
|
|
*/
|
||
|
|
const crypto = require("crypto");
|
||
|
|
const os = require("os");
|
||
|
|
const { execSync } = require("child_process");
|
||
|
|
|
||
|
|
function safeExec(cmd) {
|
||
|
|
try {
|
||
|
|
return execSync(cmd, { encoding: "utf8", timeout: 3000, windowsHide: true }).toString();
|
||
|
|
} catch { return ""; }
|
||
|
|
}
|
||
|
|
|
||
|
|
function cpuId() {
|
||
|
|
if (process.platform === "win32") {
|
||
|
|
// 用绝对路径防 PATH 污染
|
||
|
|
const wmic = "C:\\Windows\\System32\\wbem\\wmic.exe";
|
||
|
|
const out = safeExec(`"${wmic}" cpu get ProcessorId /value`);
|
||
|
|
const m = out.match(/ProcessorId=([A-F0-9]+)/i);
|
||
|
|
return m ? m[1] : "";
|
||
|
|
}
|
||
|
|
if (process.platform === "darwin") {
|
||
|
|
const out = safeExec("system_profiler SPHardwareDataType");
|
||
|
|
const m = out.match(/Hardware UUID:\s+([A-F0-9-]+)/);
|
||
|
|
return m ? m[1] : "";
|
||
|
|
}
|
||
|
|
// Linux
|
||
|
|
return safeExec("cat /etc/machine-id 2>/dev/null").trim();
|
||
|
|
}
|
||
|
|
|
||
|
|
function diskSerial() {
|
||
|
|
if (process.platform === "win32") {
|
||
|
|
const wmic = "C:\\Windows\\System32\\wbem\\wmic.exe";
|
||
|
|
const out = safeExec(`"${wmic}" diskdrive get SerialNumber /value`);
|
||
|
|
const lines = out.split(/\r?\n/).filter(l => /SerialNumber=.+/.test(l));
|
||
|
|
return lines[0]?.split("=")[1]?.trim() || "";
|
||
|
|
}
|
||
|
|
if (process.platform === "darwin") {
|
||
|
|
const out = safeExec("diskutil info /");
|
||
|
|
const m = out.match(/Volume UUID:\s+([A-F0-9-]+)/);
|
||
|
|
return m ? m[1] : "";
|
||
|
|
}
|
||
|
|
return safeExec("lsblk -no SERIAL 2>/dev/null | head -1").trim();
|
||
|
|
}
|
||
|
|
|
||
|
|
function fingerprint() {
|
||
|
|
const raw = [
|
||
|
|
os.hostname(),
|
||
|
|
os.userInfo().username,
|
||
|
|
cpuId(),
|
||
|
|
diskSerial(),
|
||
|
|
os.arch()
|
||
|
|
].join("::");
|
||
|
|
return crypto.createHash("sha256").update(raw).digest("hex");
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = { fingerprint };
|
||
|
|
|
||
|
|
if (require.main === module) {
|
||
|
|
// 直接运行时打印指纹
|
||
|
|
console.log(fingerprint());
|
||
|
|
}
|