2010-03-17 11 views
17

Mi piacerebbe ottenere un ID univoco su un computer con Python su Windows e Linux. Potrebbe essere l'ID della CPU, la scheda madre seriale, ... o qualsiasi altra cosa.Ottieni un ID computer univoco in Python su windows e linux

Ho esaminato diversi moduli (pycpuid, psi, ...) senza fortuna.

Qualche idea su come farlo?

+0

Che cosa avete bisogno di questo _for_? – Kimvais

+0

Ho bisogno di questo per fare un sistema di licenza per computer per il mio software. Voglio che la licenza sia unica per ogni computer. Se l'utente installa il software su un altro computer e lo * unlocker * su questo computer, non dovrebbe essere in grado di avviare il software. – darkpotpot

+0

correlati http://stackoverflow.com/questions/4193514/get-hard-disk-serial-number-using-python-on-linux e http://stackoverflow.com/questions/227222/how-can-you- extract-hardware-id-using-python – pmav99

risposta

0

ne dite di usare l'indirizzo MAC ID univoco?

La discussione qui Obtain MAC Address from Devices using Python mostra come ottenere l'indirizzo MAC

+3

Questo è quello che volevo fare inizialmente ma dopo diversi test su diversi computer, ho scoperto che a volte ci sono diversi indirizzi mac su un singolo computer. Ad esempio, uno dei miei computer * test * aveva un server VPN e una scheda di rete. E voglio essere sicuro di usare l'indirizzo MAC della scheda di rete, non la VPN (o altre cose) – darkpotpot

+1

Poiché si desidera ottenere solo un ID univoco per il computer. Supponiamo che la configurazione hardware/software del computer non venga cambiata di frequente. In questo modo è possibile ottenere l'indirizzo MAC per TUTTI gli adattatori di rete e unirli per creare un ID. Questo suono è adatto alle tue esigenze? –

+0

Sì, dovrebbe funzionare. Penso che lo farò finché non troverò un modo migliore. – darkpotpot

2
+5

Questo modulo fornisce univocità su spazio e tempo, come GUID. Non penso che questo sia ciò che vuole. Vuole un modo per identificare un computer in modo univoco (ad esempio per scopi di licenza) ma coerente nel tempo ... – David

+3

Questo è esattamente ciò che vuole, tuttavia il modulo python non fa ciò che vuole: dovrebbe leggere l'UUID dal BIOS , su linux 'dmidecode | grep UUID' può fare il trucco – Kimvais

+4

Il modulo uuid fornisce un modo semplice per ottenere un indirizzo MAC attraverso [uuid.getnode()] (https://docs.python.org/2/library/ uuid.html # uuid.getnode). I documenti dicono "se ci sono più interfacce di rete, ognuna di esse può essere restituita". Nel mio breve test quando ci sono multipli sembra che restituisca sempre lo stesso almeno. – foz

4

non credo che ci sia un affidabile, cross platform, modo per fare questo. Conosco un dispositivo di rete che cambia il suo indirizzo MAC come una forma di segnalazione di errori hardware e ci sono altri milioni di modi in cui questo potrebbe fallire.

L'unica soluzione affidabile è che l'applicazione assegni una chiave univoca a ciascuna macchina. Sì, può essere falsificato, ma non devi preoccupartene completamente. Se sei preoccupato di spoofing, puoi applicare una sorta di euristica (come una modifica nell'indirizzo mac) per provare a determinare se la chiave è stata spostata.

AGGIORNAMENTO: È possibile utilizzare bacterial fingerprinting.

+1

Questo riferimento alle impronte batteriche non è una risposta utile alla domanda, e non penso nemmeno che sia uno scherzo divertente. – steveha

+1

Ho una risatina sensibile. –

12

Sembra che non ci sia un modo diretto "python" per farlo. Sull'hardware del PC moderno, di solito c'è un UUID memorizzato nel BIOS - su Linux esiste una utility da riga di comando dmidecode che può leggerlo; ad esempio dal desktop:

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 

Il problema con gli indirizzi MAC è che di solito si può facilmente modificarli a livello di codice (almeno se si esegue il sistema operativo in una VM)

In Windows, è possibile utilizzare questo C API

+4

Si noti che sono necessari i privilegi di root per leggere i dati DMI su Linux. Inoltre, lo stesso numero può essere trovato in/sys/class/dmi/id/product_uuid. – Juliano

+3

Il problema è che non ho (e non voglio usare) i privilegi di root nella mia applicazione. – darkpotpot

+0

Devi essere root per leggere l'UUID, ma puoi leggere il resto senza essere root. Tutto il resto delle cose non privilegiate è concatenato in/sys/class/dmi/id/modalias. Potresti fare hash. Combina con un hash dei mac e l'output dell'istruzione cpuid e hai una buona impronta digitale di sistema. –

10

per Windows è necessario dmidecode per Windows (link):

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

per Linux (non root):

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

Oppure, se non si desidera utilizzare sottoprocesso, (E 'lento) usare ctypes. Questo è per 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_ 

È possibile utilizzare questo tipo:

get_uuid = HardwareUuid() 
print get_uuid() 
5

Invoke uno di questi nella shell o attraverso un tubo in Python per ottenere il numero di serie dell'hardware di macchine Apple con OS X> = 10.5:

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

o

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

BTW: Gli indirizzi MAC non sono una buona idea: ci possono essere> 1 schede di rete in una macchina e gli indirizzi MAC possono essere spoofed.

-2

Divertente! Ma uuid.getnode restituisce lo stesso valore di 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

Questo dovrebbe funzionare su Windows:

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