详解Python用UUID库生成唯一ID的点子实例,模块使用示例

此模块提供不可变的 UUID 对象 (类 uuid)
和函数uuid1()、uuid3()、uuid4()、uuid5(),

UUID介绍

 

uuid:
 uuid库是一个小的接纳工具,可以表示和生成UUID
 UUID是University Unique
Identifier的缩写,它是一个128位的数字(16字节),不要求有一个主旨认证部门就足以制造全国唯一的标示符。别名:GUID
 uuid位于名字空间boost::uuisd,没有集中的头文件,把效益疏散在了多少小文件中,因而为了选取uuid组件,须求包括数身材文件,即:
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
using namespace boost::uuids;

用于转移在 RFC 4122 中指定版本1、3、4和5UUIDs 。如若你想要的只是一个唯一

UUID是128位的大局唯一标识符,平日由32字节的字符串表示。它可以有限协理时间和空间的唯一性,也称为GUID,全名叫:UUID
―― Universally Unique IDentifier,Python 中叫 UUID。

1. 背景知识:

 

  UUID: 通用唯一标识符 ( Universally Unique Identifier ),
对于有所的UUID它可以保障在半空和岁月上的绝无仅有性. 它是透过MAC地址, 时间戳,
命名空间, 随机数, 伪随机数来担保生成ID的唯一性, 有着固定的分寸( 128 bit
).  它的唯一性和一致性特点使得可以不用注册进度就能够暴发一个新的UUID.
UUID可以被看成三种用场, 既可以用来短期内标记一个目的,
也得以可看重的分辨网络中的持久性对象. 

  为何要拔取UUID?

  很多施用场景要求一个id, 不过又不须求这一个id 有现实的意义,
仅仅用来标识一个对象. 常见的例子有多少库表的id 字段.
另一个例证是前者的种种UI库, 因为它们经常必要动态创设各类UI元素,
那些要素须要唯一的id , 那时候就要求选用UUID了. 

 

uuid还周密协理比较操作和流输入输出,七个uuid值的可比是基于字典序的,分别采纳了标准算法std
::equal()和std::lexicographical_compare().

的ID,你应该调用uuid1()或uuid4()。请小心, uuid1()可能会损害隐私,
因为它创设了一

它通过MAC地址、时间戳、命名空间、随机数、伪随机数来确保生成ID的唯一性。

2. Python的uuid模块

 

  python的uuid模块提供UUID类和函数uuid1(), uuid3(), uuid4(), uuid5()
来生成1, 3, 4, 5种种版本的UUID ( 须求留意的是:
python中没有uuid2()那个函数). 对uuid模块中最常用的多少个函数计算如下: 

  1.  uuid.uuid1([node[, clock_seq]])  :
基于大运戳

  使用主机ID, 序列号, 和当前时光来生成UUID,
可有限支撑全世界范围的绝无仅有性.
但由于应用该措施生成的UUID中蕴含有主机的网络地址,
由此恐怕危及隐衷. 该函数有七个参数, 即使 node 参数未指定, 系统将会自动调用 getnode() 函数来获得主机的硬件地址.
倘若 clock_seq
 参数未指定系统会拔取一个随意暴发的14位种类号来代替. 

  2.  uuid.uuid3(namespace, name) :
基于名字的MD5散列值

  通过测六柱预测名空间和名字的MD5散列值来生成UUID,
能够有限支撑平等命名空间中分化名字的唯一性和分歧命名空间的唯一性,
但同一命名空间的同样名字生成的UUID相同.

  4.  uuid.uuid4() : 基于自由数

亚洲必赢手机入口 ,  通过随机数来生成UUID. 使用的是伪随机数有自然的再一次几率. 

  5.  uuid.uuid5(namespace, name) :
基于名字的SHA-1散列值

详解Python用UUID库生成唯一ID的点子实例,模块使用示例。  通过测六柱预测名空间和名字的SHA-1散列值来生成UUID, 算法与 uuid.uuid3() 相同.

 

用法:
 uuid是一个很小的类,它尤其被设计为没有构造函数,可以像POD数据类型一样使用.
 uuid内部选拔一个16字节的数组data作为UUID值的储存,那几个数组是public的,因而得以自由拜访,比如拷贝或者赋值。基于data数组,uuid提供了begin()和end()的迭代器协理,可以像一个容器一样操作UUID值的各种字节。成员函数size()和静态成员函数static_size()可以收获UUID的长短,是一个固定值,大小总为16,元素类型为unsigned
char的器皿。
示例:
#include <iostream>
#include <vector>
#include <assert.h>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
using namespace boost::uuids;
using namespace std;
int main()
{
 uuid u;
 assert(uuid::static_size() == 16);
 assert(u.size() == 16);
 vector<unsigned char> v(16, 7);
 //使用正规拷贝算法
 std::copy(v.begin(), v.end(), u.begin());
 assert(u.data[0] == u.data[1] && u.data[15] ==
7);  //数组情势访问
 cout<<u<<endl;
 std::fill_n(u.data + 10, 6, 8); //标准算法fill_n间接操纵数组
 cout<<u<<endl;
 system(“pause”);
 return 0;
}

个 UUID, 其中富含统计机的互联网地址。

UUID紧要有七个算法,也就是四种办法来兑现。

3. uuid模块的超级使用办法: 

>>> import uuid

>>> # make a UUID based on the host ID and current time
>>> uuid.uuid1()
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

>>> # make a UUID using an MD5 hash of a namespace UUID and a name
>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')

>>> # make a random UUID
>>> uuid.uuid4()
UUID('16fd2706-8baf-433b-82eb-8c7fada847da')

>>> # make a UUID using a SHA-1 hash of a namespace UUID and a name
>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

>>> # make a UUID from a string of hex digits (braces and hyphens ignored)
>>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')

>>> # convert a UUID to a string of hex digits in standard form
>>> str(x)
'00010203-0405-0607-0809-0a0b0c0d0e0f'

>>> # get the raw 16 bytes of the UUID
>>> x.bytes
'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'

>>> # make a UUID from a 16-byte string
>>> uuid.UUID(bytes=x.bytes)
UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')

 

参考资料:

Python_uuid模块参考手册
: https://docs.python.org/2/library/uuid.html

UUID算法 : 

 

 uuid内部定义的枚举类型variant_type标识了UUID的变体号,表示了UUID的布局项目,成员函数variant()可以取得这些UUID的变体号.
 UUID的转变有不一样的算法,这几个算法使用枚举version_type来标识,version()函数可以拿走UUID的算法版本,uuid类能够辨别现在的有多种变化算法:
 【1】基于时间和MAC的算法(version_time_based);
 【2】分布计算环境算法(dce_security);
 【3】MD5摘要算法(version_name_based_md5);
 【4】随机数算法(version_random_number)based)
 【5】SHA1摘要算法(version_name_based_shal)
在数据极大的UUID中有一个出色的全零值nil,它意味着一个不算的UUID,成员函数is_nil()可以检测uuid是或不是是nil。
示范:uuid用于表示UUID用法的代码如下:
uuid u;
std::fill_n(u.begin(), u.size(), 0xab);
assert(!u.is_nil);
assert(u.variant() == u.variant_rfc_4122); //4122变体类型
assert(!u.version() == u.version_unknown); //生成算法未知
cout<<u<<endl;
std::memset(u.data, 0, 16);
assert(u.is_nil());
uuid u1,u2;
std::file_n(u1.begin(), u1.size(), 0xab);
std::file_n(u2.begin(), u2.size(), 0xa0);
assert(u1 != u2 && u1>u2);
u2.data[0] = 0xff; //u2的首先个字节改为0xff
assert(u1 < u2);
std::memset(u1.data, 0, 16);
std::memset(u2.data, 0, 16);
assert(u1 == u2);

顶级用法:

1

生成器:
 使用uuid提供的数组和迭代器接口,可以平昔写出自由的UUID值,但因为不行使规定的算法,手工创立的UUID值很不难重新,那种情势只适合于从其余地方得到的原始UUID值导入到uuid对象中,要是要创造属于自己的UUID,需求选用UUID生成器。
 uuid库提供了多样生成器,分别是Nil生成器,字符串生成器,名字生成器和自由生成器,它们都是函数对象,重载了operator(),可以一贯调用uuid对象.

    >>> import uuid

    # make a UUID based on the host ID and current time
    >>> uuid.uuid1()    # doctest: +SKIP
    UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

    # make a UUID using an MD5 hash of a namespace UUID and a name
    >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
    UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')

    # make a random UUID
    >>> uuid.uuid4()    # doctest: +SKIP
    UUID('16fd2706-8baf-433b-82eb-8c7fada847da')

    # make a UUID using a SHA-1 hash of a namespace UUID and a name
    >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
    UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

    # make a UUID from a string of hex digits (braces and hyphens ignored)
    >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')

    # convert a UUID to a string of hex digits in standard form
    >>> str(x)
    '00010203-0405-0607-0809-0a0b0c0d0e0f'

    # get the raw 16 bytes of the UUID
    >>> x.bytes
    b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'

    # make a UUID from a 16-byte string
    >>> uuid.UUID(bytes=x.bytes)
    UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')

uuid1()

Nil生成器:
 Nil生成器是最简便易行的UUID生成器,只好生成一个失效的UUID值,它的留存只是为着便利地意味着无效UUID。
 Nil生成器的类名是nil_generator,此外有一个内联函数nil_uuid(),相当于间接调用了Nil生成器。
示范:
 uuid u =
nil_generator()();//第一对圆括号与nil_generator()结合,结果是调用nil_generator的构造函数,生成一个暂时对象,然后第二对圆括号是nil_generator对象的operator()操作符重载,如同一个函数调用,发生了一个nil
uuid对象.
 assert(u.is_nil);
 u = nil_uuid();
 assert(u.is_nil());

来源:

――基于时间戳。由MAC地址、当前岁月戳、随机数变化。可以确保全世界限量内的唯一性,但MAC的行使同时带来安全性难点,局域网中得以选取IP来替代MAC。

字符串生成器:
 字符串生成器string_generator能够从一个字符串创造出uuid对象,字符串可以是C数组(NULL结尾),string,wstring,或者是一对迭代器指定的字符连串的距离。
 string_generator对字符串的格式有严格的需要,有三种格式是可接受的,一种是绝非连字符的全16进制数字,另一种是运用连字符,但必须符合UUID的定义,在第5,7,9,11,字节前应用连字符,其余岗位出现连字符都不一致意。UUID字符串也可以选取花括号括起来,除了花括号无法冒出16进制数以外的其余字符,否则会抛出runtime_error异常。
示范string_generator用法的代码如下:
string_generator sgen; //声明字符串生成器对象
uuid u1 = sgen(“0123456789abcdef0123456789abcdef”);
cout<<u1<<endl;
uuid u2 = sgen(“01234567-89ab-cdef-0123-456789abcdef”);
cout<<u2<<endl;
uuid u3 = sgen(L”{01234567-89ab-cdef-0123-456789abcdef}”);
cout<<u3<<endl;

1

名字生成器:
 名字生成器name_generator使用基于名字的SHA1摘要算法,它须要先指定一个基准UUID,然后选取字符串名字派生出基于这些UUID的一系列UUID,名字生成器的头角崭然的选拔场景是为一个集体内的持有成员创制UUID标识,唯有基准UUID不变,那么相同的名字总会暴发同样的UUID。
示范:name_generator用法:
//首先生成一个社团的UUID
uuid www_xxx_com =
string_generator()(“{0123456789abcdef0123456789abcdef}”);
name_generator ngen(www_xxx_com);//构造名字生成器
uuid u1 = ngen(“mario”);//为名字mario生成UUID
assert(!u1.is_nil() && u1.version() ==
uuid::version_name_based_sha1);//version是sha1算法
uuid u2 = ngen(“link”);//为名字link生成uuid
cout<<u2<<endl;

uuid2()

轻易生成器:
 随机生成器选取擅自数生成UUID,uuid库使用Boost库的另一个零部件random作为自由数的暴发源,它可以生出高质量的伪随机数,有限协助生成的随机UUID不会再也。
 随机生成器basic_random_generator是一个模板类,能够用模板参数指定要运用的自由数暴发器,具有的轻易数类可以参考random库,为了方便使用,uuid定义了一个常用的生成器random_generator,它应用mt19937作为自由数发生器。
以身作则随机生成器用法的代码:
random_generator rgen;//随机生成器
uuid u = rgen();//生成一个肆意的UUID
assert(u.version() == uuid::version_random_number_based)
cout<<u<<endl;

――基于分布式计算环境DCE(Python中从不那些函数)。算法与uuid1相同,不一样的是把时间戳的前4地点换为POSIX的UID。实际中很少用到该格局。

增强的uuid类:
 uuid类为了追求成效而尚未提供构造函数,要生成一个UUID值,必须求利用生成器,但有时这几个操作步骤显得有些麻烦,由此可以从uuid类派生一个方可自动发生uuid值的增加类,以简化uuid的使用。

1

 uuid_t,它是uuid的子类,具有uuid的漫天力量,它里面定义了多个生成器的静态成员变量,分别用来发生随机uuid和字符串uuid,对应地也提供了二种重载方式的构造函数,对于Nil生成器,uuid_t使用带int参数的构造函数来调用已毕,而名字生成器则采纳了接受uuid和字符串参数的构造函数。
 uuid_t还落到实处了八个类型转换操作符重载,可以隐式地转换uuid对象,方便被接纳在任何应用uuid类型的风貌。

uuid3()

uuid_t的总体落到实处代码:
class uuid_t:pubilc uuid
{
private:
 static random_generator rgen; //随机生成器
 static string_generator sgen;//字符串生成器
public:
 uuid_t(): uuid(rgen()){}//缺省构造函数,生成随机UUID
 uuid_t(int):uuid(nil_uuid()){}//0值的uuid构造函数
 uuid_t(const char*str):uuid(sgen(str)){}//字符串构造函数
 uuid_t(const uuid&u, const char* str)://名字生成器构造函数
  uuid(name_generator(u)(str)){}
 explicit uuid_t(const uuid& u):uuid(u){}拷贝构造函数
 operator uuid()//转换到uuid类型
 { return static_cast<uuid&>(*this);}
 operator uuid() const //常函数,转换到const uuid类型
 { return static_cast<const uuid&>(*this);}
};

――基于名字的MD5散列值。通过计算名字和命名空间的MD5散列值得到,有限扶助了扳平命名空间中不一样名字的唯一性,和见仁见智命名空间的唯一性,但一样命名空间的平等名字生成相同的uuid。

random_generator uuid_t::rgen;//静态成员变量的概念
string_generator uuid_t::sgen;

1

 由于uuid_t类封装了uuid的保有生成器,故它比uuid用起来尤其有利于容易,例如:
uuid_t u0 =0;
assert(u0.is_nil());;
uuid_t u1,u2;
cout<< u1<<endl;
cout<< u2<<endl;
uuid_t u3(“{01234567-89ab-cdef-0123-456789abcdef}”);//字符串构造
cout<<u3<<endl;
cout<< uuid_t(u3, “test name gen”)<<endl; //通过名字构造

uuid4()

与字符串的转换:
 uuid不可能一贯得到一个uuid的字符串表示,但因为uuid协助流输入输出,故可以利用std::stringstream转换为字符串,例如;
uuid u = string_generator()(“01234567-89ab-cdef-0123-456789abcdef”);
stringstream ss;
ss << u; //uuid输出到字符串流
string str;
ss>>str;//字符串流输出到字符串对象
cout<<str<<endl;

――基于随机数。由伪随机数到手,有早晚的双重几率,该几率可以总计出来。

另一个Boost库组件lexical_cast,它可以一本万利地落到实处字符串与uuid的双向转换
示例:
#include <iostream>
#include <vector>
#include <assert.h>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>
using namespace boost;
using namespace boost::uuids;
using namespace std;
int main()
{
 uuid u =
lexical_cast<uuid>(“01234567-89ab-cdef-0123-456789abcdef”);
 cout<<u<<endl;
 string str = lexical_cast<string>(u);  //uuid转换来字符串
 cout<<str<<endl;
}
 lexical_cast的字符串转换uuid的用法很接近字符串生成器string_generator,但作用要弱很多,因为lexical_cast的更换职能是基于uuid的流输入能力,因而只好承受连字符格式的字符串,而且不可能有花括号.

1

SHA1摘要算法:
 SHA1算法广泛地行使于防篡改,身份鉴定等安全注脚领域.
#include <boost/uuid/sha1.hpp>
boost::uuids::detail
shal类的用法很粗略,使用成员函数process_byte(),process_block()和process_bytes()以不用的情势把数据”喂”给shal对象,当输入所有数据后用get_digest()得到计算出的摘要值。
示例:
#include <iostream>
#include <vector>
#include <assert.h>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/uuid/sha1.hpp>
using namespace boost;
using namespace boost::uuids::detail;
using namespace std;
int main()
{
 sha1 sha;

uuid5()

 char *szMsg = “a short message”;   //用于摘要的新闻
 sha.process_byte(0x10);      //处理一个字节
 sha.process_bytes(szMsg, strlen(szMsg)); //处理多少个字节
 sha.process_block(szMsg, szMsg + strlen(szMsg));
 unsigned int digest[5];      //摘要的重临值
 sha.get_digest(digest);
 for (int i = 0; i< 5; ++i)
  cout<< hex << digest[i];    //16进制输出
}

――基于名字的SHA-1散列值。算法与uuid3等同,不一致的是利用 Secure Hash
Algorithm 1 算法。

动用示例

#! coding:utf-8

import uuid

printu”uuid1 生成基于电脑主机ID和如今光阴的UUID”

printuuid.uuid1() # UUID(‘a8098c1a-f86e-11da-bd1a-00112444be1e’)

printu”\nuuid3 基于命名空间和一个字符的MD5加密的UUID”

printuuid.uuid3(uuid.NAMESPACE_DNS,’www.dadiqp.info’)
#UUID(‘6fa459ea-ee8a-3ca4-894e-db77e160355e’)

printu”\nuuid4 随机生成一个UUID”

printuuid.uuid4() #’16fd2706-8baf-433b-82eb-8c7fada847da’

printu”\nuuid5 按照命名空间和一个字符的SHA-1加密的UUID”

uuid.uuid5(uuid.NAMESPACE_DNS,”)
#UUID(‘886313e1-3b8a-5372-9b90-0c9aee199e5d’)

printu”\n根据十六进制字符生成UUID”

x = uuid.UUID(‘{00010203-0405-0607-0809-0a0b0c0d0e0f}’)

printu”转换成十六进制的UUID表现字符”

printstr(x) #’00010203-0405-0607-0809-0a0b0c0d0e0f’

结果

uuid1 生成基于电脑主机ID和近期时间的UUID

31a936a1-2339-11e6-8542-9cb70ded607f

uuid3 基于命名空间和一个字符的MD5加密的UUID

6fa459ea-ee8a-3ca4-894e-db77e160355e

uuid4 随机生成一个UUID

67e6497c-8aec-4413-9955-da86f38ff2d6

uuid5 基于命名空间和一个字符的SHA-1加密的UUID

根据十六进制字符生成UUID

转换成十六进制的UUID表现字符

00010203-0405-0607-0809-0a0b0c0d0e0f

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图