转载自:https://github.com/youmi/SimulateIDFA/wiki/%E4%B8%AD%E6%96%87%E8%AF%B4%E6%98%8E%E6%96%87%E6%A1%A3
上一篇说到ios10 开启限制广告跟踪之后 获取的idfa就是一串000000,网上大神很快就给吾等屌丝搬砖者带来了福音SimulateIDFA
(源文件下载地址:https://files.cnblogs.com/files/slc-lover/SimulateIDFA.zip)
SimulateIDFA
是根据一堆设备信息(每个app获取的值都是一样的)生成的一个MD5值。用于标志不同设备。
使用时
导入CoreTelephony.framework
#import "SimulateIDFA.h
"
NSString *simulateIDFA = [SimulateIDFA createSimulateIDFA];
NSLog(@"获取到的simulateIDFA
是 %@",simulateIDFA
);
具体实现文件(可从上面提供的源文件下载地址直接下载源文件)
导入CoreTelephony.framework
SimulateIDFA.h文件:
SimulateIDFA.m文件:
#import <UIKit/UIKit.h>
#import "SimulateIDFA.h"
#import <sys/sysctl.h>
#import <CommonCrypto/CommonDigest.h>
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
@implementation SimulateIDFA
static NSString *systemBootTime(){
struct timeval boottime;
size_t len = sizeof(boottime);
int mib[2] = { CTL_KERN, KERN_BOOTTIME };
if( sysctl(mib, 2, &boottime, &len, NULL, 0) < 0 )
{
return @"";
}
time_t bsec = boottime.tv_sec / 10000;
NSString *bootTime = [NSString stringWithFormat:@"%ld",bsec];
return bootTime;
}
static NSString *countryCode() {
NSLocale *locale = [NSLocale currentLocale];
NSString *countryCode = [locale objectForKey:NSLocaleCountryCode];
return countryCode;
}
static NSString *language() {
NSString *language;
NSLocale *locale = [NSLocale currentLocale];
if ([[NSLocale preferredLanguages] count] > 0) {
language = [[NSLocale preferredLanguages]objectAtIndex:0];
} else {
language = [locale objectForKey:NSLocaleLanguageCode];
}
return language;
}
static NSString *systemVersion() {
return [[UIDevice currentDevice] systemVersion];
}
static NSString *deviceName(){
return [[UIDevice currentDevice] name];
}
static const char *SIDFAModel = "hw.model";
static const char *SIDFAMachine = "hw.machine";
static NSString *getSystemHardwareByName(const char *typeSpecifier) {
size_t size;
sysctlbyname(typeSpecifier, NULL, &size, NULL, 0);
char *answer = malloc(size);
sysctlbyname(typeSpecifier, answer, &size, NULL, 0);
NSString *results = [NSString stringWithUTF8String:answer];
free(answer);
return results;
}
static NSUInteger GetSysInfo(uint typeSpecifier) {
size_t size = sizeof(int);
int results;
int mib[2] = {CTL_HW, typeSpecifier};
sysctl(mib, 2, &results, &size, NULL, 0);
return (NSUInteger) results;
}
static NSString *carrierInfo() {
NSMutableString* cInfo = [NSMutableString string];
CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = [networkInfo subscriberCellularProvider];
NSString *carrierName = [carrier carrierName];
if (carrierName != nil){
[cInfo appendString:carrierName];
}
NSString *mcc = [carrier mobileCountryCode];
if (mcc != nil){
[cInfo appendString:mcc];
}
NSString *mnc = [carrier mobileNetworkCode];
if (mnc != nil){
[cInfo appendString:mnc];
}
return cInfo;
}
static NSString *systemHardwareInfo(){
NSString *model = getSystemHardwareByName(SIDFAModel);
NSString *machine = getSystemHardwareByName(SIDFAMachine);
NSString *carInfo = carrierInfo();
NSUInteger totalMemory = GetSysInfo(HW_PHYSMEM);
return [NSString stringWithFormat:@"%@,%@,%@,%td",model,machine,carInfo,totalMemory];
}
static NSString *DQUSystemFileTime(){
NSFileManager *file = [NSFileManager defaultManager];
NSDictionary *dic= [file attributesOfItemAtPath:@"System/Library/CoreServices" error:nil];
return [NSString stringWithFormat:@"%@,%@",[dic objectForKey:NSFileCreationDate],[dic objectForKey:NSFileModificationDate]];
}
static NSString *DQUDisk(){
NSDictionary *fattributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
NSString *diskSize = [[fattributes objectForKey:NSFileSystemSize] stringValue];
return diskSize;
}
void MD5_16(NSString *source, unsigned char *ret){
const char* str = [source UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(str, (CC_LONG)strlen(str), result);
for(int i = 4; i < CC_MD5_DIGEST_LENGTH - 4; i++) {
ret[i-4] = result[i];
}
}
static NSString *combineTwoFingerPrint(unsigned char *fp1,unsigned char *fp2){
NSMutableString *hash = [NSMutableString stringWithCapacity:36];
for(int i = 0; i<CC_MD5_DIGEST_LENGTH; i+=1)
{
if (i==4 || i== 6 || i==8 || i==10)
[hash appendString:@"-"];
if (i < 8) {
[hash appendFormat:@"%02X",fp1[i]];
}else{
[hash appendFormat:@"%02X",fp2[i-8]];
}
}
return hash;
}
+ (NSString *)createSimulateIDFA{
NSString *sysBootTime = systemBootTime();
NSString *CC= countryCode();
NSString *languge = language();
NSString *deviceN = deviceName();
NSString *sysVer = systemVersion();
NSString *systemHardware = systemHardwareInfo();
NSString *systemFT = DQUSystemFileTime();
NSString *diskS = DQUDisk();
NSString *fingerPrintUnstablePart = [NSString stringWithFormat:@"%@,%@,%@,%@",sysBootTime,CC,languge,deviceN];
NSString *fingerPrintStablePart = [NSString stringWithFormat:@"%@,%@,%@,%@",sysVer,systemHardware,systemFT,diskS];
unsigned char fingerPrintUnstablePartMD5[CC_MD5_DIGEST_LENGTH/2];
MD5_16(fingerPrintUnstablePart,fingerPrintUnstablePartMD5);
unsigned char fingerPrintStablePartMD5[CC_MD5_DIGEST_LENGTH/2];
MD5_16(fingerPrintStablePart,fingerPrintStablePartMD5);
NSString *simulateIDFA = combineTwoFingerPrint(fingerPrintStablePartMD5,fingerPrintUnstablePartMD5);
return simulateIDFA;
}
@end