在Windows和Linux上使用Python获取唯一的计算机ID

dar*_*pot 29 python hardware

我想获得一个在Windows和Linux上使用Python的计算机独有的ID.它可能是CPU ID,主板串口,......或其他任何东西.

没有运气,我看了几个模块(pycpuid,psi,...).

有关如何做到这一点的任何想法?

Kim*_*ais 14

似乎没有直接的"python"方式来做到这一点.在现代PC硬件上,通常存在一个存储在BIOS中的UUID - 在Linux上有一个命令行实用程序dmidecode可以读取它; 我的桌面示例:

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
Run Code Online (Sandbox Code Playgroud)

MAC地址的问题通常是您可以通过编程方式轻松更改它们(至少如果您在VM中运行操作系统)

在Windows上,您可以使用此C API

  • 请注意,您需要root权限才能读取Linux上的DMI数据.此外,可以在/ sys/class/dmi/id/product_uuid中找到相同的编号. (5认同)
  • 问题是我的应用程序中没有(并且不想使用)root权限. (3认同)

naz*_*zca 11

对于Windows,您需要DmiDecode for Windows(链接):

subprocess.Popen('dmidecode.exe -s system-uuid'.split())
Run Code Online (Sandbox Code Playgroud)

对于Linux(非root):

subprocess.Popen('hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.uuid'.split())
Run Code Online (Sandbox Code Playgroud)


Ale*_*kin 10

对于python3.6和Windows必须使用解码

>>> import subprocess
... current_machine_id = subprocess.check_output('wmic csproduct get uuid').decode().split('\n')[1].strip()
... print(current_machine_id)
Run Code Online (Sandbox Code Playgroud)


小智 6

或者如果你不想使用子进程,(它很慢)使用ctypes.这适用于Linux非root用户.

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_
Run Code Online (Sandbox Code Playgroud)

你可以这样使用:

get_uuid = HardwareUuid()
print get_uuid()
Run Code Online (Sandbox Code Playgroud)

  • 我收到错误:`AttributeError: function 'libhal_ctx_new' not found` 帮助! (3认同)

Ale*_*kin 6

滑稽!但是uuid.getnode返回的值与dmidecode.exe相同。

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')
Run Code Online (Sandbox Code Playgroud)

  • `uuid.getnode()` 足以满足我的目的 (2认同)

mik*_*obi 5

我不认为有一种可靠的,跨平台的方式来做到这一点.我知道有一个网络设备将其MAC地址更改为硬件错误报告的形式,并且还有其他一百万种方法可能会失败.

唯一可靠的解决方案是让您的应用程序为每台机器分配一个唯一的密钥.是的,它可以被欺骗,但你不必担心它会彻底破坏.如果您担心欺骗,可以应用某种启发式方法(如更改mac地址)来尝试确定密钥是否已被移动.

更新:您可以使用细菌指纹识别.

  • 我有一个明智的笑声. (4认同)
  • 那个细菌指纹参考不是这个问题的有用答案,我也不认为这是一个有趣的笑话。 (2认同)

Lar*_*dua 5

在shell中或通过Python中的管道调用其中一个以获取运行OS X> = 10.5的Apple机器的硬件序列号:

/usr/sbin/system_profiler SPHardwareDataType | fgrep 'Serial' | awk '{print $NF}'

要么

ioreg -l | awk '/IOPlatformSerialNumber/ { print $4 }' | sed s/\"//g

BTW:MAC地址不是一个好主意:一台机器中可能有> 1个网卡,而MAC地址可能是欺骗性的.


Sou*_*vik 5

这应该适用于 Windows:

import subprocess
current_machine_id = subprocess.check_output('wmic csproduct get uuid').split('\n')[1].strip()
Run Code Online (Sandbox Code Playgroud)


Jay*_*Zhu 1

使用 MAC 地址作为唯一 ID 怎么样?

这里的讨论使用Python从设备获取MAC地址展示了如何获取MAC地址

  • -1 MAC 地址很容易更改,并且作为唯一标识符并不可靠。但公平地说,有许多商业软件产品可以做到这一点。;) (22认同)
  • 我一开始也是这么想的,但是在多台电脑上进行多次测试后,我发现有时一台电脑上会有多个mac地址。例如,我的一台“测试”计算机有一个 VPN 服务器和一个网卡。我想确保使用网卡MAC地址,而不是VPN(或其他东西) (4认同)