如何在Java中获取唯一的计算机标识符(如磁盘ID或主板ID)?

Goh*_*ohu 60 java uuid uniqueidentifier

我希望在Windows,MacOS以及Linux(如果可能的话)上获得一台带有Java的计算机的唯一ID.它可能是磁盘UUID,主板S/N ......

Runtime.getRuntime().exec 可以使用(它不是applet).

想法?

Bar*_*ryn 45

MAC地址的问题是可以有许多网络适配器连接到计算机.大多数最新版本默认有两个(wi-fi + cable).在这种情况下,人们必须知道应该使用哪个适配器的MAC地址.我在我的系统上测试了MAC解决方案,但是我有4个适配器(有线,WiFi,用于Virtual Box的TAP适配器和一个用于蓝牙),我无法确定应该采用哪个MAC ...如果有人决定使用适配器当前正在使用(已分配地址)然后出现新问题,因为有人可以带他/她的笔记本电脑并从电缆适配器切换到Wi-Fi.当笔记本电脑通过电缆连接时存储的MAC条件现在无效.

例如,那些是我在我的系统中找到的适配器:

lo MS TCP Loopback interface
eth0 Intel(R) Centrino(R) Advanced-N 6205
eth1 Intel(R) 82579LM Gigabit Network Connection
eth2 VirtualBox Host-Only Ethernet Adapter
eth3 Sterownik serwera dostepu do sieci LAN Bluetooth
Run Code Online (Sandbox Code Playgroud)

代码我用来列出它们:

Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
while (nis.hasMoreElements()) {
    NetworkInterface ni = nis.nextElement();
    System.out.println(ni.getName() + " " + ni.getDisplayName());
}
Run Code Online (Sandbox Code Playgroud)

从这个选项上听,对我来说最容易接受,我在我的解决方案中使用的那个是@Ozhan Duz,另一个,类似于@finnw回答,他使用了JACOB,值得一提的是com4j - 使用WMI的示例可在此处获得:

ISWbemLocator wbemLocator = ClassFactory.createSWbemLocator();
ISWbemServices wbemServices = wbemLocator.connectServer("localhost","Root\\CIMv2","","","","",0,null);
ISWbemObjectSet result = wbemServices.execQuery("Select * from Win32_SystemEnclosure","WQL",16,null);
for(Com4jObject obj : result) {
    ISWbemObject wo = obj.queryInterface(ISWbemObject.class);
    System.out.println(wo.getObjectText_(0));
}
Run Code Online (Sandbox Code Playgroud)

这将打印一些计算机信息和计算机序列号.请注意,此示例所需的所有类必须由maven-com4j-plugin生成.maven-com4j-plugin的配置示例:

<plugin>
    <groupId>org.jvnet.com4j</groupId>
    <artifactId>maven-com4j-plugin</artifactId>
    <version>1.0</version>
    <configuration>
        <libId>565783C6-CB41-11D1-8B02-00600806D9B6</libId>
        <package>win.wmi</package>
        <outputDirectory>${project.build.directory}/generated-sources/com4j</outputDirectory>
    </configuration>
    <executions>
        <execution>
            <id>generate-wmi-bridge</id>
            <goals>
                <goal>gen</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)

上面的配置将告诉插件在项目文件夹中的target/generated-sources/com4j目录中生成类.

对于那些希望看到即用型解决方案的人,我要包含我为了在Windows,Linux和Mac OS上获取机器SN而编写的三个类的链接:


Bul*_*aza 27

该OSHI项目提供与平台无关的硬件实用程序.

Maven依赖:

<dependency>
    <groupId>com.github.oshi</groupId>
    <artifactId>oshi-core</artifactId>
    <version>LATEST</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

例如,您可以使用类似以下代码的内容来唯一地标识计算机:

import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.ComputerSystem;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;

class ComputerIdentifier
{
    static String generateLicenseKey()
    {
        SystemInfo systemInfo = new SystemInfo();
        OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
        HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
        CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();
        ComputerSystem computerSystem = hardwareAbstractionLayer.getComputerSystem();

        String vendor = operatingSystem.getManufacturer();
        String processorSerialNumber = computerSystem.getSerialNumber();
        String processorIdentifier = centralProcessor.getIdentifier();
        int processors = centralProcessor.getLogicalProcessorCount();

        String delimiter = "#";

        return vendor +
                delimiter +
                processorSerialNumber +
                delimiter +
                processorIdentifier +
                delimiter +
                processors;
    }

    public static void main(String[] arguments)
    {
        String identifier = generateLicenseKey();
        System.out.println(identifier);
    }
}
Run Code Online (Sandbox Code Playgroud)

我机器的输出:

Microsoft#57YRD12#Intel64 Family 6 Model 60 Stepping 3#8
Run Code Online (Sandbox Code Playgroud)

您的输出会有所不同,因为至少处理器序列号会有所不同.

  • 请注意,其中某些操作需要根访问权限,具体取决于您的操作系统。可能是一个限制因素 (2认同)

小智 19

通常使用与网卡相关联的MAC地址.

通过以下API在Java 6中提供该地址:

Java 6 Docs for Hardware Address

我没有在Java中使用它,但对于其他网络识别应用程序,它一直很有帮助.

  • 我考虑过它,但是当网卡没有连接时,我无法获得任何MAC地址 (5认同)
  • 并且不要忘记,甚至不需要更改网卡以欺骗MAC:http://www.aboutlinux.info/2005/09/how-to-change-mac-address-of-your.html (3认同)

Ped*_*rdi 12

你想用这个唯一的ID做什么?没有这个ID,也许你可以做你想做的事.

MAC地址可能是一个选项,但这不是可信的唯一ID,因为用户可以更改计算机的MAC地址.

要在此链接上检查主板或处理器ID .


fin*_*nnw 9

仅在Windows上,您可以通过COM桥(如JACOB)使用WMI获取主板ID .

例:

import java.util.Enumeration;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;

public class Test {
    public static void main(String[] args) {
        ComThread.InitMTA();
        try {
            ActiveXComponent wmi = new ActiveXComponent("winmgmts:\\\\.");
            Variant instances = wmi.invoke("InstancesOf", "Win32_BaseBoard");
            Enumeration<Variant> en = new EnumVariant(instances.getDispatch());
            while (en.hasMoreElements())
            {
                ActiveXComponent bb = new ActiveXComponent(en.nextElement().getDispatch());
                System.out.println(bb.getPropertyAsString("SerialNumber"));
                break;
            }
        } finally {
            ComThread.Release();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您选择使用MAC地址来识别机器,则可以使用WMI确定接口是否通过USB连接(如果要排除USB适配器.)

也可以通过WMI获取硬盘ID,但这是不可靠的.


Jas*_*ols 7

使用MAC地址作为标识符时要小心.我经历了几次陷阱:

  1. 在OS X上,未激活/启动的以太网端口未显示在NetworkInterface.getNetworkInterfaces()枚举中.
  2. 如果您拥有适当的操作系统权限,那么在卡上更改MAC地址非常容易.
  3. Java有一种不能正确识别"虚拟"接口的习惯.即使使用NetworkInterface.isVirtual()也不会总是告诉你真相.

即使出现上述问题,我仍然认为这是硬件锁定许可证的最佳纯Java方法.


小智 6

不知道你的所有要求.例如,您是尝试从世界上所有计算机中唯一标识计算机,还是只是尝试从应用程序的一组用户中唯一标识计算机.此外,您可以在系统上创建文件吗?

如果您能够创建文件.您可以创建一个文件,并使用该文件的创建时间作为您的唯一ID.如果您在用户空间中创建它,那么它将唯一地标识特定计算机上的应用程序的用户.如果您在某个全局创建它,那么它可以唯一地识别该机器.

同样,大多数情况下,速度有多快......或者在这种情况下,独特性是多么独特.