package com.tongran.agent.client.utils; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.NetworkInterface; import java.net.SocketException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Enumeration; public class MachineFingerprint { /** * 获取服务器硬件指纹:MD5( MAC + CPU信息 ) */ public static String getHardwareFingerprint() { StringBuilder data = new StringBuilder(); // 1. 获取第一个非回环网卡的 MAC 地址 String mac = getFirstValidMacAddress(); if (mac != null) { data.append(mac); System.out.println("MAC 信息="+mac); } else { System.err.println("无法获取 MAC 地址"); } // 2. 获取 CPU 信息(如 CPU 型号、序列号) String cpuInfo = getCpuInfo(); if (cpuInfo != null) { System.out.println("CPU 信息="+cpuInfo); data.append(cpuInfo); } else { System.err.println("无法获取 CPU 信息"); } data.append(System.currentTimeMillis()); if (data.length() == 0) { return "unknown"; } // 3. 生成 MD5 return md5(data.toString()); } /** * 获取第一个非回环、UP 状态网卡的 MAC 地址 */ private static String getFirstValidMacAddress() { try { Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface ni = interfaces.nextElement(); if (ni.isLoopback() || !ni.isUp()) continue; byte[] mac = ni.getHardwareAddress(); if (mac != null && mac.length > 0) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < mac.length; i++) { sb.append(String.format("%02X", mac[i])); if (i < mac.length - 1) sb.append(":"); } return sb.toString(); } } } catch (SocketException e) { e.printStackTrace(); } return null; } /** * 读取 CPU 信息(CPU 型号 + 序列号,如果存在) */ private static String getCpuInfo() { StringBuilder cpuInfo = new StringBuilder(); try { Process process = Runtime.getRuntime().exec("cat /proc/cpuinfo"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; boolean found = false; while ((line = reader.readLine()) != null) { if (line.contains("model name")) { cpuInfo.append(line.split(":")[1].trim()).append(";"); found = true; } // 树莓派等设备有 cpu serial if (line.contains("Serial")) { cpuInfo.append("Serial=").append(line.split(":")[1].trim()); found = true; } // 多数 x86 服务器没有 serial,可用 processor 数量做补充 if (line.startsWith("processor")) { // 可选:记录核心数 } } reader.close(); return found ? cpuInfo.toString() : null; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 生成 MD5 哈希 */ private static String md5(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(input.getBytes()); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b & 0xff)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("MD5 算法不可用", e); } } // ================== 测试 ================== public static void main(String[] args) { String fingerprint = getHardwareFingerprint(); System.out.println("服务器硬件指纹 (MD5): " + fingerprint); } }