Get a unique computer ID in Python on windows and linux
我想获得Windows和Linux上使用Python的计算机唯一的ID。 可能是CPU ID,主板序列号或其他。
我看了几个运气不好的模块(pycpuid,psi,...)。
关于如何做到这一点的任何想法?
似乎没有直接的" python"方式可以做到这一点。在现代PC硬件上,通常在BIOS中存储有一个UUID-在Linux上,有一个命令行实用程序
1 2 3 4 5 6 7 8 9 | System Information Manufacturer: Dell Inc. Product Name: OptiPlex 755 Version: Not Specified Serial Number: 5Y8YF3J UUID: 44454C4C-5900-1038-8059-B5C04F46334A Wake-up Type: Power Switch SKU Number: Not Specified Family: Not Specified |
MAC地址的问题在于,通常您可以轻松地以编程方式更改它们(至少如果在VM中运行操作系统)
在Windows上,您可以使用此C API
对于Windows,您需要Windows的DmiDecode(链接):
1 | subprocess.Popen('dmidecode.exe -s system-uuid'.split()) |
对于Linux(非root用户):
1 | subprocess.Popen('hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.uuid'.split()) |
对于python3.6和Windows
必须使用解码
1 2 3 4 | >>> import subprocess ... current_machine_id = subprocess.check_output('wmic csproduct get uuid').decode().split('\ ')[1].strip() ... print(current_machine_id) |
滑稽!
但是uuid.getnode返回的值与dmidecode.exe相同。
1 2 3 4 5 6 7 8 | subprocess.Popen('dmidecode.exe -s system-uuid'.split()) 00000000-0000-0000-0000-001FD088565A import uuid uuid.UUID(int=uuid.getnode()) UUID('00000000-0000-0000-0000-001fd088565a') |
在外壳中或通过Python中的管道调用其中之一,以获取运行OS X> = 10.5的Apple计算机的硬件序列号:
要么
顺便说一句:MAC地址不是一个好主意:一台机器中可以有1个以上的网卡,并且MAC地址可以被欺骗。
或者,如果您不想使用子进程,(很慢)请使用ctypes。这适用于Linux非root用户。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import ctypes from ctypes.util import find_library from ctypes import Structure class DBusError(Structure): _fields_ = [("name", ctypes.c_char_p), ("message", ctypes.c_char_p), ("dummy1", ctypes.c_int), ("dummy2", ctypes.c_int), ("dummy3", ctypes.c_int), ("dummy4", ctypes.c_int), ("dummy5", ctypes.c_int), ("padding1", ctypes.c_void_p),] class HardwareUuid(object): def __init__(self, dbus_error=DBusError): self._hal = ctypes.cdll.LoadLibrary(find_library('hal')) self._ctx = self._hal.libhal_ctx_new() self._dbus_error = dbus_error() self._hal.dbus_error_init(ctypes.byref(self._dbus_error)) self._conn = self._hal.dbus_bus_get(ctypes.c_int(1), ctypes.byref(self._dbus_error)) self._hal.libhal_ctx_set_dbus_connection(self._ctx, self._conn) self._uuid_ = None def __call__(self): return self._uuid @property def _uuid(self): if not self._uuid_: udi = ctypes.c_char_p("/org/freedesktop/Hal/devices/computer") key = ctypes.c_char_p("system.hardware.uuid") self._hal.libhal_device_get_property_string.restype = \\ ctypes.c_char_p self._uuid_ = self._hal.libhal_device_get_property_string( self._ctx, udi, key, self._dbus_error) return self._uuid_ |
您可以这样使用:
1 2 | get_uuid = HardwareUuid() print get_uuid() |
我认为没有可靠的跨平台方法可以做到这一点。我知道有一种网络设备会更改其MAC地址,这是一种硬件错误报告的形式,还有百万种其他方法可能会失败。
唯一可靠的解决方案是为您的应用程序为每台计算机分配唯一的密钥。是的,它可以被欺骗,但是您不必担心它会完全损坏。如果您担心欺骗,则可以应用某种启发式方法(例如更改mac地址)来尝试确定密钥是否已移动。
更新:您可以使用细菌指纹识别。
在Windows上应该可以使用:
1 2 3 | import subprocess current_machine_id = subprocess.check_output('wmic csproduct get uuid').split('\ ')[1].strip() |
UUID-通用唯一标识符
Python uuid模块
[RFC 4122]通用唯一标识符(UUID)URN命名空间
2019年答案(对于Windows):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | from typing import Optional import re import subprocess import uuid def get_windows_uuid() -> Optional[uuid.UUID]: try: # Ask Windows for the device's permanent UUID. Throws if command missing/fails. txt = subprocess.check_output("wmic csproduct get uuid").decode() # Attempt to extract the UUID from the command's result. match = re.search(r"\\bUUID\\b[\\s\ \ ]+([^\\s\ \ ]+)", txt) if match is not None: txt = match.group(1) if txt is not None: # Remove the surrounding whitespace (newlines, space, etc) # and useless dashes etc, by only keeping hex (0-9 A-F) chars. txt = re.sub(r"[^0-9A-Fa-f]+","", txt) # Ensure we have exactly 32 characters (16 bytes). if len(txt) == 32: return uuid.UUID(txt) except: pass # Silence subprocess exception. return None print(get_windows_uuid()) |
使用Windows API获取计算机的永久UUID,然后处理字符串以确保它是有效的UUID,最后返回一个Python对象(https://docs.python.org/3/library/uuid.html),这为您提供了方便使用数据的方式(例如128位整数,十六进制字符串等)。
祝好运!
PS:可以用直接为Win32_ComputerSystemProduct API(这是
我发现了我正在使用的其他东西。 linux的Mac地址,windows的MachineGuid,还有mac的东西。
详情请见:
http://www.serialsense.com/blog/2011/02/generating-unique-machine-ids/
如何使用MAC地址作为唯一ID?
此处的讨论使用Python从设备获取MAC地址显示了如何获取MAC地址