mirror of
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git
synced 2025-10-22 22:53:09 +00:00
169 lines
4.2 KiB
JavaScript
169 lines
4.2 KiB
JavaScript
const crypto = require("crypto");
|
||
const os = require("os");
|
||
|
||
class AdvancedClientSignGenerator {
|
||
/**
|
||
* 获取本机MAC地址
|
||
*/
|
||
static getRealMacAddress() {
|
||
try {
|
||
const interfaces = os.networkInterfaces();
|
||
for (let interfaceName in interfaces) {
|
||
const interface = interfaces[interfaceName];
|
||
for (let i = 0; i < interface.length; i++) {
|
||
const alias = interface[i];
|
||
// 排除内部地址和无效地址
|
||
if (
|
||
alias.mac &&
|
||
alias.mac !== "00:00:00:00:00:00" &&
|
||
!alias.internal
|
||
) {
|
||
return alias.mac.toUpperCase();
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
} catch (error) {
|
||
console.warn("获取MAC地址失败:", error.message);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 生成随机MAC地址
|
||
*/
|
||
static generateRandomMac() {
|
||
const chars = "0123456789ABCDEF";
|
||
let mac = "";
|
||
for (let i = 0; i < 6; i++) {
|
||
if (i > 0) mac += ":";
|
||
mac +=
|
||
chars[Math.floor(Math.random() * 16)] +
|
||
chars[Math.floor(Math.random() * 16)];
|
||
}
|
||
// 确保第一个字节是单播地址(最低位为0)
|
||
const firstByte = parseInt(mac.substring(0, 2), 16);
|
||
const unicastFirstByte = (firstByte & 0xfe)
|
||
.toString(16)
|
||
.padStart(2, "0")
|
||
.toUpperCase();
|
||
return unicastFirstByte + mac.substring(2);
|
||
}
|
||
|
||
/**
|
||
* 获取MAC地址(优先真实,否则随机)
|
||
*/
|
||
static getMacAddress() {
|
||
const realMac = this.getRealMacAddress();
|
||
if (realMac) {
|
||
return realMac;
|
||
}
|
||
console.warn("无法获取真实MAC地址,使用随机生成");
|
||
return this.generateRandomMac();
|
||
}
|
||
|
||
/**
|
||
* 字符串转HEX编码
|
||
*/
|
||
static stringToHex(str) {
|
||
return Buffer.from(str, "utf8").toString("hex").toUpperCase();
|
||
}
|
||
|
||
/**
|
||
* SHA-256哈希
|
||
*/
|
||
static sha256(data) {
|
||
return crypto.createHash("sha256").update(data, "utf8").digest("hex");
|
||
}
|
||
|
||
/**
|
||
* 生成随机设备ID
|
||
*/
|
||
static generateRandomDeviceId() {
|
||
const partLengths = [4, 4, 4, 4, 4, 4, 4, 5]; // 各部分长度
|
||
const chars = "0123456789ABCDEF";
|
||
|
||
const parts = partLengths.map((length) => {
|
||
let part = "";
|
||
for (let i = 0; i < length; i++) {
|
||
part += chars[Math.floor(Math.random() * 16)];
|
||
}
|
||
return part;
|
||
});
|
||
|
||
return parts.join("_");
|
||
}
|
||
|
||
/**
|
||
* 生成随机clientSign(优先使用真实MAC,否则随机)
|
||
*/
|
||
static generateRandomClientSign(secretKey = "") {
|
||
// 获取MAC地址(优先真实,否则随机)
|
||
const macAddress = this.getMacAddress();
|
||
|
||
// 生成随机设备ID
|
||
const deviceId = this.generateRandomDeviceId();
|
||
|
||
// 转换设备ID为HEX
|
||
const hexDeviceId = this.stringToHex(deviceId);
|
||
|
||
// 构造签名字符串
|
||
const signString = `${macAddress}@@@${hexDeviceId}`;
|
||
|
||
// 生成哈希
|
||
const hash = this.sha256(signString + secretKey);
|
||
|
||
return `${signString}@@@@@@${hash}`;
|
||
}
|
||
|
||
/**
|
||
* 批量生成多个随机签名
|
||
*/
|
||
static generateMultipleRandomSigns(count, secretKey = "") {
|
||
const signs = [];
|
||
for (let i = 0; i < count; i++) {
|
||
signs.push(this.generateRandomClientSign(secretKey));
|
||
}
|
||
return signs;
|
||
}
|
||
|
||
/**
|
||
* 使用指定参数生成签名
|
||
*/
|
||
static generateWithCustomDeviceId(macAddress, deviceId, secretKey = "") {
|
||
const hexDeviceId = this.stringToHex(deviceId);
|
||
const signString = `${macAddress}@@@${hexDeviceId}`;
|
||
const hash = this.sha256(signString + secretKey);
|
||
return `${signString}@@@@@@${hash}`;
|
||
}
|
||
|
||
/**
|
||
* 验证签名格式是否正确
|
||
*/
|
||
static validateClientSign(clientSign) {
|
||
try {
|
||
const parts = clientSign.split("@@@@@@");
|
||
if (parts.length !== 2) return false;
|
||
|
||
const [infoPart, hash] = parts;
|
||
const infoParts = infoPart.split("@@@");
|
||
if (infoParts.length !== 2) return false;
|
||
|
||
const [mac, hexDeviceId] = infoParts;
|
||
|
||
// 验证MAC地址格式
|
||
const macRegex = /^([0-9A-F]{2}:){5}[0-9A-F]{2}$/;
|
||
if (!macRegex.test(mac)) return false;
|
||
|
||
// 验证哈希格式
|
||
const hashRegex = /^[0-9a-f]{64}$/;
|
||
if (!hashRegex.test(hash)) return false;
|
||
|
||
return true;
|
||
} catch (error) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
module.exports = AdvancedClientSignGenerator; |