什么是UUID?

UUID是Universally Unique Identifier的缩写,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符。UUID具有以下涵义:

  • 经由一定的算法机器生成

为了保证UUID的唯一性,规范定义了包括网卡MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素,以及从这些元素生成UUID的算法。UUID的复杂特性在保证了其唯一性的同时,意味着只能由计算机生成。

  • 非人工指定,非人工识别

UUID是不能人工指定的,除非你冒着UUID重复的风险。UUID的复杂性决定了“一般人“不能直接从一个UUID知道哪个对象和它关联。

  • 在特定的范围内重复的可能性极小

UUID的生成规范定义的算法主要目的就是要保证其唯一性。但这个唯一性是有限的,只在特定的范围内才能得到保证,这和UUID的类型有关(参见UUID的版本)。

UUID是16字节128位长的数字,通常以36字节的字符串表示,示例如下:

3F2504E0-4F89-11D3-9A0C-0305E82C3301

其中的字母是16进制表示,大小写无关。

Universally Unique IDentifier(UUID),有着正儿八经的RFC规范,是一个128bit的数字,也可以表现为32个16进制的字符,中间用”-”分割。

- 时间戳+UUID版本号,分三段占16个字符(60bit+4bit),
- Clock Sequence号与保留字段,占4个字符(13bit+3bit),
- 节点标识占12个字符(48bit),

GUID(Globally Unique Identifier)是UUID的别名;但在实际应用中,GUID通常是指微软实现的UUID。

UUID的版本

UUID具有多个版本,每个版本的算法不同,应用范围也不同。

首先是一个特例--Nil UUID--通常我们不会用到它,它是由全为0的数字组成,如下:

00000000-0000-0000-0000-000000000000

UUID Version 1:基于时间的UUID

因为时间戳有满满的60bit,所以可以尽情花,以100纳秒为1,从1582年10月15日算起(能撑3655年,真是位数多给烧的,1582年有意思么)

节点标识也有48bit,一般用MAC地址表达,如果有多块网卡就随便用一块。如果没网卡,就用随机数凑数,或者拿一堆尽量多的其他的信息,比如主机名什么的,拼在一起再hash一把。

顺序号这16bit则仅用于避免前面的节点标示改变(如网卡改了),时钟系统出问题(如重启后时钟快了慢了),让它随机一下避免重复。

但好像Version 1就没考虑过一台机器上起了两个进程这类的问题,也没考虑相同时间戳的并发问题,所以严格的Version1没人实现,接着往下看各个变种吧。

Version1变种 – Hibernate

Hibernate的CustomVersionOneStrategy.java,解决了之前version 1的两个问题

- 时间戳(6bytes, 48bit):毫秒级别的,从1970年算起,能撑8925年….
- 顺序号(2bytes, 16bit, 最大值65535): 没有时间戳过了一秒要归零的事,各搞各的,short溢出到了负数就归0。
- 机器标识(4bytes 32bit): 拿localHost的IP地址,IPV4呢正好4个byte,但如果是IPV6要16个bytes,就只拿前4个byte。
- 进程标识(4bytes 32bit): 用当前时间戳右移8位再取整数应付,不信两条线程会同时启动。

值得留意就是,机器进程和进程标识组成的64bit Long几乎不变,只变动另一个Long就够了。

Version1变种 – MongoDB

MongoDB的ObjectId.java

- 时间戳(4 bytes 32bit): 是秒级别的,从1970年算起,能撑136年。

- 自增序列(3bytes 24bit, 最大值一千六百万): 是一个从随机数开始(机智)的Int不断加一,也没有时间戳过了一秒要归零的事,各搞各的。因为只有3bytes,所以一个4bytes的Int还要截一下后3bytes。

- 机器标识(3bytes 24bit): 将所有网卡的Mac地址拼在一起做个HashCode,同样一个int还要截一下后3bytes。搞不到网卡就用随机数混过去。

- 进程标识(2bytes 16bits):从JMX里搞回来到进程号,搞不到就用进程名的hash或者随机数混过去。

可见,MongoDB的每一个字段设计都比Hibernate的更合理一点,比如时间戳是秒级别的。总长度也降到了12 bytes 96bit,但如果果用64bit长的Long来保存有点不上不下的,只能表达成byte数组或16进制字符串。

另外对Java版的driver在自增序列那里好像有bug。

Twitter的snowflake派号器

snowflake也是一个派号器,基于Thrift的服务,不过不是用redis简单自增,而是类似UUID version1,

只有一个Long 64bit的长度,所以IdWorker紧巴巴的分配成:

- 时间戳(42bit) 自从2012年以来(比那些从1970年算起的会过日子)的毫秒数,能撑139年。
- 自增序列(12bit,最大值4096), 毫秒之内的自增,过了一毫秒会重新置0。
- DataCenter ID (5 bit, 最大值32),配置值。
- Worker ID ( 5 bit, 最大值32),配置值,因为是派号器的id,所以一个数据中心里最多32个派号器就够了,还会在ZK里做下注册。

可见,因为是派号器,把机器标识和进程标识都省出来了,所以能够只用一个Long表达。

另外,这种派号器,client每次只能一个ID,不能批量取,所以额外增加的延时是问题。

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使用方法

#生成基于计算机主机ID和当前时间的UUID
print(uuid.uuid1())
#基于命名空间和一个字符的MD5加密的UUID
print(uuid.uuid3(uuid.NAMESPACE_DNS,'alaji'))
#随机生成一个UUID
print(uuid.uuid4())
#基于命名空间和一个字符的SHA-1加密的UUID
print(uuid.uuid5(uuid.NAMESPACE_DNS,'alaji'))#需要转换成str类型,下面说明

结果

98345eb4-da04-11e8-9133-54ab3a0caf8d
171898c7-77dd-3258-99f8-41664402c08a
31d7df8f-cb78-41aa-bd4b-b73db34f9358
a08d35bf-65b8-558f-beea-369294bebbd8

UUID是128位的全局唯一标识符,通常由32字节的字符串表示。它可以保证时间和空间的唯一性,也称为GUID,全称为:UUID —— Universally Unique IDentifier,Python 中叫 UUID。
它通过MAC地址、时间戳、命名空间、随机数、伪随机数来保证生成ID的唯一性。
UUID主要有五个算法,也就是五种方法来实现。

  • uuid1()——基于时间戳。由MAC地址、当前时间戳、随机数生成。可以保证全球范围内的唯一性,但MAC的使用同时带来安全性问题,局域网中可以使用IP来代替MAC。
  • uuid2()——基于分布式计算环境DCE(Python中没有这个函数)。算法与uuid1相同,不同的是把时间戳的前4位置换为POSIX的UID。实际中很少用到该方法。
  • uuid3()——基于名字的MD5散列值。通过计算名字和命名空间的MD5散列值得到,保证了同一命名空间中不同名字的唯一性,和不同命名空间的唯一性,但同一命名空间的同一名字生成相同的uuid。
  • uuid4()——基于随机数。由伪随机数得到,有一定的重复概率,该概率可以计算出来。
  • uuid5()——基于名字的SHA-1散列值。算法与uuid3相同,不同的是使用 Secure Hash Algorithm 1 算法。
 

 

转载于:https://www.cnblogs.com/HUIWANG/p/11133765.html

UUID介绍与生成的方法相关推荐

  1. UUID介绍与生成方法

    什么是UUID? UUID是Universally Unique Identifier的缩写,它是在一定的范围内(从特定的名字空间到全球)唯一的机器生成的标识符.UUID具有以下涵义: 经由一定的算法 ...

  2. UUID/GUID介绍、生成规则及生成代码

    UUID/GUID介绍.生成规则及生成代码 1. UUID介绍 1.1 介绍 1.2 UUID优势 1.3 UUID劣势 2. UUID版本 2.1 版本1 - 基于时间的UUID 2.1.1优点 2 ...

  3. UUID介绍与使用范围

    最近再做存储Multipath 以及/etc/fstab挂载得时候遇到需要查询磁盘得uuid得情况,查找到如下得信息,可以提供一起学习,交流 前言介绍 描述:通用唯一识别码(英语:Universall ...

  4. RocketMQ 介绍 msgId生成算法

    我们用RocketMQ发送信息的时候通常都会返回如下信息: SendResult [sendStatus=SEND_OK, msgId=0A42333A0DC818B4AAC246C290FD0000 ...

  5. Python uuid 介绍

    1. 背景知识: UUID: 通用唯一标识符 ( Universally Unique Identifier ), 对于所有的UUID它可以保证在空间和时间上的唯一性. 它是通过MAC地址, 时间戳, ...

  6. Java中使用UUID工具类生成唯一标志防止重复

    场景 UUID 是指Universally Unique Identifier,翻译为中文是通用唯一识别码,UUID 的目的是让分布式系统中的所有元素都能有唯一的识别信息. 在某些场景下需要给数据库中 ...

  7. 直播 | 清华大学关健:利用自监督学习的开放端故事生成评价方法

    「AI Drive」是由 PaperWeekly 和 biendata 共同发起的学术直播间,旨在帮助更多的青年学者宣传其最新科研成果.我们一直认为,单向地输出知识并不是一个最好的方式,而有效地反馈和 ...

  8. php yii把pdf转成图片,yii实现图片上传及缩略图生成的方法

    这篇文章主要介绍了yii实现图片上传及缩略图生成的方法,详细分析了图片的上传及缩略图的生成原理与实现方法,是非常实用的技巧,需要的朋友可以参考下 本文实例讲述了利用yii框架来实现图片上传功能并在上传 ...

  9. uuid java 重复_Java中使用UUID工具类生成唯一标志防止重复

    import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.secur ...

最新文章

  1. 负载均衡技术中的真集群和伪集群
  2. 解决WAS报错SRVE0207E: servlet 创建了未捕获到的初始化异常
  3. python 堆_面试再问你什么是堆和栈,你就把这篇文章甩给他
  4. (计算机组成原理题目题型总结)第四章:指令系统
  5. 原生开发什么意思_什么是原生开发?什么是混合开发?两者有什么区别?
  6. Java编程风格与命名规范整理(转载)
  7. 网页设计如何排成一列_学习DIV+CSS网页布局之一列布局
  8. CMU 15-213 Introduction to Computer Systems学习笔记(4) Machine-Level Programming-Basic
  9. 打印机服务器启用后自动关闭,Win7打印机服务自动关闭了怎么打开|Win7打开打印机服务的简单方法...
  10. win7 计算机刷新dns,win7系统刷新DNS缓存的操作方法
  11. vlan和静态路由配置实验
  12. java verbose gc_java –verbose:gc
  13. Springer的latex压缩包上传转不了pdf
  14. springboot - vue-element-admin 整合,修改原有的登录退出
  15. mysql8 内存设置_高性能的MySQL(8)优化服务器配置一内存
  16. ubuntu 1604 修改mac地址
  17. 60天月活破亿,ChatGPT之父传奇:16岁出柜,20岁和男友一同当上CEO
  18. 索赔cs1.6最新服务器,《cs1.6》最新刷服补丁
  19. Shockwave Flash可能正忙
  20. 基于.NET 5实现的开源通用权限管理平台

热门文章

  1. Ubuntu安装Nginx+PHP+Memcache+Mysql指导手册
  2. XHProf安装使用笔记
  3. github snap android,GitHub - albuer/heapsnap: HeapSnap 是一个定位内存泄露的工具,适用于Android平台。...
  4. python详细安装步骤-Python的详细安装步骤
  5. python要不要装pycharm-python安装教程 Pycharm安装详细教程
  6. python入门指南bl-Vue 3 高阶指南之 Map
  7. python读数据-python读取各种文件数据方法解析
  8. 熟练掌握python是什么概念-Quant面试时说:熟练掌握Python,请三思,不然凉凉~
  9. python爬虫程序实例-10个python爬虫入门实例
  10. 学好python需要什么基础-自学Python需要怎样的基础和准备