bookworm-smart-assistant/lib/fingerprint.js

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());
}