web-dev-qa-db-fra.com

Obtenez un ID d'ordinateur unique dans Python sur Windows et Linux

J'aimerais obtenir un identifiant unique à un ordinateur avec Python sous Windows et Linux. Il peut s'agir de l'ID du processeur, de la série de la carte mère, ... ou de toute autre chose.

J'ai regardé plusieurs modules (pycpuid, psi, ...) sans chance.

Une idée sur comment faire ça?

32
darkpotpot

Que diriez-vous d'utiliser l'adresse MAC comme identifiant unique?

La discussion ici Obtenir l'adresse MAC à partir de périphériques utilisant Python montre comment obtenir l'adresse MAC

0
Jay Zhu

Il ne semble pas y avoir de méthode "python" directe pour ce faire. Sur le matériel PC moderne, il y a généralement un UUID stocké dans le BIOS - sous Linux il y a un utilitaire de ligne de commande dmidecode qui peut lire ceci; exemple de mon bureau:

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

Le problème avec les adresses MAC est qu'en général, vous pouvez facilement les modifier par programme (au moins si vous exécutez le système d'exploitation dans une machine virtuelle)

Sous Windows, vous pouvez utiliser ceci API C

14
Kimvais

pour Windows, vous avez besoin DmiDecode pour Windows ( link ):

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

pour Linux (non root):

subprocess.Popen('hal-get-property --udi /org/freedesktop/Hal/devices/computer --key system.hardware.uuid'.split())
11
nazca

Pour python3.6 et les fenêtres doivent être utilisées décoder

>>> import subprocess
... current_machine_id = subprocess.check_output('wmic csproduct get uuid').decode().split('\n')[1].strip()
... print(current_machine_id)
9
Alexandr Dragunkin

Ou si vous ne voulez pas utiliser de sous-processus, (c'est lent) utilisez des ctypes. C'est pour Linux non 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_

Vous pouvez utiliser ceci comme:

get_uuid = HardwareUuid()
print get_uuid()
6
Six

Je ne pense pas qu'il existe un moyen fiable et multiplateforme de procéder. Je connais un périphérique réseau qui change son adresse MAC comme une forme de rapport d'erreurs matérielles, et il y a un million d'autres façons dont cela pourrait échouer.

La seule solution fiable est que votre application attribue une clé unique à chaque machine. Oui, il peut être usurpé, mais vous n'avez pas à vous soucier qu'il se casse complètement. Si vous vous inquiétez de l'usurpation d'identité, vous pouvez appliquer une sorte d'heuristique (comme un changement d'adresse mac) pour essayer de déterminer si la clé a été déplacée.

MISE À JOUR: Vous pouvez utiliser empreinte bactérienne .

5
mikerobi

Appelez l'un d'eux dans le Shell ou via un canal dans Python pour obtenir le numéro de série matériel de Apple machines exécutant OS X> = 10.5:

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

ou

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

BTW: Les adresses MAC ne sont pas une bonne idée: il peut y avoir> 1 cartes réseau dans une machine, et les adresses MAC peuvent être surpées .

5
Laryx Decidua

Drôle! Mais id.getnode retourne la même valeur que 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')
5
Alexandr Dragunkin
3
Pratik Deoghare

Cela devrait fonctionner sur les fenêtres:

import subprocess
current_machine_id = subprocess.check_output('wmic csproduct get uuid').split('\n')[1].strip()
1
Souvik

J'ai trouvé autre chose que j'utilise. Adresse Mac pour Linux, MachineGuid pour Windows et il y a aussi quelque chose pour Mac.

Plus de détails ici: http://www.serialsense.com/blog/2011/02/generating-unique-machine-ids/

1
darkpotpot