4.10.3 生成器
使用uuid提供的数组和迭代器接口,我们可以直接写出任意的UUID值,但因为不使用规定的算法,手工创建的UUID值很容易重复。这种方式只适合于从其他地方获得的原始UUID值导入到uuid对象中,如果要创建属于自己的UUID,我们需要使用UUID生成器。
uuid库提供了四种生成器,分别是Nil生成器、字符串生成器、名字生成器和随机生成器。它们都是函数对象,重载了operator(),可以直接调用生成uuid对象。
Nil生成器
Nil生成器是最简单的UUID生成器,只能生成一个无效的UUID值(即全零的UUID),它的存在只是为了方便地表示无效UUID。
Nil生成器的类名是nil_generator,另外有一个内联函数nil_uuid(),相当于直接调用了Nil生成器。
示范Nil生成器用法的代码如下:
- uuid u = nil_generator()();
- assert(u.is_nil());
-
- u = nil_uuid();
- assert(u.is_nil());
注意:代码的第一行,在nil_generator类名后面出现了两对圆括号,不熟悉函数对象的读者可能会不太理解。它的语义解析是:第一对圆括号与nil_generator结合,结果是调用nil_generator的构造函数,生成一个临时对象,然后第二对圆括号是nil_generator对象的operator()操作符重载,就像是一个函数调用,产生了一个nil uuid对象。
字符串生成器
字符串生成器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;
名字生成器
名字生成器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() && //version是sha1算法
- u1.version() == uuid::version_name_based_sha1);
- uuid u2 = ngen("link"); //为名字link生成UUID
- cout << u2 << endl;
随机生成器
随机生成器采用随机数生成UUID,uuid库使用Boost库的另一个组件random(参见9.4节,第357页)作为随机数的发生源,它可以产生高质量的伪随机数,保证生成的随机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;