Получить уникальный идентификатор компьютера в Python для Windows и Linux - PullRequest
26 голосов
/ 17 марта 2010

Я бы хотел получить уникальный идентификатор для компьютера с Python в Windows и Linux. Это может быть идентификатор процессора, серийный номер материнской платы ... или что-то еще.

Я посмотрел на несколько модулей (pycpuid, psi, ...) без удачи.

Есть идеи, как это сделать?

Ответы [ 11 ]

14 голосов
/ 17 марта 2010

Кажется, что нет прямого "питона" способа сделать это. На современном оборудовании ПК в 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

Проблема с MAC-адресами состоит в том, что обычно вы можете легко изменять их программно (по крайней мере, если вы запускаете ОС в ВМ)

В Windows вы можете использовать этот C API

11 голосов
/ 30 июня 2010

для Windows вам нужно DmiDecode для Windows ( ссылка ):

subprocess.Popen('dmidecode.exe -s system-uuid'.split())

для Linux (не root):

subprocess.Popen('hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.uuid'.split())
6 голосов
/ 07 октября 2010

Или, если вы не хотите использовать подпроцесс, (это медленно) используйте 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_

Вы можете использовать это как:

get_uuid = HardwareUuid()
print get_uuid()
5 голосов
/ 26 июля 2018

для python3.6 и windows необходимо использовать декодирование

>>> import subprocess
... current_machine_id = subprocess.check_output('wmic csproduct get uuid').decode().split('\n')[1].strip()
... print(current_machine_id)
5 голосов
/ 12 мая 2013

Вызовите один из них в оболочке или через канал в Python, чтобы получить серийный номер оборудования компьютеров Apple, работающих под управлением OS X> = 10.5:

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

или

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

Кстати: MAC-адреса не очень хорошая идея: в машине может быть> 1 сетевая карта, а MAC-адреса могут быть поддельными .

5 голосов
/ 17 марта 2010

Я не думаю, что есть надежный кроссплатформенный способ сделать это. Мне известно об одном сетевом устройстве, которое меняет свой MAC-адрес как форму сообщения об аппаратных ошибках, и существует миллион других способов, с помощью которых это может произойти.

Единственное надежное решение для вашего приложения - назначить уникальный ключ для каждой машины. Да, это может быть подделано, но вам не нужно беспокоиться о том, что он полностью сломается. Если вас беспокоит подмена, вы можете применить эвристику (например, изменение mac-адреса), чтобы попытаться определить, была ли перемещена клавиша.

ОБНОВЛЕНИЕ: Вы можете использовать бактериальная дактилоскопия .

4 голосов
/ 10 января 2017

Забавно! Но 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')
1 голос
/ 14 июля 2017

Это должно работать на Windows:

import subprocess
current_machine_id = subprocess.check_output('wmic csproduct get uuid').split('\n')[1].strip()
1 голос
/ 20 октября 2011

Я нашел что-то еще, что я использую. Mac-адрес для Linux, MachineGuid для Windows, а также есть что-то для Mac.

Подробнее здесь: http://www.serialsense.com/blog/2011/02/generating-unique-machine-ids/

...