文档章节

UDID 和 UUID 的问题

 王素年
发布于 2017/02/07 11:13
字数 2196
阅读 62
收藏 0

一、UDID 全名  Unique Device Identifier :设备唯一标识符。UDID是和设备有关的,而且是只和设备有关的,有点类似于电脑的MAC地址。真机调试中我们需要把UDID这个东西添加到Provisoning Profile授权文件中,也就是把设备唯一标识符添加进去,以此来识别某一台设备。

UDID是一个40位十六进制序列,我们可以使用 iTunes 和 Xcode 来获取这个值。

 

(1)iTunes获取UDID:

  设备连上电脑,打开iTunes.

注意:默认这个位置显示的是序列号,只要点击一下序列号(红色箭头处)的位置,就可以切换为UDID了

 

(2)Xcode获取UDID:

把设备连上电脑,然后打开Xcode,选择Window-->Devices,就会显示出当前你连接上的所有设备,其中显示的Identifier就是该设备的UDID:

上面是通过设备直接查看得到的,如果我们要在代码中访问UDID,怎么做呢?

ios5 sdk中的获取方法: 

[UIDevice currentDevice] uniqueIdentifier];

对于已越狱了的设备,UDID并不是唯一的.使用Cydia插件UDIDFaker,可以为每一个应用分配不同的UDID. 

所以UDID作为标识唯一设备的用途已经不大了. 

 

二、UUID全名 Universally Unique Identifier的缩写,中文意思是通用唯一识别码。

 

很遗憾,自从iOS5之后,苹果就禁止了通过代码访问UDID,在这之前,可以使用[[UIDevice cuurrent] uniqueIdenfier] 这个方法来获取某设备UDID,现在是不可能了。对于为什么要禁止访问UDID,我下面会提到。

 

CFUUID 从iOS2.0开始,CFUUID就有了。它是CoreFoundatio包的一部分,因此API属于C语言风格。CFUUIDCreate 方法用来创建CFUUIDRef,并且可以获得一个相应的 NSString,代码如下:

  • CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault); 
  • NSString *cfuuidString =(NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));

获得的这个CFUUID值系统并没有存储每次调用CFUUIDCreate,系统都会返回一个的唯一标示符。如果你希望存储这个标示符,那么需要自己将其存储到NSUserDefaults, Keychain,或其它地方。

示例: 68753A44-4D6F-1226-9C60-0050E4C00067

 

NSUUID在iOS 6中才出现,这跟CFUUID几乎完全一样,只不过它是Objective-C接口。+ (id)UUID 是一个类方法,调用该方法可以获得一个UUID。通过下面的代码可以获得一个UUID字符串:

  • NSString *uuid = [[NSUUID UUID] UUIDString];

CFUUID一样,这个值系统也不会存储每次调用的时候都会获得一个的唯一标示符。如果要存储的话,你需要自己存储。在我读取NSUUID时,注意到获取到的这个值跟CFUUID完全一样(不过也可能不一样):

示例: 68753A44-4D6F-1226-9C60-0050E4C00067

 

广告标示符(IDFA-identifierForIdentifier)这是iOS 6中另外一个新的方法,advertisingIdentifier 是新框架AdSupport.framework的一部分。ASIdentifierManager单例提供了一个方法advertisingIdentifier,通过调用该方法会返回一个上面提到的NSUUID实例。

  • NSString *adId =[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

CFUUIDNSUUID不一样,广告标示符是由系统存储着的。不过即使这是由系统存储的,但是有几种情况下,会重新生成广告标示符。如果用户完全重置系统((设置程序 -> 通用 -> 还原 -> 还原位置与隐私) ,这个广告标示符会重新生成。另外如果用户明确的还原广告(设置程序-> 通用 -> 关于本机 -> 广告 -> 还原广告标示符) ,那么广告标示符也会重新生成。关于广告标示符的还原,有一点需要注意:如果程序在后台运行,此时用户“还原广告标示符”,然后再回到程序中,此时获取广告标示符并不会立即获得还原后的标示符。必须要终止程序,然后再重新启动程序,才能获得还原后的广告标示符。之所以会这样,我猜测是由于ASIdentifierManager是一个单例。

针对广告标示符用户有一个可控的开关“限制广告跟踪”。Nick Arnott的文章中已经指出了。将这个开关打开,实际上什么也没有做,不过这是希望限制你访问广告标示符。这个开关是一个简单的boolean标志,当将广告标示符发到任意的服务器端时,你最好判断一下这个值,然后再做决定。

示例: 1E2DFA89-496A-47FD-9941-DF1FC4E6484A

 

Vindor标示符 (IDFV-identifierForVendor)这种叫法也是在iOS 6中新增的,不过获取这个IDFV的新方法被添加在已有的UIDevice类中。跟advertisingIdentifier一样,该方法返回的是一个NSUUID对象。

  • NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

苹果官方的文档中对identifierForVendor有如下这样的一段描述 :

The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor.

 

相同的程序-相同的vindor-相同的设备,那么获取到的这个属性值就不会变

相同的程序-相同的设备-不同的vindor,或 相同的程序-不同的设备-无论是否相同的vindor 那么这个值是不同的:。

(vendor非常简单:一个Vendor是CFBundleIdentifier(反转DNS格式)的前两部分。例如,com.doubleencore.app1 和 com.doubleencore.app2 得到的identifierForVendor是相同的,因为它们的CFBundleIdentifier 前两部分是相同的。)

在这里,还需要注意的一点就是:如果用户卸载了同一个vendor对应的所有程序,然后在重新安装同一个vendor提供的程序,此时identifierForVendor会被重置。

示例: 599F9C00-92DC-4B5C-9464-7971F01F8370

 

重点:上面的IDFV方法中

这个identifierForVendor应用设备两者都有关的,A应用安装到张三这台设备上,就会产生一个identifierForVendor(比如是:1234);A应用安装到李四这台设备上,就会产生另一个identifierForVendor(比如是:5678);B应用安装到张三这台设备上,又是一个全新的identifierForVendor(比如是:9999),B应用安装到李四这台设备上,还是一个全新的identifierForVendor(比如是:7777)。  所以我们知道,这个identifierForVendor是一种应用加设备绑定产生的标识符,相当于是:Z(identifierForVendor) = X(某应用) + Y(某设备)。 当然,和真正的UDID的区别是显而易见的:也就是说App的开发者没有办法去区分某一台设备了,而是只能识别某个应用在某台设备上。且UUID每次生成的值都不一样,需要开发者自行保存UUID. 

如果使用UUID为标识保存用户的资料在网络上,当用户卸载软件重装软件后,UUID的值就可能会发生改变(基本上可说是百分百会发生改变),用户则无法重新下载原来的网络资料。

 

三.一个可行的解决方案 

大多数应用都会用到苹果设备的UDID号,UDID通常有以下两种用途:

1)用于一些统计与分析目的;【第三方统计工具如友盟,广告商如ADMOB等】

2)将UDID作为用户ID来唯一识别用户,省去用户名,密码等注册过程。

 

但是因为UUID的特性,不能解决这种问题,现在网上有一现成的解决方案,使用设备的Mac地址,因为Mac地址也是唯一的.unix有系统调用可以获取Mac地址.但有些事情需要注意: 

1.iPhone可能有多个Mac地址,wifi的地址,以及SIM卡的地址.一般来讲,我们取en0的地址,因为他是iPhone的wifi的地址,是肯定存在的.(例外情况依然有:市面上依然存在一部分联通的阉割版无wifi的iPhone) 

2.Mac地址涉及到隐私,不应该胡乱将用户的Mac地址传播!所以我们需要将Mac地址进行hash之后,才能作为DeviceId上传. 

 

关于第一个注意点的问题,经过我测试,没有Wifi功能的iPhone3GS一样可以获得Mac地址,所以这应该是目前标识设备唯一最好的一个解决方案. 

 

 

解决方案github下载地址github。https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5

该方案提供了两个方法:

uniqueDeviceIdentifier (返回MAC和CFBundleIdentifier的MD5值)

uniqueGlobalDeviceIdentifier(返回MAC的MD5值)

 

使用方法:

#import "UIDevice+IdentifierAddition.h"

NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]);

NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);

 

 

测试结果:

WIFI下:

UDID:XXXX21f1f19edff198e2a2356bf4XXXX 

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX 

 

3G下:

UDID:XXXX21f1f19edff198e2a2356bf4XXXX

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX

 

GPRS下

UDID:XXXX21f1f19edff198e2a2356bf4XXXX

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX

 

飞行模式下:

UDID:XXXX21f1f19edff198e2a2356bf4XXXX

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX

 

删除应用重装后:

UDID:XXXX21f1f19edff198e2a2356bf4XXXX

新生成的:XXXX7dc3c577446a2bcbd77935bdXXXX

© 著作权归作者所有

粉丝 2
博文 75
码字总数 45756
作品 0
普陀
程序员
私信 提问
iOS 唯一标示用户的设备

众所周知,苹果在iOS7禁用了 [UIDevice uniqueIdentifier] 也抛弃MAC 地址 现在苹果明确的表明你应该使用-[UIDevice identifierForVendor]或是-[ASIdentifierManager advertisingIdentifier...

小胖123
2015/11/26
1K
0
iOS开发中的UDID和UUID详解

版权声明:本文为博主原创文章,欢迎分享到其它技术社区,分享请标明出处: https://blog.csdn.net/CHENYUFENG1991/article/details/51531491 今天突然想和大家聊聊UDID和UUID的问题,虽然平...

乞力马扎罗的雪CYF
2016/05/29
0
0
iPhone开发关于UDID和UUID的一些理解

一.UDID(Unique Device Identifier) UDID是Unique Device Identifier的缩写,中文意思是设备唯一标识. 在很多需要限制一台设备一个账号的应用中经常会用到,在Symbian时代,我们是使用IMEI作为设...

Megan_zhou
2013/07/11
12.5K
2
iOS开发技巧(系列十二:UUID和UDID的区别)

Google搜索关键字Difference between UUID and UDID,在stackoverflow看见解释,我翻译过来,如下所述。 UUID(Universally Unique IDentifier)是基于iOS设备上面某个单个的应用程序,只要用...

召唤攻城狮
2014/05/19
9.3K
4
iOS5中的UUID

在ios5中,UDID已不再被推荐使用,在将来的版本中,这个功能可能会消失。所以我们得探寻它的取代方法,能唯一标识设备的东西。往往硬件上有唯一标识,所以我们可以用硬件上的信息来取代UDID,...

长平狐
2012/08/13
107
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 如果是个帅小伙你愿意和他出去吗

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐:《Ghost 》游戏《死亡搁浅》原声 《Ghost 》游戏(《死亡搁浅》原声) - Au/Ra / Alan Walker 手机党少年们想听歌,请使劲儿戳...

小小编辑
47分钟前
77
5
java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
16
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部