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?
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
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
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())
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)
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()
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 .
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 .
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')
Cela devrait fonctionner sur les fenêtres:
import subprocess
current_machine_id = subprocess.check_output('wmic csproduct get uuid').split('\n')[1].strip()
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/