6

我正在尝试使用 Java 生成特定的计算机 ID。我考虑过诸如硬盘序列号、Windows 序列号、CPU ID 或 MAC 地址之类的东西,但其他计算机可能有相同的。例如,如果有人盗版 Windows 7,他们可能有相同的序列号作为某人.. 我想知道是否有人可以给我一种方法来生成一个永远不会改变并且可以使用 Java 检索的计算机特定 ID?

我做了一些研究,发现了一些有用的功能。而且,我在想​​这样的事情。但是如果他们改变他们的硬件,它会改变计算机ID。有人知道我可以使用的东西吗?

public String getComputerID(){
    InetAddress ip = InetAddress.getLocalHost();
    NetworkInterface network = NetworkInterface.getByInetAddress(ip);
    byte[] mac = network.getHardwareAddress();
    String sn = getSerialNumber("C");
    String cpuId = getMotherboardSN();
    return MD5(mac + sn + cpuId);
}


public String MD5(String md5) {
try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(md5.getBytes());
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
        sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
    }
        return sb.toString();
    } catch (java.security.NoSuchAlgorithmException e) {
    }
    return null;
}

public String getSerialNumber(String drive) {
String result = "";
    try {
    File file = File.createTempFile("realhowto",".vbs");
    file.deleteOnExit();
    FileWriter fw = new java.io.FileWriter(file);

  StringBufferring vbs = "Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n"
                +"Set colDrives = objFSO.Drives\n"
                +"Set objDrive = colDrives.item(\"" + drive + "\")\n"
                +"Wscript.Echo objDrive.SerialNumber";  // see note
    fw.write(vbs);
    FileWriter.close();
      Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
      BufferedReader input =
        new BufferedReader
        (new InputStreamReader(p.getInputStream()));
    String line;
    while ((line = input.readLine()) != null) {
        result += line;
    }
    input.close();
    }
    catch(Exception e){
        e.printStackTrace();
    }
    return result.trim();
}

public String getMotherboardSN() {
String result = "";
try {
File file = File.createTempFile("realhowto",".vbs");
file.deleteOnExit();
FileWriter fw = new java.io.FileWriter(file);

String vbs =
"Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
+ "Set colItems = objWMIService.ExecQuery _ \n"
+ " (\"Select * from Win32_BaseBoard\") \n"
+ "For Each objItem in colItems \n"
+ " Wscript.Echo objItem.SerialNumber \n"
+ " exit for ' do the first cpu only! \n"
+ "Next \n";

fw.write(vbs);
fw.close();
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result += line;
}
input.close();
}
catch(Exception e){
e.printStackTrace();
}
return result.trim();
}
4

3 回答 3

4

我实际上确实相信您应该使用硬件配置文件中的某些东西。
可以将计算机视为一组硬件,包括网络接口。一个典型的模式可以是通过管理网络计算机的管理系统将 MAC 地址和生成的 ID 组合在一起。
在向管理系统注册过程中唯一标识机器的 MAC 地址。
作为注册的结果,管理系统可以返回一个生成的UniqueId,
存储在注册它的计算机上,供以后使用。
注册成功后,可以更换网卡,因为电脑不依赖MAC地址来识别。
您还可以考虑使用 linux dmidecode 实用程序
(对于 linux 机器,
因为您提供了基于 win 的解决方案,
所以对于我们的 linux 读者,
我想建议一个 linux 替代方案)(如果您要唯一识别的机器具有 linux 和dmidecoe 安装)。
使用 dmidecoe,您可以获得更多硬件配置文件,并对其执行一些哈希函数,并生成一个唯一 ID,该 ID 将唯一(准确地说,很有可能)标识您的机器。在此处
阅读有关 dmidecode的更多信息。 当然,如果您使用“从操作系统获取硬件信息”方法(即 dmidecode 或您在获取 MAC 地址后的部分建议,

您需要一个跨平台代码来检查 java 程序运行的操作系统是什么,您可以使用以下方法:

System.getProperty("os.name");
于 2012-11-16T20:27:52.453 回答
1

在查看了每个人的意见之后,我在谷歌上搜索了很多次,我得出了这个结论

从技术上讲,好像您卸下并更换了一个组件,这将是一台全新的计算机,要生成真正的计算机特定 ID,您必须从系统中的每个组件中获取特定变量(即序列号) ,将它们全部组合起来,这将是一个“计算机特定 ID”。但是,由于计算机非常容易更改,因此最接近的方法是采用 LAST LIKELY TO CHANGE 组件,并从中获取特定变量作为计算机 ID。这通常是主板或其他不太可能更改的组件。因此,最接近的可能是主板的序列号(或其他一些子组件)。在我个人看来。

为什么主板最不可能改变?

似乎主板是人们考虑更换的最后一部分,尤其是在较新的计算机上。除非绝对需要,否则他们通常不会更改它。另一个可行的选择是 NIC。老实说,您使用哪种硬件取决于您,但最好使用的是您认为最不可能更改的硬件。

于 2013-10-27T03:22:04.317 回答
1

对于磁盘/卷,它可能是:

    /**
     * Execute system console command 'vol' and retrieve volume serial number
     *
     * @param driveLetter - drive letter in convetion 'X:'
     * @return - Volume Serial Number, typically: 'XXXX-XXXX'
     * @throws IOException
     * @throws InterruptedException
     */
    static final String getVolumeSerial(String driveLetter) throws IOException, InterruptedException {
        Process process = Runtime.getRuntime().exec("cmd /C vol " + driveLetter);
        InputStream inputStream = process.getInputStream();
        InputStream errorStream = process.getErrorStream();
        if (process.waitFor() != 0) {
            Scanner sce = new Scanner(errorStream);
            throw new RuntimeException(sce.findWithinHorizon(".*", 0));
        }
        Scanner scn = new Scanner(inputStream);
        // looking for: ': XXXX-XXXX' using regex
        String res = scn.findWithinHorizon(": \\w+-\\w+", 0);
        return res.substring(2).toUpperCase().trim();
    }
于 2014-01-03T22:48:17.457 回答