On Windows, we generate a PC-specific unique key used to tie a license to a PC. It's a C++ app using wxWidgets, which is theoretically cross-platform compatible but not been maintained on the Mac side. We use some Win32-specific code for generating a key... how might I do something comparable on the Mac?
Generate machine-specific key for Mac
958 Views Asked by Mr. Boy AtThere are 3 best solutions below

You could just call system_profiler
and look for "Serial Number"
/usr/sbin/system_profiler | grep "Serial Number (system)"
There might well be a programmatic way to get the same information, but I don't know it offhand.

Looking more into whitelionV and blahdiblah's asnwers, I found this useful page:
Accessing the system serial number programmatically
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
// Returns the serial number as a CFString.
// It is the caller's responsibility to release the returned CFString when done with it.
void CopySerialNumber(CFStringRef *serialNumber)
{
if (serialNumber != NULL) {
*serialNumber = NULL;
io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching("IOPlatformExpertDevice"));
if (platformExpert) {
CFTypeRef serialNumberAsCFString =
IORegistryEntryCreateCFProperty(platformExpert,
CFSTR(kIOPlatformSerialNumberKey),
kCFAllocatorDefault, 0);
if (serialNumberAsCFString) {
*serialNumber = serialNumberAsCFString;
}
IOObjectRelease(platformExpert);
}
}
}
Accessing the built-in MAC address programmatically
#include <stdio.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/network/IOEthernetController.h>
static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices);
static kern_return_t GetMACAddress(io_iterator_t intfIterator, UInt8 *MACAddress, UInt8 bufferSize);
static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices)
{
kern_return_t kernResult;
CFMutableDictionaryRef matchingDict;
CFMutableDictionaryRef propertyMatchDict;
matchingDict = IOServiceMatching(kIOEthernetInterfaceClass);
if (NULL == matchingDict) {
printf("IOServiceMatching returned a NULL dictionary.\n");
}
else {
propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (NULL == propertyMatchDict) {
printf("CFDictionaryCreateMutable returned a NULL dictionary.\n");
}
else {
CFDictionarySetValue(matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
CFRelease(propertyMatchDict);
}
}
kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, matchingServices);
if (KERN_SUCCESS != kernResult) {
printf("IOServiceGetMatchingServices returned 0x%08x\n", kernResult);
}
return kernResult;
}
static kern_return_t GetMACAddress(io_iterator_t intfIterator, UInt8 *MACAddress, UInt8 bufferSize)
{
io_object_t intfService;
io_object_t controllerService;
kern_return_t kernResult = KERN_FAILURE;
if (bufferSize < kIOEthernetAddressSize) {
return kernResult;
}
bzero(MACAddress, bufferSize);
while ((intfService = IOIteratorNext(intfIterator)))
{
CFTypeRef MACAddressAsCFData;
kernResult = IORegistryEntryGetParentEntry(intfService,
kIOServicePlane,
&controllerService);
if (KERN_SUCCESS != kernResult) {
printf("IORegistryEntryGetParentEntry returned 0x%08x\n", kernResult);
}
else {
MACAddressAsCFData = IORegistryEntryCreateCFProperty(controllerService,
CFSTR(kIOMACAddress),
kCFAllocatorDefault,
0);
if (MACAddressAsCFData) {
CFShow(MACAddressAsCFData); // for display purposes only; output goes to stderr
CFDataGetBytes(MACAddressAsCFData, CFRangeMake(0, kIOEthernetAddressSize), MACAddress);
CFRelease(MACAddressAsCFData);
}
(void) IOObjectRelease(controllerService);
}
(void) IOObjectRelease(intfService);
}
return kernResult;
}
int main(int argc, char *argv[])
{
kern_return_t kernResult = KERN_SUCCESS;
io_iterator_t intfIterator;
UInt8 MACAddress[kIOEthernetAddressSize];
kernResult = FindEthernetInterfaces(&intfIterator);
if (KERN_SUCCESS != kernResult) {
printf("FindEthernetInterfaces returned 0x%08x\n", kernResult);
}
else {
kernResult = GetMACAddress(intfIterator, MACAddress, sizeof(MACAddress));
if (KERN_SUCCESS != kernResult) {
printf("GetMACAddress returned 0x%08x\n", kernResult);
}
else {
printf("This system's built-in MAC address is %02x:%02x:%02x:%02x:%02x:%02x.\n",
MACAddress[0], MACAddress[1], MACAddress[2], MACAddress[3], MACAddress[4], MACAddress[5]);
}
}
(void) IOObjectRelease(intfIterator); // Release the iterator.
return kernResult;
}
While MAC is on the face of it probably preferable as being more predictable, they warn that:
Netbooting introduces a wrinkle with systems with multiple built-in Ethernet ports. The primary Ethernet port on these systems is the one that is connected to the NetBoot server. This means that a search for the primary port may return either of the built-in MAC addresses depending on which port was used for netbooting. Note that "built-in" does not include Ethernet ports that reside on an expansion card.
It concerns me this might mean you don't always get the same value back?
To uniquely identify any machine you could try to use the MAC address. The process, although not trivial, its quite simple. There are a lot of cross platform open source libraries.
In fact you could try this Apple dev example