计算机专用ID?

时间:2012-11-16 19:51:53

标签: java

我正在尝试使用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();
}

3 个答案:

答案 0 :(得分:4)

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

System.getProperty("os.name");

答案 1 :(得分:1)

在查看了所有人的输入以及相当多的谷歌搜索后,我得出了这个结论

在技术性方面,看起来好像你删除了一个组件并替换它,它将是一个全新的计算机,生成一个真正的计算机专用ID,你必须从系统中的每个组件获得一个特定的变量,(即序列号),将它们全部组合起来,这将是一个&#34;计算机专用ID&#34;。但是,由于计算机很容易发生变化,因此最接近的计算机是获取LEAST LIKELY TO CHANGE组件,并从中获取计算机ID的特定变量。这通常是主板或其他不太可能改变的组件。所以,最接近的可能是主板的序列号(或其他一些子组件)..在我个人看来。

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

主板似乎是人们考虑改变的最后一部分,特别是在新电脑上。除非绝对需要,否则他们通常不会改变它。另一个可行的选择是NIC。老实说,你使用的硬件是什么,但最好用的是你认为最不容易改变的硬件。

答案 2 :(得分: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();
    }
相关问题