2012-11-16 86 views
6

我想使用Java生成特定的计算机ID。我曾考虑过硬盘序列号或Windows串行密钥,CPU ID或MAC地址等内容,但其他计算机可能具有相同的内容。例如,如果有人盗用Windows 7的副本,则它们可能具有相同的序列号作为某人..我想知道如果有人可以给我一种方法来生成一个从未改变,并可以使用Java检索的计算机特定ID?计算机特定的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(); 
} 
+0

那么,你如何定义电脑的独特性?我想如果他们改变硬件,他们会改变他们的ID。 –

+0

的确如此,我试图找到一种方法来生成一个在改变硬件时不会改变的计算机ID .. –

+2

这将成为版权所有者以及DRM创造者无处不在的幻想漫长的高潮。问题很复杂,无边无际,“陷阱”和妥协。祝你好运! –

回答

4

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

System.getProperty("os.name"); 
+0

拥有提供唯一ID并将该ID存储在客户端计算机上的中央管理系统的概念是可靠的。然而,海报没有详细解释他的用例,以确定这个解决方案是否适用于他的案例。不过,我不明白为什么你会在这种情况下使用客户机的MAC地址或其他硬件属性。 –

1

看在每个人的投入后,也有不少谷歌搜索,我得出这样的结论

技术性,看起来好像你删除了一个组件并替换了它,它将是一台全新的计算机,为了生成一个真正的计算机特定的ID,你必须从系统中的每个组件获得一个特定的变量。序列号),将它们全部结合起来,这就是“计算机专用ID”。但是,由于计算机容易发生变化,最接近的就是采取最可靠的更改组件,并且我们为计算机ID指定一个特定的变量。这通常是主板或其他不太可能改变的组件。所以,最接近的人可能是主板的序列号(或其他子组件)。在我个人看来。

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

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

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

你好,对不起,如果这个问题看起来很天真,但是这个答案只适用于windows,对吗? – SpencerD

+0

是的,不幸的是只有窗户。 – user3158918