生成特定计算机唯一ID

12

可能重复:
可靠的生成唯一硬件ID的方法

我正在尝试生成一个对于特定计算机是唯一的ID。该ID不会随机生成。它将基于计算生成,因此为计算机A生成的ID将固定且唯一于计算机A。每次在计算机A上执行程序时,它将继续生成相同的ID,并在另一台计算机上执行时生成另一个唯一于该计算机的ID。这是为了确保两台计算机没有相同的ID。

我的挑战:为了使我的程序能够生成唯一的计算机ID,它需要基于计算机执行的唯一种子进行计算。

我的问题:如何获取唯一于计算机的值,以便我可以将该值用作ID生成程序中的种子?

是否可以从计算机的硬件(例如主板)中获取唯一于该计算机的值?这样,只要计算机的主板没有更换,该值就很可能不会改变。


2
无论如何,都无法以任何有意义的方式完成,这种方式不能被足够有动机的计算机所有者所破坏。如果您正在尝试找到一种设备可以与其连接的其他设备进行唯一区分的方法,那么这是一个不同的问题,有合作解决方案可供选择。 - msw
2
没有物理组件的虚拟机怎么办?如果两个虚拟机具有相同的配置数据,它们是同一台机器吗? - emory
非常感谢大家的快速回复。是否可以获取计算机主处理器的ID?我在互联网上看到过类似的东西,但是它是用C#编写的。想知道是否可以在Java中实现相同的功能。 - Dami Lola
7个回答

10

MAC地址?它(在实际用途中)对每个NIC都是唯一的,因此即使用户双启动,也可以保证可重现性。当然,有些人会交换网卡,但是结合其他指标(不要仅使用此项,因为网络卡可能会更改),仍然有可能。

你该如何获取它?

public static byte[] getMACAddress() throws SocketException, UnknownHostException {
    InetAddress address = InetAddress.getLocalHost();
    NetworkInterface networkInterface = NetworkInterface.getByInetAddress(address);

    return networkInterface.getHardwareAddress();
}

如果您想要一个字符串表示,请执行以下操作

for (int byteIndex = 0; byteIndex < macAddress.length; byteIndex++) {
    System.out.format("%02X%s", macAddress[byteIndex], (byteIndex < macAddress.length - 1) ? "-" : "");
}

(感谢http://www.kodejava.org/examples/250.html

注意:如评论中所述,Mac地址可以被欺骗。但你所说的只是一小部分人这样做,除非你将其用于反盗版之类的用途,否则它足够唯一。


4
如果我更换网卡,请不要让我重新安装软件。 - Michael Petrotta
2
@EJP 95%的情况下,它们并不是由用户伪造的。你所说的只是人群中的一小部分:A)甚至知道如何做到这一点,B)非常偏执,C)关心这个问题。 - TheLQ
2
@TheLQ 换句话说,它不是唯一的。 - user207421
1
@EJP,找到任何保证唯一的ID是不可能的。即使是2^128位的随机数也不能保证是唯一的。只是很不可能有其他人在相同的上下文中生成完全相同的数字。 - extraneon
如果用户从局域网切换到WiFi,那么使用哪个MAC地址? - Tomáš Zato
显示剩余6条评论

7
Win32生成计算机SID,该SID应该是通过WMI或Active Directory获得的每个安装程序都是唯一的,但这是相当特定于平台的。您还可以使用MAC地址,就像其他人提到的那样,只要确保它是物理网络适配器,因为虚拟适配器倾向于在计算机之间共享相同的MAC地址。
然而,UUID(或GUID)是128位数字,被认为是保证唯一的,并且实际上是为解决在多个随机机器之间生成唯一标识符的问题而创建的。根据维基百科:
“为了将这些数字放入透视中, 被流星撞击的年度风险之一 被估计为170亿分之一,[25]这意味着 概率约为0.00000000006 (6×10 ^ -11),相当于 在一年内创建数万亿个UUID并具有一个重复项的几率。 换句话说,在未来100年里每秒生成10亿个UUID后, 仅产生一个重复项的概率约为50%。 如果地球上的每个人都拥有6亿个UUID,则一个重复项的概率约为50%。”
可能组合的总数为2^128(或3 x 10 ^ 38),所以我倾向于相信它。此外,大多数现代UUID生成器不再使用V1算法(即基于MAC地址的算法),因为它被认为是安全问题,因为可以知道GUID何时生成以及谁生成了它。在Win32世界中,围绕Win2K或NT 4的安全补丁更改为使用基于伪随机数而不是MAC的V4版本算法,并且JVM始终使用V3 / V4版本。
编辑:在Java中生成UUID的方法是通过java.util.UUID类。

那么执行 UUID.fromString("some string"); 会在多个虚拟机实例上生成完全相同的 UUID 吗? 在同一台计算机上但在不同操作系统上呢? - TheLQ
@TheLQ: "some string" 无法解析 :) 你有阅读过 http://www.ietf.org/rfc/rfc4122.txt 吗? - extraneon
@TheLQ: 语法应该是UUID.fromString("{00000000-0000-0000-0000-000000000000}"),用于将现有的 UUID 字符串表示转换为 UUID 类,因此,对于相同的输入值(假设您硬编码了输入字符串),每次都会得到相同的 UUID。要生成新的 UUID,可以使用 UUID.randomUUID(),它应该在多个 VM 实例之间是唯一的。 - Javert93
我忘了提到,但对于不同的操作系统也是一样的。 - Javert93
UUID并不能解决任何问题。生成的数据必须存储在文件中。该文件可能会被盗取或复制。我需要的是系统/计算机的一部分,无法轻易通过获取设置文件而被窃取。 - Tomáš Zato

1

0

幸运的是,这篇文章的标签确实指明了他使用的编程语言。在我打完之前就有三个人回答了...我想那可能是新纪录 :) - Dan J

0

您最好的选择是基于主网络适配器的MAC地址作为ID。

这有可能在某些时候发生变化,但任何单个硬件组件都有可能如此。

顺便说一下,GUID是使用MAC地址进行计算的。


哈哈...一次买四个。 - ocodo

0

序列号是指与Windows操作系统相关的,还是实际制造商的序列号? - avacariu
这与物理外壳有关。如果它能正常工作,我指出这是仅适用于Windows的解决方案。 - James

0

如果你正在使用英特尔芯片,另一个选择是使用处理器序列号,假设你可以确保该功能已启用。有关更多信息,请参见Intel Serial # Note


他正在使用Java,这里没有处理器的概念 :) - L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接