关于UUID的二三事

点击上方 "编程技术圈"关注, 星标或置顶一起成长

后台回复“大礼包”有惊喜礼包!

每日英文

Always remember two things: Don't make any decision when you are angry. Don't make any promises when you are happy.

生活中一定要记住这两件事:不在生气时做决定,不在高兴时轻许诺言。

每日掏心话

人生就像饺子,岁月是皮,经历是馅。每个人都是孤独的个体,人生的痛苦永远多于快乐,正视人生的每一个挫折。

责编:乐乐 | 来自:沉默剑士

链接:jianshu.com/p/d77f3ef0868a

编程技术圈(ID:study_tech)第 1150 次推文 图源:百度

往日回顾:绝了!这款工具让SpringBoot不再需要Controller、Service、DAO、Mapper!

     

   正文   

一、简介

UUID,是Universally Unique Identifier的缩写,UUID出现的目的,是为了让分布式系统可以不借助中心节点,就可以生成UUID来标识一些唯一的信息;

GUID,是Globally Unique Identifier的缩写,跟UUID是同一个东西,只是来源于微软。

规范定义

UUID来自于IETF发布的一个规范:

https://www.ietf.org/rfc/rfc4122.txt

UUID来源于OSF的DCE规范,也就是RFC4122的前身

GUID来源于微软,注意RFC4122的作者之一是微软员工

下面摘录一下,RFC4144中的Abstract

This specification defines a Uniform Resource Name namespace for UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDentifier).  A UUID is 128 bits long, and can guarantee uniqueness across space and time.  UUIDs were originally used in the Apollo Network Computing System and later in the Open Software Foundation's (OSF) Distributed Computing Environment (DCE), and then in Microsoft Windows platforms.

This specification is derived from the DCE specification with the kind permission of the OSF (now known as The Open Group). Information from earlier versions of the DCE specification have been incorporated into this document.

不知道起什么标题好

1个UUID是1个16字节(128位)的数字;为了方便阅读,通常将UUID表示成如下的方式:

123e4567-e89b-12d3-a456-426655440000

1个UUID被连字符分为五段,形式为8-4-4-4-12的32个字符。

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

二、不同的版本

UUID本身也经过了多个版本的演化,每个版本的算法都不同。

标准格式

UUID的格式是这样的:xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

N那个位置,只会是8,9,a,b

M那个位置,代表版本号,由于UUID的标准实现有5个版本,所以只会是1,2,3,4,5

各个版本简介
版本1:基于时间的UUID

通过当前时间戳、机器MAC地址生成;

由于在算法中使用了MAC地址,这个版本的UUID可以保证在全球范围的唯一性。

但与此同时,因为它暴露了电脑的MAC地址和生成这个UUID的时间,这就是这个版本UUID被诟病的地方。

在python里面的使用的例子:

>>> import uuid
>>> uuid.uuid1()
UUID('444b5cc0-ae5d-11e6-8d22-28924a431726')
>>> uuid.uuid1()
UUID('46a9bf21-ae5d-11e6-9549-28924a431726')

其中,最后的12个字符28924a431726就是我电脑网卡的MAC地址

版本2:DCE安全的UUID

DCE安全的UUID和基于时间的UUID算法相同,但会把时间戳的前4位置换为POSIX的UID或GID。

在公众号顶级架构师后台回复“架构整洁”,获取一份惊喜礼包。

不过,在UUID的规范里面没有明确地指定,所以基本上所有的UUID实现都不会实现这个版本。

版本3:基于名字空间的UUID(MD5)

由用户指定1个namespace和1个具体的字符串,通过MD5散列,来生成1个UUID;

根据规范描述,这个版本的存在是为了向后兼容?平时这个版本我们也很少用到

在python里面的使用的例子:

>>> import uuid
>>> uuid.uuid3(uuid.NAMESPACE_DNS, "myString")
UUID('21fc48e5-63f0-3849-8b9d-838a012a5936')
>>> uuid.uuid3(uuid.NAMESPACE_DNS, "myString")
UUID('21fc48e5-63f0-3849-8b9d-838a012a5936')

在java中使用的例子

System.out.println(UUID.nameUUIDFromBytes("myString".getBytes("UTF-8")).toString());

Java只支持生成版本3和版本4的UUID

版本4:基于随机数的UUID

根据随机数,或者伪随机数生成UUID。这种UUID产生重复的概率是可以计算出来的,但随机的东西就像是买彩票:你指望它发财是不可能的,但狗屎运通常会在不经意中到来。这个版本应该是平时大家无意中用得最多的版本了;

在python里面使用的例子:

>>> import uuid
>>> uuid.uuid4()
UUID('e584539d-a334-4f15-9819-88d73fcf707d')
>>> uuid.uuid4()
UUID('76ec02cc-1b1d-4ad3-bd09-a4f6d67c7af4')

以及Java中大家最熟悉的:

System.out.println(UUID.randomUUID().toString());
版本5:基于名字空间的UUID(SHA1)

和版本3一样,不过散列函数换成了SHA1

在python里面的使用的例子:

>>> import uuid
>>> uuid.uuid5(uuid.NAMESPACE_DNS, "myString")
UUID('cd086011-6aac-5a06-a94a-0b67c59649ba')
>>> uuid.uuid5(uuid.NAMESPACE_DNS, "myString")
UUID('cd086011-6aac-5a06-a94a-0b67c59649ba')

三、UUID的应用

从几个版本的定义来看,感觉都不是特别完美,可能版本4是平时用得最多的,但是在现实的业务场景中,考虑到可读性、唯一性、长度,我们一般也不会选择UUID当做数据库的主键。

至于其他场景的应用,可以结合具体的场景,来使用各个版本的实现。

四、UUID和各个编程语言

  • 微软:http://msdn.microsoft.com/en-us/library/system.guid(v=vs.110).aspx

  • Linux:http://en.wikipedia.org/wiki/Util-linux

  • Android:http://developer.android.com/reference/java/util/UUID.html

  • PHP:http://php.net/manual/en/function.uniqid.php#94959

  • MySQL:http://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html#function_uuid

  • Java:http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html

  • nodejs - https://github.com/broofa/node-uuid

参考:

  • https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_3_.28MD5_hash_and_namespace.29

  • https://github.com/simongong/js-stackoverflow-highest-votes/blob/master/questions1-10/how-to-create-a-UUID-in-javascript.md

  • http://www.blogjava.net/feelyou/archive/2008/10/14/234320.html

PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

欢迎加入后端架构师交流群,在后台回复“学习”即可。

猜你还想看

阿里、腾讯、百度、华为、京东最新面试题汇集

一行代码搞定Spring Boot反爬虫,防止接口盗刷!

GitHub代码一键转VS Code:只需+1s

请马上卸载Notepad++...!

BAT等大厂Java面试经验总结

别找了,想获取 Java大厂面试题学习资料

扫下方二维码回复「手册」就好了



嘿,你在看吗

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,你可以使用以下方法获取UUID(通用唯一标识符): 方法一:使用第三方库(例如boost库)来生成UUID。 首先,确保你的C++项目中已经安装了boost库。然后,可以使用以下代码来生成UUID: ```cpp #include <boost/uuid/uuid.hpp> #include <boost/uuid/uuid_generators.hpp> #include <boost/uuid/uuid_io.hpp> int main() { boost::uuids::random_generator gen; boost::uuids::uuid uuid = gen(); std::cout << uuid << std::endl; return 0; } ``` 这段代码使用了boost库中的`random_generator`类来生成UUID,并通过`uuid()`方法获取随机生成的UUID。然后,可以通过`std::cout`输出UUID。 方法二:使用操作系统提供的API来获取UUID。 在不使用第三方库的情况下,你可以使用操作系统提供的API来获取UUID。以下是在Windows和Linux上获取UUID的示例代码: - Windows: ```cpp #include <iostream> #include <rpc.h> #pragma comment(lib, "Rpcrt4.lib") int main() { UUID uuid; UuidCreate(&uuid); unsigned char* str; UuidToStringA(&uuid, &str); std::cout << str << std::endl; RpcStringFreeA(&str); return 0; } ``` 这段代码使用了Windows提供的`UuidCreate()`函数来生成UUID,并通过`UuidToStringA()`函数将UUID转换为字符串格式,并输出。 - Linux: ```cpp #include <iostream> #include <uuid/uuid.h> int main() { uuid_t uuid; uuid_generate(uuid); char str[37]; uuid_unparse(uuid, str); std::cout << str << std::endl; return 0; } ``` 这段代码使用了Linux提供的`uuid_generate()`函数来生成UUID,并通过`uuid_unparse()`函数将UUID转换为字符串格式,并输出。 这些是获取UUID的两种常见方法,你可以根据自己的需求选择其中一种来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值