Apple解决方案
1、使用CFUUIDCreateString(NULL, CFUUIDCreate(NULL))生成UUID
2、将UUID缓存在本地,sqlite或plist。使用时取出
评价:
坑爹!这种方式每次UUID生成一次都不一样,如果产品被fuck out of device,再装载会导致两次UUID不一致。这个方案明显适用范围狠窄啊亲。于是乎各路妖魔鬼怪开始了各种解决方案。
方案一:(Mac地址+bundle_id)
1、获取本地mac地址和应用bundle_id
2、将mac+bundle_id进行散列运算获得机器+应用的唯一标识
3、只将mac进行散列运算获得机器的唯一标识
评价:
狠好的解决方案,如果没有2B的联通搅局,这个方案可以说完美了,取wifi的mac地址除,非你修机器把wifi换掉。但是亲,中国曾经出过太监版3GS,泥马,这是一种怎样的考量删除了wifi啊。这种拍脑袋的做法就是当局的2B,联通跟着傻B。whatthe fuck!你说还有其他方案不,不要依赖硬件?
方案二:(推送token+bundle_id)
1、应用中增加推送用来获取token
2、获取应用bundle_id
3、根据token+bundle_id进行散列运算
评价:
apple push token保证设备唯一,但必须有网络情况下才能工作,该方法不依赖于设备本身,但依赖于apple push。加上一定的业务逻辑可以解决大部分情景。
方案三:openUUID
我不知道是谁想出来的,而且还有很多博客里都说这个是解决方案,还弄的长篇大论,我实在看不出来这个方案和apple提供的UUID方案有什么不同。这种方案各种无解,删除应用后还是没法解决问题啊亲。
这里以第一种方案做设置 :
根据设备的Mac地址和系统唯一标示符BundleIdentifier获取设备唯一识别符
第一步:获取设备Mac地址,并转化为传统的Mac地址格式;
第二步:进行散列hash处理,即进行MD5信息加密,目的是用户个人隐私数据不能进行明文传播;
第三步:返回设备唯一识别符,保存到服务器端,作为唯一标示符区别注册用户。
具体操作过程为:
1.创建文件
这里创建两个文件,这两个都包括.h和.m 文件,文件名分别为:NSString+MD5sAddition和UIDevice+BundleIdentifier,其创建步骤如果下,找到文件创建模板如图1.1所示:
图1.1
创建该格式的文件,选择NSString格式和UIDevice两种格式,分别创建文件如图1.2所示,创建结束后生成的文件如图1.3所示
图1.2 选中需要的文件格式
图1.3 生成后文件
2.代码编写
文件创建完后,编写代码,首先理清思路,即Mac地址不能明文传递,必须进行加密处理,故编写加密代码,加密算法主要是使用MD5加密技术进行加密。
在NSString+MD5sAddition.h文件中声明对外方法,方法名为:stringFromMD5s;返回值为字符串类型,如图2.1所示:
图2.1 声明加密方法
具体实现需要在.m文件中进行,需要引入一些命名空间,具体代码如下所示:
//调用系统内部文件,获取获取硬件信息
#import<CommonCrypto/CommonDigest.h>
@implementation
-(NSString
{
//若为空则返回
if (self==nil||[self length]==0) {
return nil;
}
//将传入的信息进行UTF8格式化
const char *value=[self UTF8String];
//16位加密
unsigned char outPutBuffer[CC_MD5_DIGEST_LENGTH];
//将传入的字符串value加密,并以固定长度的outPutBuffer输出
CC_MD5(value, strlen(value), outPutBuffer);
NSMutableString *outPutString=[[NSMutableString alloc]initWithCapacity:CC_MD5_DIGEST_LENGTH*2];
for (NSInteger count=0;count<CC_MD5_DIGEST_LENGTH; count++) {
//向可变字符串中追加字节信息
appendFormat:@"%02x",outPutBuffer[count]];
}
//返回加密后的字符串
return [outPutString autorelease];
}
@end
下面是在UIDevice+BundleIdentifier文件中进行的操作,在.h文件中声明两个对外的方法,如图2.2所示,声明两个对外的公共方法
.m文件中代码如下所示:
/*
本类说明:根据设备的Mac地址和系统唯一标示符BundleIdentifier获取设备唯一识别符
第一步:获取设备Mac地址,并转化为传统的Mac地址格式;
第二步:进行散列hash处理,即进行MD5信息加密,目的是用户个人隐私数据不能进行明文传播;
第三步:返回设备唯一识别符,保存到服务器端,作为唯一标示符区别注册用户。
创建时间:2012年11月02日
写 作:张志轩
*/
#import"UIDevice+BundleIdentifier.h"
//MD5加密文件调用
#import"NSString+MD5sAddition.h"
//引用底层信息类
#include<sys/socket.h>
#include<sys/sysctl.h>
#include<net/if.h>
#include<net/if_dl.h>
@interface
//获取Mac地址--本类私有方法
-(NSString
@end
@implementation
-(NSString
{
//设置参数
//Mac地址为6组共12个字符,格式为:XX:XX:XX:XX:XX:XX
int mib[6];
size_t
char
unsigned char
struct if_msghdr
struct sockaddr_dl
/*
设置信息资源库
*/
//请求网络子系统
0]=CTL_NET;
//路由表信息
1]=AF_ROUTE;
2]=0;
//链路层信息
3]=AF_LINK;
//配置端口信息
4]=NET_RT_IFLIST;
//判断En0地址是否存在,除联通3GS太监外,都存在
if ((mib[5]=if_nametoindex("en0"))==0) {
return NULL;
}
//获取数据的大小
if (sysctl(mib, 6, NULL,&len, NULL, 0)<0) {
return NULL;
}
//分配内存的基础上调用
if ((buf=malloc(len))==NULL) {
return NULL;
}
//获取系统信息,存储在缓冲区
if ((sysctl(mib, 6, buf, &len, NULL, 0))<0) {
free(buf);
return NULL;
}
//获取接口电气性结构
struct if_msghdr
struct sockaddr_dl *)(ifm+1);
unsigned char *)LLADDR(sdl);
//获取Mac地址信息:读取字符数组到一个字符串对象,设置为传统的Mac地址,即XX:XX:XX:XX:XX:XX
NSString *outString=[NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
//返回Mac地址信息
return
}
/*
对外公开方法
*/
#pragmamark -
#pragmamark - 通过Mac地址获取设备唯一标示符
-(NSString
{
//获取Mac地址
NSString *macAddress=[[UIDevice currentDevice] macAddress];
//对Mac地址进行加密
NSString *uniquenessDeviceIdentifier=[macAddress stringFromMD5s];
//返回加密后的Mac地址
return
}
#pragmamark -
#pragmamark - 将mac+bundle_id进行散列运算获得机器+应用的唯一标识
-(NSString
{
//获取Mac地址
NSString *macAddress=[[UIDevice currentDevice] macAddress];
//获取BundleIdentifier标示符
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
//组合信息
NSString *hashStringToMacAndIdentifier=[NSString stringWithFormat:@"%@%@",macAddress,bundleIdentifier];
//进行加密
NSString *uniquenessDeviceIdentifier=[hashStringToMacAndIdentifier stringFromMD5s];
//返回加密后唯一标示符
return
}
@end
3.获取用户设备唯一标示符
在调用文件中引入UIDevice+BundleIdentifier.h",如图3.1所示,
图3.1 文件引用,获取唯一标示符
下面是在某一方法中获取这个用户设备唯一标示符,如下代码所示:
//通过MacAddress和BundleIdentifier,获取用户设备唯一标示符
NSString *userUniquenessIdentifierByMacAddressAndBundleIdentifier=[NSString stringWithFormat:@"%@",[[UIDevice currentDevice]uniquenessDeviceIdentifierByMacAddressAndBundleIdentifier]];
//通过MacAddress,获取用户设备唯一标示符
NSString *userUniquenessIdentifierByMacAddress=[NSString stringWithFormat:@"%@",[[UIDevice currentDevice]uniquenessDeviceIdentifierByMacAddress]];
CheHuiLog(@"userUniquenessIdentifierByMacAddressAndBundleIdentifieris %@",userUniquenessIdentifierByMacAddressAndBundleIdentifier);
CheHuiLog(@"userUniquenessIdentifierByMacAddressis %@",userUniquenessIdentifierByMacAddress);
打印结果如图3.2所示
图3.2 唯一标示符打印结果