【发布时间】:2011-08-15 15:07:59
【问题描述】:
在 iOS 上,为当前设备检索唯一且匿名的字符串相当容易 ([[UIDevice currentDevice] uniqueIdentifier])。而且我在这里指的不是计算机的序列号,而是由不同组件特征/sn 组成的哈希值,例如 iOS udid。
Mac OS X 端有没有类似的东西,如何访问?
【问题讨论】:
在 iOS 上,为当前设备检索唯一且匿名的字符串相当容易 ([[UIDevice currentDevice] uniqueIdentifier])。而且我在这里指的不是计算机的序列号,而是由不同组件特征/sn 组成的哈希值,例如 iOS udid。
Mac OS X 端有没有类似的东西,如何访问?
【问题讨论】:
#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);
}
}
}
【讨论】:
不要使用计算机序列号——它仅在初始工厂安装时有效。如果您的主板在任何时候被更换,您将不再拥有序列号,因为出厂时并未设置将序列号作为整机的一部分。
相反,您应该使用硬件以太网 ID,特别是设备“en0”的 ID。以下(非常相似的)代码将为您提供:
//
// MACAddress.m
// XPPublisherCore
//
// Created by Jim Dovey on 11-01-30.
// Copyright 2011 XPlatform Inc. All rights reserved.
//
#import "MACAddress.h"
#import <IOKit/IOKitLib.h>
NSData * GetMACAddress( void )
{
kern_return_t kr = KERN_SUCCESS;
CFMutableDictionaryRef matching = NULL;
io_iterator_t iterator = IO_OBJECT_NULL;
io_object_t service = IO_OBJECT_NULL;
CFDataRef result = NULL;
matching = IOBSDNameMatching( kIOMasterPortDefault, 0, "en0" );
if ( matching == NULL )
{
fprintf( stderr, "IOBSDNameMatching() returned empty dictionary\n" );
return ( NULL );
}
kr = IOServiceGetMatchingServices( kIOMasterPortDefault, matching, &iterator );
if ( kr != KERN_SUCCESS )
{
fprintf( stderr, "IOServiceGetMatchingServices() returned %d\n", kr );
return ( NULL );
}
while ( (service = IOIteratorNext(iterator)) != IO_OBJECT_NULL )
{
io_object_t parent = IO_OBJECT_NULL;
kr = IORegistryEntryGetParentEntry( service, kIOServicePlane, &parent );
if ( kr == KERN_SUCCESS )
{
if ( result != NULL )
CFRelease( result );
result = IORegistryEntryCreateCFProperty( parent, CFSTR("IOMACAddress"), kCFAllocatorDefault, 0 );
IOObjectRelease( parent );
}
else
{
fprintf( stderr, "IORegistryGetParentEntry returned %d\n", kr );
}
IOObjectRelease( service );
}
return ( (NSData *)NSMakeCollectable(result) );
}
NSString * GetMACAddressDisplayString( void )
{
NSData * macData = GetMACAddress();
if ( [macData length] == 0 )
return ( nil );
const UInt8 *bytes = [macData bytes];
NSMutableString * result = [NSMutableString string];
for ( NSUInteger i = 0; i < [macData length]; i++ )
{
if ( [result length] != 0 )
[result appendFormat: @":%02hhx", bytes[i]];
else
[result appendFormat: @"%02hhx", bytes[i]];
}
return ( [[result copy] autorelease] );
}
【讨论】: