ID de hardware único en Mac OS X


El desarrollo de Mac OS X es un animal bastante nuevo para mí, y estoy en el proceso de portar algún software. Para licencias de software y registro necesito ser capaz de generar algún tipo de ID de hardware. No tiene que ser nada sofisticado; dirección MAC Ethernet, disco duro en serie, CPU en serie, algo así.

Lo tengo cubierto en Windows, pero no tengo ni idea en Mac. Cualquier idea de lo que tengo que hacer, o donde puedo ir para obtener información sobre esto sería genial!

Editar:

Para cualquiera que esté interesado en esto, este es el código que terminé usando con la clase QProcess de Qt:

QProcess proc;

QStringList args;
args << "-c" << "ioreg -rd1 -c IOPlatformExpertDevice |  awk '/IOPlatformUUID/ { print $3; }'";
proc.start( "/bin/bash", args );
proc.waitForFinished();

QString uID = proc.readAll();

Nota: Estoy usando C++.

Author: Peter Mortensen, 2009-06-01

8 answers

Pruebe este comando de Terminal:

ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { split($0, line, "\""); printf("%s\n", line[4]); }'

De aquí

Aquí está ese comando envuelto en cacao (que probablemente podría hacerse un poco más limpio):

NSArray * args = [NSArray arrayWithObjects:@"-rd1", @"-c", @"IOPlatformExpertDevice", @"|", @"grep", @"model", nil];
NSTask * task = [NSTask new];
[task setLaunchPath:@"/usr/sbin/ioreg"];
[task setArguments:args];

NSPipe * pipe = [NSPipe new];
[task setStandardOutput:pipe];
[task launch];

NSArray * args2 = [NSArray arrayWithObjects:@"/IOPlatformUUID/ { split($0, line, \"\\\"\"); printf(\"%s\\n\", line[4]); }", nil];
NSTask * task2 = [NSTask new];
[task2 setLaunchPath:@"/usr/bin/awk"];
[task2 setArguments:args2];

NSPipe * pipe2 = [NSPipe new];
[task2 setStandardInput:pipe];
[task2 setStandardOutput:pipe2];
NSFileHandle * fileHandle2 = [pipe2 fileHandleForReading];
[task2 launch];

NSData * data = [fileHandle2 readDataToEndOfFile];
NSString * uuid = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
 14
Author: xyz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-08 07:49:44

Para C / C++:

void get_platform_uuid(char * buf, int bufSize) {
    io_registry_entry_t ioRegistryRoot = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/");
    CFStringRef uuidCf = (CFStringRef) IORegistryEntryCreateCFProperty(ioRegistryRoot, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
    IOObjectRelease(ioRegistryRoot);
    CFStringGetCString(uuidCf, buf, bufSize, kCFStringEncodingMacRoman);
    CFRelease(uuidCf);    
}
 32
Author: yairchu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-02 18:56:51

¿Por qué no probar gethostuuid()? Aquí está la documentación del Manual de Llamadas al Sistema Mac OS X:

NOMBRE:

 gethostuuid -- return a unique identifier for the current machine

SINOPSIS:

 #include <unistd.h>

 int gethostuuid(uuid_t id, const struct timespec *wait);

DESCRIPCIÓN:

La función gethostuuid() devuelve un uuid_t de 16 bytes especificado por id, que identifica de forma única la máquina actual. Tenga en cuenta que los identificadores de hardware que gethostuuid() utiliza para generar el UUID se pueden modificar por sí mismos.

El argumento wait es un puntero a una estructura timespec que especifica el tiempo máximo para esperar el resultado. Establecer los campos tv_sec y tv_nsec a cero significa esperar indefinidamente hasta que se complete.

VALORES DE RETORNO:

La función gethostuuid() devuelve cero en caso de éxito o -1 en caso de error.

ERRORES

La función gethostuuid() falla si:

 [EFAULT]           wait points to memory that is not a valid part of the
                    process address space.

 [EWOULDBLOCK]      The wait timeout expired before the UUID could be
                    obtained.
 7
Author: zhanglin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-02 03:11:41

Esto sería más fácil de responder si nos dijeras qué idioma estás usando. La información se puede obtener sin ningún comando de shell a través del framework SystemConfiguration, y también a través de IOKit si quieres ensuciarte las manos.

- (NSString*) getMACAddress: (BOOL)stripColons {
    NSMutableString         *macAddress         = nil;
    NSArray                 *allInterfaces      = (NSArray*)SCNetworkInterfaceCopyAll();
    NSEnumerator            *interfaceWalker    = [allInterfaces objectEnumerator];
    SCNetworkInterfaceRef   curInterface        = nil;

    while ( curInterface = (SCNetworkInterfaceRef)[interfaceWalker nextObject] ) {
        if ( [(NSString*)SCNetworkInterfaceGetBSDName(curInterface) isEqualToString:@"en0"] ) {
            macAddress = [[(NSString*)SCNetworkInterfaceGetHardwareAddressString(curInterface) mutableCopy] autorelease];

            if ( stripColons == YES ) {
                [macAddress replaceOccurrencesOfString: @":" withString: @"" options: NSLiteralSearch range: NSMakeRange(0, [macAddress length])];
            }

            break;
        }
    }

    return [[macAddress copy] autorelease];
}
 7
Author: Azeem.Butt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-26 15:27:37
/*
g++ mac_uuid.cpp -framework CoreFoundation -lIOKit
*/


#include <iostream>
#include <IOKit/IOKitLib.h>

using namespace std;

void get_platform_uuid(char * buf, int bufSize)
{
   io_registry_entry_t ioRegistryRoot = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/");
   CFStringRef uuidCf = (CFStringRef) IORegistryEntryCreateCFProperty(ioRegistryRoot, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
   IOObjectRelease(ioRegistryRoot);
   CFStringGetCString(uuidCf, buf, bufSize, kCFStringEncodingMacRoman);
   CFRelease(uuidCf);
}

int main()
{
   char buf[512] = "";
   get_platform_uuid(buf, sizeof(buf));
   cout << buf << endl;
}
 5
Author: Nitinkumar Ambekar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-20 14:52:06

Corriendo:

system_profiler | grep 'Serial Number (system)'

En una terminal devuelve lo que probablemente sea un id único. Eso funciona en mi caja 10.5, no estoy seguro de cuál será la cadena correcta en otras versiones de OS X.

 1
Author: kbyrd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-01 03:43:55

Como algunas personas anteriores han insinuado, puede usar un comando de Terminal para obtener un ID de hardware.

Asumo que quieres hacer esto en código, así que echaría un vistazo a la clase NSTask en Cocoa. Básicamente le permite ejecutar comandos de terminal dentro de su aplicación.

Este código es un ejemplo de cómo usar NSTask en Cocoa. Configura el entorno para ejecutar el comando" killall". Le pasa el argumento "Finder".

Es el equivalente de ejecutar "killall Finder" en la línea de comandos, que matará al Finder obviamente.

NSTask *aTask = [[NSTask alloc] init];
NSMutableArray *args = [NSMutableArray array];

[aTask setLaunchPath: @"/usr/bin/killall"];
[args addObject:[@"/Applications/Finder" lastPathComponent]];
[aTask setArguments:args];
[aTask launch];

[aTask release];
 1
Author: Brock Woolf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-17 06:16:20

System Profiler (en Aplicaciones - Utilidades) contiene la mayor parte de este tipo de información. Tiene su número de serie y su dirección mac (sin relación con Mac. Todas las computadoras tienen una dirección mac que es prácticamente única para cada tarjeta de red).

 0
Author: Singletoned,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-03 10:30:52