UUID 全世界的唯一id!(唯一的接口标识符)
UUID
(Universally Unique IDentifier)是一个128位数字的唯一标识。RFC 4122描述了具体的规范实现。本文尝试从它的结构一步步分析为什么它能做到唯一性?及各个版本的使用场景。
Format
UUID使用16进制表示,共有36个字符(32个字母数字+4个连接符"-"),格式为8-4-4-4-12,如:
6d25a684-9558-11e9-aa94-efccd7a0659b
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
M中使用4位来表示UUID的版本,N中使用1-3位表示不同的variant。如上面所示:M =1, N = a表示此UUID为version-1,variant-1的UUID(Time-based ECE/RFC 4122 UUID)。
但是为什么最开始说它是一个128位的唯一标识呢?这里明明字母位数是(8+4+4+4+12)*8=256位。
因为上面的字母是用的16进制,一个16进制只代表4个bit,所以应该是(8+4+4+4+12)*4=128位。
UUID使用的是大数位format(big-endian),比如:
00112233-4455-6677-8899-aabbccddeeff 编码就是 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff.
UUID现有5种版本,是根据不同的使用场景划分的,而不是根据精度,所以Version5并不会比Version1精度高,在精度上,大家都能保证唯一性,重复的概率近乎于0。
Version1(date-time MAC address)
基于时间戳及MAC地址的UUID实现。它包括了48位的MAC地址和60位的时间戳,
接下来使用ossp-uuid命令行创建5个UUID v1。(在Mac安装brew install ossp-uuid)
uuid -n 5 -v1
5b01c826-9561-11e9-9659-cb41250df352
5b01cc7c-9561-11e9-965a-57ad522dee7f
5b01cea2-9561-11e9-965b-a3d050dd0f99
5b01cf60-9561-11e9-965c-1b66505f58da
5b01d118-9561-11e9-965d-97354eb9e996
肉眼一看,有一种所有的UUID都很相似的感觉,几乎就要重复了!怎么回事?
其实v1为了保证唯一性,当时间精度不够时,会使用13~14位的clock sequence来扩展时间戳,比如:
当UUID的生产成速率太快,超过了系统时间的精度。时间戳的低位部分会每增加一个UUID就+1的操作来模拟更高精度的时间戳,换句话说,就是当系统时间精度无会区分2个UUID的时间先后时,为了保证唯一性,会在其中一个UUID上+1。所以UUID重复的概率几乎为0,时间戳加扩展的clock sequence一共有74bits,(2的74次方,约为1.8后面加22个零),即在每个节点下,每秒可产生1630亿不重复的UUID(因为只精确到了秒,不再是74位,所以换算了一下)。
相对于其它版本,v1还加入48位的MAC地址,这依赖于网卡供应商能提供唯一的MAC地址,同时也可能通过它反查到对应的MAC地址。Melissa病毒就是这样做到的。
Version2(date-time Mac address)
这是最神秘的版本,RFC没有提供具体的实现细节,以至于大部分的UUID库都没有实现它,只在特定的场景(DCE security)才会用到。所以绝大数情况,我们也不会碰到它。
Version3,5(namespace name-based)
V3和V5都是通过hash namespace的标识符和名称生成的。V3使用MD5作为hash函数,V5则使用SHA-1。
因为里面没有不确定的部分,所以当namespace与输入参数确定时,得到的UUID都是确定唯一的。比如:
uuid -n 3 -v3 ns:URL http://www.baidu.com
2f67490d-55a4-395e-b540-457195f7aa95
2f67490d-55a4-395e-b540-457195f7aa95
2f67490d-55a4-395e-b540-457195f7aa95
可以看到这3个UUID都是一样的。
具体的流程就是
把namespace和输入参数拼接在一起,如"http/http://wwwbaidu.com" ++ “/query=uuid”;
使用MD5算法对拼接后的字串进行hash,截断为128位;
把UUID的Version和variant字段都替换成固定的;
如果需要to_string,需要转为16进制和加上连接符"-"。
把V3的hash算法由MD5换成SHA-1就成了V5。
Version4(random)
这个版本使用最为广泛:
uuid -n 5 -v4
a3535b78-69dd-4a9e-9a79-57e2ea28981b
a9ba3122-d89b-4855-85f1-92a018e5c457
7c59d031-a143-4676-a8ce-1b24200ab463
533831da-eab4-4c7d-a3f6-1e2da5a4c9a0
def539e8-d298-4575-b769-b55d7637b51e
其中4位代表版本,2-3位代表variant。余下的122-121位都是全部随机的。即有2的122次方(5.3后面36个0)个UUID。一个标准实现的UUID库在生成了2.71万亿个UUID会产生重复UUID的可能性也只有50%的概率
这相当于每秒产生10亿的UUID,持续85年,而把这些UUID都存入文件,每个UUID占16bytes,总需要45 EB(exabytes),比目前最大的数据库(PB)还要大很多倍。
Summary
如果只是需要生成一个唯一ID,你可以使用V1或V4。
V1基于时间戳和Mac地址,这些ID有一定的规律(你给出一个,是有可能被猜出来下一个是多少的),而且会暴露你的Mac地址。
V4是完全随机(伪)的。
如果对于相同的参数需要输出相同的UUID,你可以使用V3或V5。V3基于MD5 hash算法,如果需要考虑与其它系统的兼容性的话,就用它,因为它出来得早,大概率大家都是用它的。
V5基于SHA-1 hash算法,这个是首选。
UUID 全世界的唯一id!(唯一的接口标识符)相关推荐
- Android Q 获取设备唯一ID(UDID\GUID\UUID\SSAID\GAID)
Android Q获取设备唯一ID(UDID\GUID\UUID\SSAID\GAID) 一.简介 1.1 问题背景 1.2 关键技术 二.解决方案 2.1 谷歌官方推荐方案 (4种) 2.2 实现方 ...
- 10.算法进阶之分布式篇——分布式环境下如何生成唯一ID——UUID
UUID--全局唯一ID--universally unique identifie. 一般来说常用的基于时间进行排序,因为时间是自然递增的.但是全局唯一ID的两个核心要求是: 全局唯一 粗略有序 在 ...
- JS生成唯一id方式介绍(UUID和NanoID)
记录下JS生成唯一id的方法. 1.生成uuid的方法 方法一: function guid() {return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.repl ...
- java获取imei_Android10 获取IMEI,获取UUID,唯一ID
Andorid10无法获取IMEI,读写文件也被限制. 获取设备唯一ID逻辑. 如果Android10以上 -> 在设备的外部目录创建UUID,只要用户没有手动删除该文件UUID一直存在. 如果 ...
- 通用唯一识别码(uuid):吃透id随便搞
Index v4 高64位 mostSigBits 低64位 leastSigBits v3 高64位 mostSigBits 低64位 leastSigBits v1 高64位 mostSigBit ...
- Java分布式唯一ID生成方案——比UUID效率更高的生成id工具类
package com.xinyartech.erp.core.util;import java.lang.management.ManagementFactory; import java.net. ...
- 全局唯一ID发号器的几个思路
标识(ID / Identifier)是无处不在的,生成标识的主体是人,那么它就是一个命名过程,如果是计算机,那么它就是一个生成过程.如何保证分布式系统下,并行生成标识的唯一与标识的命名空间有着密不可 ...
- Redis之String应用场景与SpringCache--存储对象信息、分布式唯一ID、文章阅读量、Lua脚本
String应用场景 一.存储对象信息 代码 重写Redis序列 解决方式 剖析SpringCache常用注解 @CacheConfig @Cacheable @CachePut @CacheEvic ...
- 一线大厂的分布式唯一ID生成方案是什么样的?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 一.前言 分布式系统中我们会对一些数据量大的业务进行分拆,如:用户 ...
最新文章
- pandas中align函数的使用示例
- Unet论文解读代码解读
- liux 常用操作命令
- 如何将索引碎片数量降至最低
- zuc算法代码详解_最短路算法-dijkstra代码与案例详解
- 《电子元器件的可靠性》——3.7节电子元器件失效率鉴定试验
- (考勤记录导出教程)指纹考勤机科密C21
- 互联网知识变现,不起眼利润高的冷门行业有哪些?
- 关于小米驱动程序的问题
- Leetcode刷题100天—347. 前 K 个高频元素(优先队列)—day16
- 记录微信分享图标不显示的问题
- 《愤怒的小鸟2》上线华为应用市场;罗克韦尔自动化将以22.2亿美元收购Plex;优克联与伦敦合作伙伴签署分销协议 | 全球TMT...
- 使用牛顿迭代法求根 一元三次方程的根
- 初学开关电源设计全过程笔记
- 痛与快乐有一个代码是什么_痛苦与快乐
- 希腊字母常用指代意义及其中英文读音
- 【必拿下系列】106. 从中序与后序遍历序列构造二叉树105从前序与中序遍历序列构造二叉树
- python 保障系统(一)
- 【外汇天眼】MT4 vs MT5:哪个更适合外汇初学者
- 怎么在mac下运行映像dmg_Mac制作dmg镜像重新安装系统方法
热门文章
- sqlbench:一个测量和比较 SQL 语句执行效率的工具
- UVCCamera实现USB摄像头Android的APP
- qq撤回的信息腾讯服务器有吗,腾讯官方:撤回消息为何提示对方?丨QQ新增自定义撤回消息~...
- 省选专练川渝友谊考试S10礼物gift
- 【SVM回归预测】基于matlab粒子群算法优化SVM回归预测【含Matlab源码 1424期】
- Linux中tail与cat的区别
- python 化学工程_学化工的出路在哪儿?
- 牛刀小试(四)——较完善的购物系统
- 由于内存不够导致clickhouse节点无法启动
- RAM与ROM程序执行速度