web-dev-qa-db-ja.com

Java(ディスクIDやマザーボードIDなど)で一意のコンピューター識別子を取得する方法は?

Java、Windows、MacOS、可能であればLinuxを搭載したコンピューターに固有のIDを取得したいと思います。ディスクUUID、マザーボードS/N ...

Runtime.getRuntime().execを使用できます(アプレットではありません)。

アイデア?

57
Gohu

ネットワークカードに関連付けられているMACアドレスを使用するのが一般的です。

アドレスは、次のAPIを介してJava 6で利用可能です。

ハードウェアアドレスのJava 6ドキュメント

Javaでは使用していませんが、他のネットワーク識別アプリケーションには役立ちました。

19
nickk_can

MACアドレスの問題は、コンピューターに多数のネットワークアダプターが接続されている可能性があることです。最新のもののほとんどは、デフォルトで2つあります(wi-fi +ケーブル)。このような状況では、どのアダプターのMACアドレスを使用する必要があるかを知る必要があります。システムでMACソリューションをテストしましたが、4つのアダプター(ケーブル、WiFi、Virtual Box用のTAPアダプターとBluetooth用のアダプター)があり、どの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

リストに使用したコード:

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

このページで聞くオプションから、私にとって最も受け入れられ、私のソリューションで使用したものは@Ozhan Duzのもので、もう1つはJACOBを使用した@finnw回答に似ており、言及する価値があります com4j -WMIを利用するサンプルが利用可能です here

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));
}

これにより、コンピューターのシリアル番号とともにコンピューター情報が出力されます。この例で必要なすべてのクラスは、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>

上記の設定は、プロジェクトフォルダーのtarget/generated-sources/com4jディレクトリーにクラスを生成するようプラグインに指示します。

ready-to-useソリューションを見たい人のために、WindowsでマシンSNを取得するために書いた3つのクラスへのリンクを含めます。 LinuxおよびMac OS:

44
Bartosz Firyn

OSHI プロジェクトは、platform-independentハードウェアユーティリティを提供します。

Maven依存関係:

<dependency>
    <groupId>com.github.oshi</groupId>
    <artifactId>oshi-core</artifactId>
    <version>LATEST</version>
</dependency>

たとえば、次のコードのようなものを使用して、マシンを一意に識別できます。

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);
    }
}

私のマシンの出力:

Microsoft#57YRD12#Intel64 Family 6 Model 60 Stepping 3#8

少なくともプロセッサーのシリアル番号が異なるため、出力は異なります。

25
BullyWiiPlaza

この一意のIDで何をしたいですか?たぶん、あなたはこのIDなしであなたが望むことをすることができます。

MACアドレスは1つのオプションかもしれませんが、ユーザーはコンピューターのMACアドレスを変更できるため、これは信頼できる一意のIDではありません。

マザーボードまたはプロセッサIDを取得するには、この link を確認してください。

12
Pedro Ghilardi

Windowsでのみ、 [〜#〜] wmi [〜#〜] を使用してマザーボードIDを取得できます。COMブリッジでは [〜#〜] jacob [〜#〜 ]

例:

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

MACアドレスを使用してマシンを識別することを選択した場合、WMIを使用して、インターフェイスがUSB経由で接続されているかどうかを判断できます(USBアダプタを除外する場合)。

WMIを介してハードドライブIDを取得することも可能ですが、これは信頼できません。

9
finnw

MACアドレスを識別子として使用する場合は注意してください。私はいくつかの落とし穴を経験しました:

  1. OS Xでは、アクティブ/アップではないイーサネットポートは NetworkInterface.getNetworkInterfaces() 列挙に表示されません。
  2. 適切なOS権限を持っている場合、カードのMACアドレスを変更するのは非常に簡単です。
  3. Javaには、「仮想」インターフェースを正しく識別しないという習慣があります。 NetworkInterface.isVirtual() を使用しても、必ずしも真実がわかるとは限りません。

上記の問題があったとしても、ライセンスをロックするハードウェアに対する最善の純粋なJavaアプローチです。

7
Jason Nichols

すべての要件を知らない。たとえば、世界のすべてのコンピューターからコンピューターを一意に識別しようとしているのですか、それともアプリケーションの一連のユーザーからコンピューターを一意に識別しようとしているのですか。また、システム上にファイルを作成できますか?

ファイルを作成できる場合。ファイルを作成し、ファイルの作成時間を一意のIDとして使用できます。ユーザー空間で作成すると、特定のマシン上のアプリケーションのユーザーを一意に識別します。グローバルな場所に作成した場合、マシンを一意に識別できます。

繰り返しになりますが、ほとんどの場合と同様に、どのくらいの速さで十分に高速です。

6
sindri

これを見る必要があると思います link ... mac + os + hostname + cpu id + motherboard serial番号

3
Michel Gokan

[〜#〜] mac [〜#〜]idの使用は、タスクがシステムの一意のidを記録することである場合に最も簡単な方法です。

mac idの変更は可能ですが、システムの他のidの変更も可能であり、それぞれのデバイスが交換されます。

そのため、一意のIDに必要なものが不明な場合を除き、適切な解決策を見つけることができない場合があります。

ただし、以下のリンクはMACアドレスの抽出に役立ちます。 http://www.stratos.me/2008/07/find-mac-address-using-Java/

1
Vamsy

Windowsマシンを一意に識別するため。 wmicを使用して代替方法の戦略を立てるときは必ず確認してください。 「wmic bios get serialnumber」はすべてのマシンで機能しない可能性があるため、追加のメソッドが必要になる場合があります。

# Get serial number from bios
wmic bios get serialnumber
# If previous fails, get UUID
wmic csproduct get UUID
# If previous fails, get diskdrive serialnumber
wmic DISKDRIVE get SerialNumber

リソース:Windowsマシンを一意に識別する最良の方法 http://www.nextofwindows.com/the-best-way-to-uniquely-identify-a-windows-machine/

1
Basil Musa

リリース用に作成したJavaプログラムでは、マザーボードのシリアル番号を使用しました(これはWindowsが使用しているものです)。ただし、これは、私の関数が値を取得するためにWMIを使用する一時的なVBスクリプトを作成するため、Windowsでのみ機能します。

public static String getMotherboardSerial() {
      String result = "";
        try {
          File file = File.createTempFile("GetMBSerial",".vbs");
          file.deleteOnExit();
          FileWriter fw = new FileWriter(file);

          String vbs =
             "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
            + "Set colItems = objWMIService.ExecQuery _ \n"
            + "   (\"Select * from Win32_ComputerSystemProduct\") \n"
            + "For Each objItem in colItems \n"
            + "    Wscript.Echo objItem.IdentifyingNumber \n"
            + "Next \n";

          fw.write(vbs);
          fw.close();
          Process gWMI = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
          BufferedReader input = new BufferedReader(new InputStreamReader(gWMI.getInputStream()));
          String line;
          while ((line = input.readLine()) != null) {
             result += line;
             System.out.println(line);
          }
          input.close();
        }
        catch(Exception e){
            e.printStackTrace();
        }
        result = result.trim();
        return result;
      }
0
Charles Eddy