• boost 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;

    uuid还全面支持比较操作和流输入输出,两个uuid值的比较是基于字典序的,分别使用了标准算法std
    ::equal()和std::lexicographical_compare().

    用法:
     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内部定义的枚举类型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);

    生成器:
     使用uuid提供的数组和迭代器接口,可以直接写出任意的UUID值,但因为不使用规定的算法,手工创建的UUID值很容易重复,这种方式只适合于从其他地方获得的原始UUID值导入到uuid对象中,如果要创建属于自己的UUID,需要使用UUID生成器。
     uuid库提供了四种生成器,分别是Nil生成器,字符串生成器,名字生成器和随机生成器,它们都是函数对象,重载了operator(),可以直接调用uuid对象.

    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());

    字符串生成器:
     字符串生成器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() && u1.version() == uuid::version_name_based_sha1);//version是sha1算法
    uuid u2 = ngen("link");//为名字link生成uuid
    cout<<u2<<endl;

    随机生成器:
     随机生成器采用随机数生成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;

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

     uuid_t,它是uuid的子类,具有uuid的全部能力,它内部定义了两个生成器的静态成员变量,分别用来产生随机uuid和字符串uuid,对应地也提供了两种重载形式的构造函数,对于Nil生成器,uuid_t使用带int参数的构造函数来调用实现,而名字生成器则使用了接受uuid和字符串参数的构造函数。
     uuid_t还实现了两个类型转换操作符重载,可以隐式地转换uuid对象,方便被应用在其他使用uuid类型的场景。

    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);}
    };

    random_generator uuid_t::rgen;//静态成员变量的定义
    string_generator uuid_t::sgen;

     由于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; //通过名字构造

    与字符串的转换:
     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的流输入能力,因此只能接受连字符格式的字符串,而且不能有花括号.

    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;

     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进制输出
    }

  • 相关阅读:
    HDU 4278 Faulty Odometer 8进制转10进制
    hdu 4740 The Donkey of Gui Zhou bfs
    hdu 4739 Zhuge Liang's Mines 随机化
    hdu 4738 Caocao's Bridges tarjan
    Codeforces Gym 100187M M. Heaviside Function two pointer
    codeforces Gym 100187L L. Ministry of Truth 水题
    Codeforces Gym 100187K K. Perpetuum Mobile 构造
    codeforces Gym 100187J J. Deck Shuffling dfs
    codeforces Gym 100187H H. Mysterious Photos 水题
    windows服务名称不是单个单词的如何启动?
  • 原文地址:https://www.cnblogs.com/lidabo/p/3897297.html
Copyright © 2020-2023  润新知