2010-03-17 40 views
17

Me gustaría obtener una ID única para una computadora con Python en Windows y Linux. Podría ser la ID de la CPU, la serie de la placa base ... o cualquier otra cosa.Obtenga una ID de computadora única en Python en Windows y Linux

Miré varios módulos (pycpuid, psi, ...) sin suerte.

¿Alguna idea de cómo hacer eso?

+0

¿Qué necesita este _for_? – Kimvais

+0

Necesito esto para hacer un sistema de licencia por computadora para mi software. Quiero que la licencia sea única para cada computadora. Si el usuario instala el software en otra computadora y el * unlocker * en esta computadora también, no debería poder iniciar el software. – darkpotpot

+0

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

Respuesta

0

¿Cómo sobre el uso de la dirección MAC ID tan único?

La discusión aquí Obtain MAC Address from Devices using Python muestra cómo obtener la dirección MAC

+3

Eso es lo que quería hacer al principio, pero después de varias pruebas en varias computadoras, descubrí que a veces hay varias direcciones MAC en una sola computadora. Por ejemplo, una computadora de mi * prueba * tenía un servidor VPN y una tarjeta de red. Y quiero asegurarme de usar la dirección MAC de la tarjeta de red, no la VPN (u otras cosas) – darkpotpot

+1

Ya que solo desea obtener una identificación única para la computadora. Supongamos que la configuración de hardware/software de la computadora no se cambia con frecuencia. De esta forma, puede obtener la dirección MAC para TODOS los adaptadores de red y unirlos para crear una identificación. ¿Funciona esto para tus necesidades? –

+0

Sí, debería funcionar. Creo que lo haré hasta que encuentre una mejor manera. – darkpotpot

2
+5

Este módulo proporciona exclusividad en el espacio y el tiempo, como los GUID. No creo que esto sea lo que él quiere. Quiere una forma única de identificar una computadora (para fines de licencia, por ejemplo) pero consistente en el tiempo ... – David

+3

Esto es exactamente lo que quiere, sin embargo, el módulo de python no hace lo que quiere, debe leer el UUID de la BIOS , en linux 'dmidecode | grep UUID' puede hacer el truco – Kimvais

+4

El módulo uuid proporciona una manera fácil de obtener una dirección MAC a través de [uuid.getnode()] (https://docs.python.org/2/library/ uuid.html # uuid.getnode). Los documentos dicen "si hay múltiples interfaces de red, cualquiera de ellas puede ser devuelto". En mi propia prueba breve cuando hay múltiples, parece devolver consistentemente la misma al menos. – foz

4

no creo que hay un fiable, multiplataforma, forma de hacerlo. Sé de un dispositivo de red que cambia su dirección MAC como una forma de informe de errores de hardware, y hay un millón de otras formas en que esto podría fallar.

La única solución confiable es que su aplicación asigne una clave única a cada máquina. Sí, puede ser falso, pero no tiene que preocuparse de que se rompa por completo. Si le preocupa la suplantación, puede aplicar algún tipo de heurística (como un cambio en la dirección MAC) para intentar determinar si la clave se ha movido.

ACTUALIZACIÓN: Puede usar bacterial fingerprinting.

+1

Esa referencia bacteriana de huellas dactilares no es una respuesta útil a la pregunta, y tampoco creo que sea una broma graciosa. – steveha

+1

Tengo una sonrisa sensata. –

12

Parece que no hay una forma directa de "pitón" de hacer esto. En el hardware de PC moderno, generalmente hay un UUID almacenado en el BIOS; en Linux hay una utilidad de línea de comandos dmidecode que puede leer esto; ejemplo de mi escritorio:

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 

El problema con las direcciones MAC es que por lo general se puede fácilmente cambiar mediante programación (por lo menos si se ejecuta el sistema operativo en una máquina virtual)

En Windows, puede utilizar este C API

+4

Tenga en cuenta que necesita privilegios de administrador para leer los datos de DMI en Linux. Además, el mismo número se puede encontrar en/sys/class/dmi/id/product_uuid. – Juliano

+3

El problema es que no tengo (y no quiero usar) privilegios de administrador en mi aplicación. – darkpotpot

+0

Debe ser el usuario root para leer el UUID, pero puede leer el resto sin ser root. Todo el resto de las cosas no privilegiadas se concatena en/sys/class/dmi/id/modalias. Podrías hash eso. Combine con un hash de los Mac y la salida de la instrucción cpuid y tendrá una huella digital de sistema bastante buena. –

10

para Windows necesita dmidecode para Windows (link):

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

para Linux (no root):

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

O si no desea utilizar subproceso, (Es lento) utilizan ctypes. Esto es para Linux no 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_ 

Usted puede utilizar esto como:

get_uuid = HardwareUuid() 
print get_uuid() 
5

Invoque uno de estos en la cubierta o por medio de una tubería en Python para obtener el número de serie del hardware de las máquinas de 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: las direcciones MAC no son una buena idea: puede haber> 1 tarjeta de red en una máquina, y las direcciones MAC pueden ser spoofed.

-2

¡Divertido! Pero uuid.getnode devuelve el mismo valor 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') 
1

Esto debería funcionar en Windows:

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