TVCUtils.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. //
  2. // TVCUtils.m
  3. // TCLVBIMDemo
  4. //
  5. // Created by carolsuo on 2017/11/3.
  6. // Copyright © 2017年 tencent. All rights reserved.
  7. //
  8. #import "TVCUtils.h"
  9. #import <sys/utsname.h>
  10. #import <sys/sysctl.h>
  11. #import <CommonCrypto/CommonDigest.h>
  12. #import <CoreTelephony/CTCarrier.h>
  13. #import <CoreTelephony/CTTelephonyNetworkInfo.h>
  14. #import <SystemConfiguration/SystemConfiguration.h>
  15. #import <UIKit/UIKit.h>
  16. #include <sys/types.h>
  17. #include <sys/socket.h>
  18. #include <arpa/inet.h>
  19. #include <netdb.h>
  20. static NSString * const kTVCPDDictionaryKey = @"com.tencent.liteavupload.uuidDictionaryKey";
  21. static NSString * const kTVCPDKeyChainKey = @"com.tencent.liteavupload.uuidkeychainKey";
  22. @implementation TVCUtils
  23. static NSString *tvc_systemBootTime(){
  24. struct timeval boottime;
  25. size_t len = sizeof(boottime);
  26. int mib[2] = { CTL_KERN, KERN_BOOTTIME };
  27. if( sysctl(mib, 2, &boottime, &len, NULL, 0) < 0 )
  28. {
  29. return @"";
  30. }
  31. time_t bsec = boottime.tv_sec / 10000;
  32. NSString *bootTime = [NSString stringWithFormat:@"%ld",bsec];
  33. return bootTime;
  34. }
  35. static NSString *tvc_countryCode() {
  36. NSLocale *locale = [NSLocale currentLocale];
  37. NSString *countryCode = [locale objectForKey:NSLocaleCountryCode];
  38. return countryCode;
  39. }
  40. static NSString *tvc_language() {
  41. NSString *language;
  42. NSLocale *locale = [NSLocale currentLocale];
  43. if ([[NSLocale preferredLanguages] count] > 0) {
  44. language = [[NSLocale preferredLanguages]objectAtIndex:0];
  45. } else {
  46. language = [locale objectForKey:NSLocaleLanguageCode];
  47. }
  48. return language;
  49. }
  50. static NSString *tvc_systemVersion() {
  51. return [[UIDevice currentDevice] systemVersion];
  52. }
  53. static NSString *tvc_deviceName(){
  54. return [[UIDevice currentDevice] name];
  55. }
  56. static const char *tvc_SIDFAModel = "hw.model";
  57. static const char *tvc_SIDFAMachine = "hw.machine";
  58. static NSString *tvc_getSystemHardwareByName(const char *typeSpecifier) {
  59. size_t size;
  60. sysctlbyname(typeSpecifier, NULL, &size, NULL, 0);
  61. char *answer = malloc(size);
  62. sysctlbyname(typeSpecifier, answer, &size, NULL, 0);
  63. NSString *results = [NSString stringWithUTF8String:answer];
  64. free(answer);
  65. return results;
  66. }
  67. static NSUInteger tvc_getSysInfo(uint typeSpecifier) {
  68. size_t size = sizeof(int);
  69. int results;
  70. int mib[2] = {CTL_HW, typeSpecifier};
  71. sysctl(mib, 2, &results, &size, NULL, 0);
  72. return (NSUInteger) results;
  73. }
  74. static NSString *tvc_carrierInfo() {
  75. NSMutableString* cInfo = [NSMutableString string];
  76. CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init];
  77. CTCarrier *carrier = [networkInfo subscriberCellularProvider];
  78. NSString *carrierName = [carrier carrierName];
  79. if (carrierName != nil){
  80. [cInfo appendString:carrierName];
  81. }
  82. NSString *mcc = [carrier mobileCountryCode];
  83. if (mcc != nil){
  84. [cInfo appendString:mcc];
  85. }
  86. NSString *mnc = [carrier mobileNetworkCode];
  87. if (mnc != nil){
  88. [cInfo appendString:mnc];
  89. }
  90. return cInfo;
  91. }
  92. static NSString *tvc_systemHardwareInfo(){
  93. NSString *model = tvc_getSystemHardwareByName(tvc_SIDFAModel);
  94. NSString *machine = tvc_getSystemHardwareByName(tvc_SIDFAMachine);
  95. NSString *carInfo = tvc_carrierInfo();
  96. NSUInteger totalMemory = tvc_getSysInfo(HW_PHYSMEM);
  97. return [NSString stringWithFormat:@"%@,%@,%@,%td",model,machine,carInfo,totalMemory];
  98. }
  99. static NSString *tvc_systemFileTime(){
  100. NSFileManager *file = [NSFileManager defaultManager];
  101. NSDictionary *dic= [file attributesOfItemAtPath:@"System/Library/CoreServices" error:nil];
  102. return [NSString stringWithFormat:@"%@,%@",[dic objectForKey:NSFileCreationDate],[dic objectForKey:NSFileModificationDate]];
  103. }
  104. static NSString *tvc_disk(){
  105. NSDictionary *fattributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
  106. NSString *diskSize = [[fattributes objectForKey:NSFileSystemSize] stringValue];
  107. return diskSize;
  108. }
  109. static void tvc_MD5_16(NSString *source, unsigned char *ret){
  110. const char* str = [source UTF8String];
  111. unsigned char result[CC_MD5_DIGEST_LENGTH];
  112. CC_MD5(str, (CC_LONG)strlen(str), result);
  113. for(int i = 4; i < CC_MD5_DIGEST_LENGTH - 4; i++) {
  114. ret[i-4] = result[i];
  115. }
  116. }
  117. static NSString *tvc_combineTwoFingerPrint(unsigned char *fp1,unsigned char *fp2){
  118. NSMutableString *hash = [NSMutableString stringWithCapacity:36];
  119. for(int i = 0; i<CC_MD5_DIGEST_LENGTH; i+=1)
  120. {
  121. if (i==4 || i== 6 || i==8 || i==10)
  122. [hash appendString:@"-"];
  123. if (i < 8) {
  124. [hash appendFormat:@"%02X",fp1[i]];
  125. }else{
  126. [hash appendFormat:@"%02X",fp2[i-8]];
  127. }
  128. }
  129. return hash;
  130. }
  131. + (NSString *)tvc_createSimulateIDFA{
  132. NSString *sysBootTime = tvc_systemBootTime();
  133. NSString *countryC= tvc_countryCode();
  134. NSString *languge = tvc_language();
  135. NSString *deviceN = tvc_deviceName();
  136. NSString *sysVer = tvc_systemVersion();
  137. NSString *systemHardware = tvc_systemHardwareInfo();
  138. NSString *systemFT = tvc_systemFileTime();
  139. NSString *diskS = tvc_disk();
  140. NSString *fingerPrintUnstablePart = [NSString stringWithFormat:@"%@,%@,%@,%@", sysBootTime, countryC, languge, deviceN];
  141. NSString *fingerPrintStablePart = [NSString stringWithFormat:@"%@,%@,%@,%@", sysVer, systemHardware, systemFT, diskS];
  142. unsigned char fingerPrintUnstablePartMD5[CC_MD5_DIGEST_LENGTH/2];
  143. tvc_MD5_16(fingerPrintUnstablePart,fingerPrintUnstablePartMD5);
  144. unsigned char fingerPrintStablePartMD5[CC_MD5_DIGEST_LENGTH/2];
  145. tvc_MD5_16(fingerPrintStablePart,fingerPrintStablePartMD5);
  146. NSString *simulateIDFA = tvc_combineTwoFingerPrint(fingerPrintStablePartMD5,fingerPrintUnstablePartMD5);
  147. return simulateIDFA;
  148. }
  149. + (NSMutableDictionary *)tvc_getKeychainQuery:(NSString *)service {
  150. return [NSMutableDictionary dictionaryWithObjectsAndKeys:
  151. (id)kSecClassGenericPassword,(id)kSecClass,
  152. service, (id)kSecAttrService,
  153. service, (id)kSecAttrAccount,
  154. (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,
  155. nil];
  156. }
  157. + (void)tvc_keyChainSave:(NSString *)string {
  158. NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];
  159. [tempDic setObject:string forKey:kTVCPDDictionaryKey];
  160. //Get search dictionary
  161. NSMutableDictionary *keychainQuery = [TVCUtils tvc_getKeychainQuery:kTVCPDKeyChainKey];
  162. //Delete old item before add new item
  163. SecItemDelete((CFDictionaryRef)keychainQuery);
  164. //Add new object to search dictionary(Attention:the data format)
  165. [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:tempDic] forKey:(id)kSecValueData];
  166. //Add item to keychain with the search dictionary
  167. SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
  168. }
  169. + (NSString *)tvc_keyChainLoad{
  170. id ret = nil;
  171. NSMutableDictionary *keychainQuery = [TVCUtils tvc_getKeychainQuery:kTVCPDKeyChainKey];
  172. //Configure the search setting
  173. //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue
  174. [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
  175. [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
  176. CFDataRef keyData = NULL;
  177. if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
  178. @try {
  179. ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
  180. } @catch (NSException *e) {
  181. NSLog(@"Unarchive of %@ failed: %@", kTVCPDKeyChainKey, e);
  182. } @finally {
  183. }
  184. }
  185. if (keyData)
  186. CFRelease(keyData);
  187. NSMutableDictionary *tempDic = ret;
  188. return [tempDic objectForKey:kTVCPDDictionaryKey];
  189. }
  190. + (NSString *)tvc_createDevUUID:(NSString *)simulateIDFA {
  191. NSString * devUuid = [TVCUtils tvc_keyChainLoad];
  192. if (nil == devUuid) {
  193. CFUUIDRef puuid = CFUUIDCreate( nil );
  194. CFStringRef uuidString = CFUUIDCreateString( nil, puuid );
  195. NSString * cUUID = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString));
  196. CFRelease(puuid);
  197. CFRelease(uuidString);
  198. simulateIDFA = [simulateIDFA stringByAppendingString:cUUID];
  199. const char *c_str_simulateIDFA = [simulateIDFA UTF8String];
  200. unsigned char md5_simulateIDFA[CC_MD5_DIGEST_LENGTH];
  201. CC_MD5( c_str_simulateIDFA, (CC_LONG)strlen(c_str_simulateIDFA), md5_simulateIDFA);
  202. devUuid = tvc_combineTwoFingerPrint(md5_simulateIDFA, md5_simulateIDFA+(CC_MD5_DIGEST_LENGTH/2));
  203. [TVCUtils tvc_keyChainSave:devUuid];
  204. }
  205. return devUuid;
  206. }
  207. + (NSString *)tvc_getDevUUID {
  208. return [TVCUtils tvc_createDevUUID:[TVCUtils tvc_createSimulateIDFA]];
  209. }
  210. + (int) tvc_getNetWorkType
  211. {
  212. int NetworkType = 0; // UNKNOWN
  213. //创建零地址,0.0.0.0的地址表示查询本机的网络连接状态
  214. struct sockaddr_storage zeroAddress;
  215. bzero(&zeroAddress, sizeof(zeroAddress));
  216. zeroAddress.ss_len = sizeof(zeroAddress);
  217. zeroAddress.ss_family = AF_INET;
  218. // Recover reachability flags
  219. SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
  220. SCNetworkReachabilityFlags flags;
  221. //获得连接的标志
  222. BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
  223. CFRelease(defaultRouteReachability);
  224. //如果不能获取连接标志,则不能连接网络,直接返回
  225. if (!didRetrieveFlags)
  226. {
  227. return NetworkType;
  228. }
  229. if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
  230. {
  231. // if target host is reachable and no connection is required
  232. // then we'll assume (for now) that your on Wi-Fi
  233. if ((flags & kSCNetworkReachabilityFlagsReachable) != 0) // fix by annidy:无连接时不能返回WIFI
  234. NetworkType = 1; // WIFI
  235. }
  236. if (
  237. ((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
  238. (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0
  239. )
  240. {
  241. // ... and the connection is on-demand (or on-traffic) if the
  242. // calling application is using the CFSocketStream or higher APIs
  243. if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
  244. {
  245. // ... and no [user] intervention is needed
  246. NetworkType = 1; // WIFI
  247. }
  248. }
  249. if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
  250. {
  251. if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
  252. {
  253. CTTelephonyNetworkInfo * info = [[CTTelephonyNetworkInfo alloc] init];
  254. NSString *currentRadioAccessTechnology = info.currentRadioAccessTechnology;
  255. if (currentRadioAccessTechnology)
  256. {
  257. if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE])
  258. {
  259. NetworkType = 2; // 4G
  260. }
  261. else if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge] || [currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS])
  262. {
  263. NetworkType = 4; // 2G
  264. }
  265. else
  266. {
  267. NetworkType = 3; // 3G
  268. }
  269. }
  270. }
  271. else
  272. {
  273. if((flags & kSCNetworkReachabilityFlagsReachable) == kSCNetworkReachabilityFlagsReachable)
  274. {
  275. if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection)
  276. {
  277. if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired)
  278. {
  279. NetworkType = 4; // 2G
  280. }
  281. else
  282. {
  283. NetworkType = 3; // 3G
  284. }
  285. }
  286. }
  287. }
  288. }
  289. return NetworkType;
  290. }
  291. + (NSString *)tvc_deviceModelName
  292. {
  293. struct utsname systemInfo;
  294. uname(&systemInfo);
  295. NSString *deviceModel = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
  296. //iPhone 系列
  297. if ([deviceModel isEqualToString:@"iPhone1,1"]) return @"iPhone 1G";
  298. if ([deviceModel isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
  299. if ([deviceModel isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
  300. if ([deviceModel isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
  301. if ([deviceModel isEqualToString:@"iPhone3,2"]) return @"Verizon iPhone 4";
  302. if ([deviceModel isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
  303. if ([deviceModel isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
  304. if ([deviceModel isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
  305. if ([deviceModel isEqualToString:@"iPhone5,3"]) return @"iPhone 5C";
  306. if ([deviceModel isEqualToString:@"iPhone5,4"]) return @"iPhone 5C";
  307. if ([deviceModel isEqualToString:@"iPhone6,1"]) return @"iPhone 5S";
  308. if ([deviceModel isEqualToString:@"iPhone6,2"]) return @"iPhone 5S";
  309. if ([deviceModel isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
  310. if ([deviceModel isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
  311. if ([deviceModel isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
  312. if ([deviceModel isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
  313. if ([deviceModel isEqualToString:@"iPhone9,1"]) return @"iPhone 7 (CDMA)";
  314. if ([deviceModel isEqualToString:@"iPhone9,3"]) return @"iPhone 7 (GSM)";
  315. if ([deviceModel isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus (CDMA)";
  316. if ([deviceModel isEqualToString:@"iPhone9,4"]) return @"iPhone 7 Plus (GSM)";
  317. //iPod 系列
  318. if ([deviceModel isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
  319. if ([deviceModel isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
  320. if ([deviceModel isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G";
  321. if ([deviceModel isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G";
  322. if ([deviceModel isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G";
  323. //iPad 系列
  324. if ([deviceModel isEqualToString:@"iPad1,1"]) return @"iPad";
  325. if ([deviceModel isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)";
  326. if ([deviceModel isEqualToString:@"iPad2,2"]) return @"iPad 2 (GSM)";
  327. if ([deviceModel isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)";
  328. if ([deviceModel isEqualToString:@"iPad2,4"]) return @"iPad 2 (32nm)";
  329. if ([deviceModel isEqualToString:@"iPad2,5"]) return @"iPad mini (WiFi)";
  330. if ([deviceModel isEqualToString:@"iPad2,6"]) return @"iPad mini (GSM)";
  331. if ([deviceModel isEqualToString:@"iPad2,7"]) return @"iPad mini (CDMA)";
  332. if ([deviceModel isEqualToString:@"iPad3,1"]) return @"iPad 3(WiFi)";
  333. if ([deviceModel isEqualToString:@"iPad3,2"]) return @"iPad 3(CDMA)";
  334. if ([deviceModel isEqualToString:@"iPad3,3"]) return @"iPad 3(4G)";
  335. if ([deviceModel isEqualToString:@"iPad3,4"]) return @"iPad 4 (WiFi)";
  336. if ([deviceModel isEqualToString:@"iPad3,5"]) return @"iPad 4 (4G)";
  337. if ([deviceModel isEqualToString:@"iPad3,6"]) return @"iPad 4 (CDMA)";
  338. if ([deviceModel isEqualToString:@"iPad4,1"]) return @"iPad Air";
  339. if ([deviceModel isEqualToString:@"iPad4,2"]) return @"iPad Air";
  340. if ([deviceModel isEqualToString:@"iPad4,3"]) return @"iPad Air";
  341. if ([deviceModel isEqualToString:@"iPad5,3"]) return @"iPad Air 2";
  342. if ([deviceModel isEqualToString:@"iPad5,4"]) return @"iPad Air 2";
  343. if ([deviceModel isEqualToString:@"i386"]) return @"Simulator";
  344. if ([deviceModel isEqualToString:@"x86_64"]) return @"Simulator";
  345. if ([deviceModel isEqualToString:@"iPad4,4"]
  346. ||[deviceModel isEqualToString:@"iPad4,5"]
  347. ||[deviceModel isEqualToString:@"iPad4,6"]) return @"iPad mini 2";
  348. if ([deviceModel isEqualToString:@"iPad4,7"]
  349. ||[deviceModel isEqualToString:@"iPad4,8"]
  350. ||[deviceModel isEqualToString:@"iPad4,9"]) return @"iPad mini 3";
  351. return deviceModel;
  352. }
  353. @end