娄二

Keep Hungry

UUID

转载于: https://blog.csdn.net/muclenerd/article/details/53171764 感谢作者

UUID是什么?

UUID,通用唯一识别码,由以下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),UUID的唯一缺陷在于生成的结果串会比较长

UUID具有以下涵义:

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

    非人工指定,非人工识别
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的生成方法,整理如下

Shell

  • Unix/Linux环境中大都有一个名为uuidgen的小工具,运行即可生成一个UUID到标准输出
  • 读取文件/proc/sys/kernel/random/uuid即得UUID,例如:

    cat /proc/sys/kernel/random/uuid
    

libuuid

libuuid是一个用于生成UUID的C库,具体用法参考http://linux.die.net/man/3/libuuid,示例如下:

#include <stdio.h>
#include <uuid/uuid.h>

int main(int argc, char **argv)
{
    uuid_t uuid;
    char str[36];

    uuid_generate(uuid);
    uuid_unparse(uuid, str);

    printf("%s\n", str);

    return 0;
}

在Linux下编译时需要链接uuid库

gcc -o uuid uuid.c -luuid
centOS下编译,记得先安装对应的库,避免报错: #include <uuid/uuid.h> 找不到

sudo yum install e2fsprogs-devel
sudo yum install uuid-devel
sudo yum install libuuid-devel

在Ubuntu中,可以用下面的命令安装libuuid:

sudo apt-get install uuid-dev

boost uuid

Boost库是一个可移植的开源C++库,它提供了UUID的实现。

下面的代码可以生成一个UUID

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>

boost::uuids::uuid a_uuid = boost::uuids::random_generator();

Qt QUuid

Qt是一个跨平台的C++编程框架,QUuid类实现了UUID的生成、比较、转换等功能。

函数QUuid createUuid();可用于生成一个随即UUID。示例如下:

#include <iostream>
#include <QUuid>
#include <QString>

int main()
{
    QUuid uuid = QUuid::createUuid();
    std::cout << qPrintable(uuid.toString()) << std::endl;
    return 0;
}

CoCreateGuid

Windows下提供了函数CoCreateGuid用于生成GUID。需要使用的头文件是”objbase.h”,需要链接的库是ole32.lib,函数原型为:

HRESULT CoCreateGuid(GUID *pguid);

GUID的原型为

typedef struct _GUID
{
    DWORD Data1;
    WORD Data2;
    WORD Data3;
    BYTE Data4[8];
} GUID;

Java

JDK 1.5以上支持UUID,用法如下:

import java.util.UUID;
String uuid = UUID.randomUUID().toString();
阅读更多
个人分类: JAVAWEB
想对作者说点什么? 我来说一句

蓝牙的uuid标准

2017年12月15日 855KB 下载

简单的uuid生产代码

2011年01月18日 358B 下载

js生成UUID

2018年04月23日 3KB 下载

Java生成UUID使用的第三方包

2009年03月24日 18KB 下载

uuid生成工具类

2018年03月23日 5KB 下载

uuid生成器

2015年02月27日 119KB 下载

UUID封装直接调用

2016年06月16日 38KB 下载

蓝牙模块功能的实现

2015年11月07日 906KB 下载

没有更多推荐了,返回首页

不良信息举报

UUID

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭