2012-11-16 168 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