6

How to find the Mac OSX serial number.

Sometimes it is required to get serial number of a mac, and you validate on that.

I needed the same, few years back, when I developed a plugin for OsiriX. I was asked to release it in such a way, only few systems can use that plugin.

If we get any better solution than this, that will be quite helpful for all of us.

jww
  • 97,681
  • 90
  • 411
  • 885
Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140

3 Answers3

19

The following code is mainly copied from Technical Note TN1103, with small modifications to return an NSString and to make it compile with ARC:

#include <IOKit/IOKitLib.h>

- (NSString *)getSerialNumber
{
    NSString *serial = nil;
    io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
                                     IOServiceMatching("IOPlatformExpertDevice"));
    if (platformExpert) {
        CFTypeRef serialNumberAsCFString =
        IORegistryEntryCreateCFProperty(platformExpert,
                                        CFSTR(kIOPlatformSerialNumberKey),
                                        kCFAllocatorDefault, 0);
        if (serialNumberAsCFString) {
            serial = CFBridgingRelease(serialNumberAsCFString);
        }

        IOObjectRelease(platformExpert);
    }
    return serial;
}

You have to add the IOKit.framework to your build settings.

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • After writing this answer I did a SO search for `kIOPlatformSerialNumberKey` which showed that there are already many answers containing the code from TN1103. – Martin R Mar 16 '13 at 16:10
  • Yes, I knew :) I only wanted to check if my way was good or not. And if you, Arpad and duskwuff says.... I got my point :) – Anoop Vaidya Mar 16 '13 at 16:27
  • This is also useful for encryption of registration keys as part of a password. – Volomike Jan 16 '16 at 21:13
9

This is the Swift version of the solution:

var serialNumber: String? {
  let platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice") )

  guard platformExpert > 0 else {
    return nil
  }

  guard let serialNumber = (IORegistryEntryCreateCFProperty(platformExpert, kIOPlatformSerialNumberKey as CFString, kCFAllocatorDefault, 0).takeUnretainedValue() as? String) else {
    return nil
  }


  IOObjectRelease(platformExpert)

  return serialNumber
}
leogdion
  • 2,332
  • 1
  • 19
  • 21
gbdavid
  • 1,639
  • 18
  • 40
3

This is a C++ version based on the TN1103 that Martin mention above.

C++ example:

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

std::string example_class::getSerialNumber()
{
    CFStringRef serial;
    char buffer[64] = {0};
    std::string seriaNumber("");
    io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
                                                          IOServiceMatching("IOPlatformExpertDevice"));
    if (platformExpert)
    {
        CFTypeRef serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert,
                                                                       CFSTR(kIOPlatformSerialNumberKey),
                                                                       kCFAllocatorDefault, 0);
        if (serialNumberAsCFString) {
            serial = (CFStringRef)serialNumberAsCFString;
        }
        if (CFStringGetCString(serial, buffer, 64, kCFStringEncodingUTF8)) {
            seriaNumber = buffer;
        }

        IOObjectRelease(platformExpert);
    }
    return seriaNumber;
}
davidj
  • 331
  • 2
  • 5