原文连接:http://www.blogjava.net/feelyou/archive/2008/10/14/234320.htmlhtml
讨论UUID的定义、分类、应用及生成工具。
什么是UUID?
UUID是Universally Unique Identifier的缩写,它是在必定的范围内(从特定的名字空间到全球)惟一的机器生成的标识符。UUID具备如下涵义:
java
为了保证UUID的惟一性,规范定义了包括网卡MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素,以及从这些元素生成UUID的算法。UUID的复杂特性在保证了其惟一性的同时,意味着只能由计算机生成。web
UUID是不能人工指定的,除非你冒着UUID重复的风险。UUID的复杂性决定了“通常人“不能直接从一个UUID知道哪一个对象和它关联。算法
UUID的生成规范定义的算法主要目的就是要保证其惟一性。但这个惟一性是有限的,只在特定的范围内才能获得保证,这和UUID的类型有关(参见UUID的版本)。
UUID是16字节128位长的数字,一般以36字节的字符串表示,示例以下:
3F2504E0-4F89-11D3-9A0C-0305E82C3301
其中的字母是16进制表示,大小写无关。
GUID(Globally Unique Identifier)是UUID的别名;但在实际应用中,GUID一般是指微软实现的UUID。
UUID的版本
UUID具备多个版本,每一个版本的算法不一样,应用范围也不一样。
首先是一个特例--Nil UUID--一般咱们不会用到它,它是由全为0的数字组成,以下:
00000000-0000-0000-0000-000000000000
UUID Version 1:基于时间的UUID
基于时间的UUID经过计算当前时间戳、随机数和机器MAC地址获得。因为在算法中使用了MAC地址,这个版本的UUID能够保证在全球范围的惟一性。但与此同时,使用MAC地址会带来安全性问题,这就是这个版本UUID受到批评的地方。若是应用只是在局域网中使用,也可使用退化的算法,以IP地址来代替MAC地址--Java的UUID每每是这样实现的(固然也考虑了获取MAC的难度)。
UUID Version 2:DCE安全的UUID
DCE(Distributed Computing Environment)安全的UUID和基于时间的UUID算法相同,但会把时间戳的前4位置换为POSIX的UID或GID。这个版本的UUID在实际中较少用到。
UUID Version 3:基于名字的UUID(MD5)
基于名字的UUID经过计算名字和名字空间的MD5散列值获得。这个版本的UUID保证了:相同名字空间中不一样名字生成的UUID的惟一性;不一样名字空间中的UUID的惟一性;相同名字空间中相同名字的UUID重复生成是相同的。
UUID Version 4:随机UUID
根据随机数,或者伪随机数生成UUID。这种UUID产生重复的几率是能够计算出来的,但随机的东西就像是买彩票:你期望它发财是不可能的,但狗屎运一般会在不经意中到来。
UUID Version 5:基于名字的UUID(SHA1)
和版本3的UUID算法相似,只是散列值计算使用SHA1(Secure Hash Algorithm 1)算法。
UUID的应用
从UUID的不一样版本能够看出,Version 1/2适合应用于分布式计算环境下,具备高度的惟一性;Version 3/5适合于必定范围内名字惟一,且须要或可能会重复生成UUID的环境下;至于Version 4,我我的的建议是最好不用(虽然它是最简单最方便的)。
一般咱们建议使用UUID来标识对象或持久化数据,但如下状况最好不使用UUID:
安全
对于具备名称不可重复的天然特性的对象,最好使用Version 3/5的UUID。好比系统中的用户。若是用户的UUID是Version 1的,若是你不当心删除了再重建用户,你会发现人仍是那我的,用户已经不是那个用户了。(虽然标记为删除状态也是一种解决方案,但会带来实现上的复杂性。)
UUID生成器
我没想着有人看完了这篇文章就去本身实现一个UUID生成器,因此前面的内容并不涉及算法的细节。下面是一些可用的Java UUID生成器:
分布式
此外,Hibernate中也有一个UUID生成器,可是,生成的不是任何一个(规范)版本的UUID,强烈不建议使用。
延伸阅读
UUID规范:rfc4122
DCE 1.1中的UUID
工具