Unique Computer Id

What is a good unique PC identifier?

Some good identifiers:

  • MAC Address: It's fairly easy to get at, and it's usually unique. However, it can be spoofed/changed rather easily, so it depends on how unique it needs to be.
  • CPU Serial Number: It's not available on lots of older systems, but it's there. Check out this MSDN page. It won't change, but it's bound to a computer.
  • HDD Serial Number: It's likely to not change, but can be a nuisance if the HD fails. Check out this MSDN page.

Unique computer ID

Like you've said CPU Id wont be unique, however you can use it with another hardware identifier to create your own unique key.

Reference assembly System.Management

So, use this code to get the CPU ID:

string cpuInfo = string.Empty;
ManagementClass mc = new ManagementClass("win32_processor");
ManagementObjectCollection moc = mc.GetInstances();

foreach (ManagementObject mo in moc)
{
cpuInfo = mo.Properties["processorID"].Value.ToString();
break;
}

Then use this code to get the HD ID:

string drive = "C";
ManagementObject dsk = new ManagementObject(
@"win32_logicaldisk.deviceid=""" + drive + @":""");
dsk.Get();
string volumeSerial = dsk["VolumeSerialNumber"].ToString();

Then, you can just combine these two serials to get a uniqueId for that machine:

string uniqueId = cpuInfo + volumeSerial;

Obviously, the more hardware components you get the IDs of, the greater the uniqueness becomes. However, the chances of the same machine having an identical CPU serial and Hard disk serial are already slim to none.

Generating a unique machine id

Parse the SMBIOS yourself and hash it to an arbitrary length. See the PDF specification for all SMBIOS structures available.

To query the SMBIOS info from Windows you could use EnumSystemFirmwareEntries, EnumSystemFirmwareTables and GetSystemFirmwareTable.

IIRC, the "unique id" from the CPUID instruction is deprecated from P3 and newer.

Unique Identifier for the PC

Interfaces doesnt get removed if you use one or another. Just loop NetworkInterface.getNetworkInterfaces() and check if one has the same MAC you registered.

The problem could be if you use a interface the is not integrated into the computer. Say a dongle which can be removed. Perhaps save all MAC adresses and check if any of them is present. Though then you can move a dongle to another computer and still get a yes.

If you want to really identify by windows uuid you can use the cmd command:

wmic csproduct get UUID

In java use Runtime.exec("wmic csproduct get UUID"); And then read the output with the outputstream of the Process and store it. I havent tested it but it should work.

How to get a unique PC ID from a web browser

You could use this as a computer ID:

$computerId = $_SERVER['HTTP_USER_AGENT'].$_SERVER['LOCAL_ADDR'].$_SERVER['LOCAL_PORT'].$_SERVER['REMOTE_ADDR'];

It's not completely fool proof, as the values of $_SERVER can be faked, however it will still add an extra layer of security that does not rely on cookies.

How to get a unique computer identifier in Java (like disk ID or motherboard ID)?

It is common to use the MAC address is associated with the network card.

The address is available in Java 6 through through the following API:

Java 6 Docs for Hardware Address

I haven't used it in Java, but for other network identification applications it has been helpful.

Get a unique computer ID in Python on windows and linux

How about using the MAC address as unique id?

The discussion here Obtain MAC Address from Devices using Python shows how to obtain the MAC address

How do I generate a unique number for every computer?

You realistically have MotherboardID, CPUID, Disk Serial and MAC address, from experience none of them are 100%.

Our stats show

  • Disk serial Is missing 0.1 %
  • MAC Is missing 1.3 %
  • Motherboard ID Is missing 30 %
  • CPUID Is missing 99 %

0.04% of machines tested they yielded no information, we couldn't even read the computer name. It maybe that these were some kind over virtual PC, HyperV or VMWare instance?

Disk serial is the most reliable, but easy to change, mac can be changed and depending on the filtering applied can change if device drivers are added (hyperv, wireshark etc).

Motherboard and CPUID sometimes return values that are placeholders "NONE" etc.

You should also note that these functions can be very slow to call (they may take a few seconds even on a fast PC), so it may be worth kicking them off on a background thread as early as possible, you ideally don't want to be blocking on them.

Motherboard ID

    private static void FetchMotherboardIdInternal()
{
try
{
ManagementScope scope = new ManagementScope("\\\\" + Environment.MachineName + "\\root\\cimv2");
scope.Connect();

using (ManagementObject wmiClass = new ManagementObject(scope, new ManagementPath("Win32_BaseBoard.Tag=\"Base Board\""), new ObjectGetOptions()))
{
object motherboardIDObj = wmiClass["SerialNumber"];
if (motherboardIDObj != null)
{
string motherboardID = motherboardIDObj.ToString().Trim();
Trace.WriteLine("MotherboardID = " + motherboardID);
if (IsValidMotherBoardID(motherboardID))
{
_motherboardID = motherboardID;
}
}
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
Trace.TraceWarning("Failed to read MotherbaordID\r\n" + ex.Message);
}
}
public static bool IsValidMotherBoardID(string value)
{
if (value == null)
return false;
string motherboardID = value.Trim();
return !( motherboardID.Replace(".", "").Replace(" ", "").Replace("\t", "").Trim().Length < 5 ||
motherboardID.ToUpper().Contains("BASE") ||
motherboardID.Contains("2345") ||
motherboardID.ToUpper().StartsWith("TO BE") ||
motherboardID.ToUpper().StartsWith("NONE") ||
motherboardID.ToUpper().StartsWith("N/A") ||
motherboardID.ToUpper().Contains("SERIAL") ||
motherboardID.ToUpper().Contains("OEM") ||
motherboardID.ToUpper().Contains("AAAAA") ||
motherboardID.ToUpper().Contains("ABCDE") ||
motherboardID.ToUpper().Contains("XXXXX") ||
motherboardID.ToUpper().Contains("NOT") ||
motherboardID.ToUpper().StartsWith("00000")
);

}

CPU ID

    private static void FetchCpuIdInternal()
{
try
{
using (ManagementClass mc = new ManagementClass("Win32_Processor"))
{
using (ManagementObjectCollection moc = mc.GetInstances())
{
foreach (ManagementObject mo in moc)
{
if (mo.Properties["UniqueId"] != null && mo.Properties["UniqueId"].Value != null)
{
// only return cpuInfo from first CPU
Trace.WriteLine("CPU ID = " + mo.Properties["UniqueId"].Value.ToString());
_cpuID = mo.Properties["UniqueId"].Value.ToString();
}
mo.Dispose();
}
}
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
Trace.TraceWarning("Failed to read CPUID\r\n" + ex.Message);
}
}

MAC Adress of first card

    private static void FecthMACAddressInternal()
{
try
{
using (ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (ManagementObjectCollection moc = mc.GetInstances())
{
if (moc != null)
{
foreach (ManagementObject mo in moc)
{
Trace.WriteLine(mo["Index"] + " Mac " + mo["Caption"] + " : " + mo["MacAddress"] + " Enabled " + (bool)mo["IPEnabled"]);
if (string.IsNullOrEmpty(_macAdderss)) // only return MAC Address from first card
{
if ( mo["MacAddress"] != null && mo["IPEnabled"] != null && (bool)mo["IPEnabled"] == true)
{
_macAdderss = mo["MacAddress"].ToString();
}
}
mo.Dispose();
}
}
}
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
Trace.TraceWarning("Failed to read DiskID\r\n" + ex.Message);
}
if (_macAdderss != null)
_macAdderss = _macAdderss.Replace(":", "");
}

Drive Serial Number

    /// <summary>
/// return Volume Serial Number from hard drive
/// </summary>
/// <param name="strDriveLetter">[optional] Drive letter</param>
/// <returns>[string] VolumeSerialNumber</returns>
public static string GetVolumeSerial(char driveLetter)
{
try
{
using (ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"" + driveLetter + ":\""))
{
if (disk == null)
return null;
disk.Get();
object diskObj = disk["VolumeSerialNumber"];
if (diskObj != null)
return diskObj.ToString();
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
Trace.TraceWarning("Failed to read DiskID\r\n" + ex.Message);
}

try
{
uint serialNum, serialNumLength, flags;
StringBuilder volumename = new StringBuilder(256);
StringBuilder fstype = new StringBuilder(256);

bool ok = GetVolumeInformation(driveLetter.ToString() + ":\\", volumename, (uint)volumename.Capacity - 1, out serialNum, out serialNumLength, out flags, fstype, (uint)fstype.Capacity - 1);
if (ok)
{
return string.Format("{0:X4}{1:X4}", serialNum >> 16, serialNum & 0xFFFF);
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex2)
{
Trace.TraceWarning("Failed to read DiskID\r\n" + ex2.Message);
}

return null;
}

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern bool GetVolumeInformation(string Volume, StringBuilder VolumeName, uint VolumeNameSize, out uint SerialNumber, out uint SerialNumberLength, out uint flags, StringBuilder fs, uint fs_size);


Related Topics



Leave a reply



Submit