C++ UUID库
库名 libuuid 下载地址https://sourceforge.net/projects/libuuid/
版本1.0.3
运行环境:mac
接口
uuid对外定义为一个无符号字符数组,这是一个压缩后的存储
typedef unsigned char uuid_t[16];
内部其实是一个结构体
struct uuid {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint16_t clock_seq;
uint8_t node[6];
};
time_low是一个32位整数,每8位转化成一个无符号字符,占了前面4位,然后是time_mid占2位,time_hi_and_version占2位,clock_seq占2位,最后node数组占6位,一共正好16位。
提供4个函数生成不同的uuid
- uuid_generate_random 如果有随机设备则利用随机设备生产随机字符串流,否则利用glibc的伪随机函数生成,然后对clock_seq和time_hi_and_version做一些位操作(为什么?)
- uuid_generate_time 和random一样生成随机字符串,然后对clock_seq,然后对clock_sql,time_mid和time_hi_and_version进行位操作
- uuid_generate 根据系统是否提供/dev/random或/dev/urandom伪随机设备,来决定用random还是time构造uuid,linux系统一般提供
- uuid_generate_time_safe 调用了uuid_generate_time_generic,内部使用uuid daemon生成uuid
几个函数获取uuid内部的属性:
- uuid_time 获取基于时间的uuid的时间值
- uuid_type 返回时间或随机
- uuid_variant 返回平台
构造和打印uuid的函数:
- uuid_unparse 把uuid buf解析成字符串
- uuid_unparse_lower
- uuid_unparse_upper
- uuid_parse 把一个字符串解析成uuid
操作uuid的几个函数:
- uuid_compare
- uuid_clear
- uuid_copy
- uuid_is_null
从名字就可以看出用途,后续给出源码中的test代码。
源码
接口
/* clear.c */
void uuid_clear(uuid_t uu);
/* compare.c */
int uuid_compare(const uuid_t uu1, const uuid_t uu2);
/* copy.c */
void uuid_copy(uuid_t dst, const uuid_t src);
/* gen_uuid.c */
void uuid_generate(uuid_t out);
void uuid_generate_random(uuid_t out);
void uuid_generate_time(uuid_t out);
int uuid_generate_time_safe(uuid_t out);
/* isnull.c */
int uuid_is_null(const uuid_t uu);
/* parse.c */
int uuid_parse(const char *in, uuid_t uu);
/* unparse.c */
void uuid_unparse(const uuid_t uu, char *out);
void uuid_unparse_lower(const uuid_t uu, char *out);
void uuid_unparse_upper(const uuid_t uu, char *out);
/* uuid_time.c */
time_t uuid_time(const uuid_t uu, struct timeval *ret_tv);
int uuid_type(const uuid_t uu);
int uuid_variant(const uuid_t uu);
源码中包含的test代码:
#include <stdio.h>
#include <stdlib.h>
#include "uuid.h"
static int test_uuid(const char * uuid, int isValid)
{
static const char * validStr[2] = {"invalid", "valid"};
uuid_t uuidBits;
int parsedOk;
parsedOk = uuid_parse(uuid, uuidBits) == 0;
printf("%s is %s", uuid, validStr[isValid]);
if (parsedOk != isValid) {
printf(" but uuid_parse says %s\n", validStr[parsedOk]);
return 1;
}
printf(", OK\n");
return 0;
}
int
main(int argc ATTR((unused)) , char **argv ATTR((unused)))
{
uuid_t buf, tst;
char str[100];
struct timeval tv;
time_t time_reg;
unsigned char *cp;
int i;
int failed = 0;
int type, variant;
uuid_generate(buf);
uuid_unparse(buf, str);
printf("UUID generate = %s\n", str);
printf("UUID: ");
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
printf("%02x", *cp++);
}
printf("\n");
type = uuid_type(buf); variant = uuid_variant(buf);
printf("UUID type = %d, UUID variant = %d\n", type, variant);
if (variant != UUID_VARIANT_DCE) {
printf("Incorrect UUID Variant; was expecting DCE!\n");
failed++;
}
printf("\n");
uuid_generate_random(buf);
uuid_unparse(buf, str);
printf("UUID random string = %s\n", str);
printf("UUID: ");
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
printf("%02x", *cp++);
}
printf("\n");
type = uuid_type(buf); variant = uuid_variant(buf);
printf("UUID type = %d, UUID variant = %d\n", type, variant);
if (variant != UUID_VARIANT_DCE) {
printf("Incorrect UUID Variant; was expecting DCE!\n");
failed++;
}
if (type != 4) {
printf("Incorrect UUID type; was expecting "
"4 (random type)!\n");
failed++;
}
printf("\n");
uuid_generate_time(buf);
uuid_unparse(buf, str);
printf("UUID string = %s\n", str);
printf("UUID time: ");
for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
printf("%02x", *cp++);
}
printf("\n");
type = uuid_type(buf); variant = uuid_variant(buf);
printf("UUID type = %d, UUID variant = %d\n", type, variant);
if (variant != UUID_VARIANT_DCE) {
printf("Incorrect UUID Variant; was expecting DCE!\n");
failed++;
}
if (type != 1) {
printf("Incorrect UUID type; was expecting "
"1 (time-based type)!\\n");
failed++;
}
tv.tv_sec = 0;
tv.tv_usec = 0;
time_reg = uuid_time(buf, &tv);
printf("UUID time is: (%ld, %ld): %s\n", tv.tv_sec, tv.tv_usec,
ctime(&time_reg));
uuid_parse(str, tst);
if (!uuid_compare(buf, tst))
printf("UUID parse and compare succeeded.\n");
else {
printf("UUID parse and compare failed!\n");
failed++;
}
uuid_clear(tst);
if (uuid_is_null(tst))
printf("UUID clear and is null succeeded.\n");
else {
printf("UUID clear and is null failed!\n");
failed++;
}
uuid_copy(buf, tst);
if (!uuid_compare(buf, tst))
printf("UUID copy and compare succeeded.\n");
else {
printf("UUID copy and compare failed!\n");
failed++;
}
failed += test_uuid("84949cc5-4701-4a84-895b-354c584a981b", 1);
failed += test_uuid("84949CC5-4701-4A84-895B-354C584A981B", 1);
failed += test_uuid("84949cc5-4701-4a84-895b-354c584a981bc", 0);
failed += test_uuid("84949cc5-4701-4a84-895b-354c584a981", 0);
failed += test_uuid("84949cc5x4701-4a84-895b-354c584a981b", 0);
failed += test_uuid("84949cc504701-4a84-895b-354c584a981b", 0);
failed += test_uuid("84949cc5-470104a84-895b-354c584a981b", 0);
failed += test_uuid("84949cc5-4701-4a840895b-354c584a981b", 0);
failed += test_uuid("84949cc5-4701-4a84-895b0354c584a981b", 0);
failed += test_uuid("g4949cc5-4701-4a84-895b-354c584a981b", 0);
failed += test_uuid("84949cc5-4701-4a84-895b-354c584a981g", 0);
if (failed) {
printf("%d failures.\n", failed);
exit(1);
}
return 0;
}
运行命令:gcc test_uuid.c -I uuid.h .libs/libuuid.a
输出结果
UUID generate = dda308b8-92b7-425e-a0e9-5d3549b0a21d
UUID: dda308b892b7425ea0e95d3549b0a21d
UUID type = 4, UUID variant = 1
UUID random string = 5351ce55-18d0-4559-874e-db90d56a85a5
UUID: 5351ce5518d04559874edb90d56a85a5
UUID type = 4, UUID variant = 1
UUID string = dfb68e3a-39f6-11e7-ac17-555bc85646d4
UUID time: dfb68e3a39f611e7ac17555bc85646d4
UUID type = 1, UUID variant = 1
UUID time is: (1494911813, 611065): Tue May 16 13:16:53 2017
UUID parse and compare succeeded.
UUID clear and is null succeeded.
UUID copy and compare succeeded.
84949cc5-4701-4a84-895b-354c584a981b is valid, OK
84949CC5-4701-4A84-895B-354C584A981B is valid, OK
84949cc5-4701-4a84-895b-354c584a981bc is invalid, OK
84949cc5-4701-4a84-895b-354c584a981 is invalid, OK
84949cc5x4701-4a84-895b-354c584a981b is invalid, OK
84949cc504701-4a84-895b-354c584a981b is invalid, OK
84949cc5-470104a84-895b-354c584a981b is invalid, OK
84949cc5-4701-4a840895b-354c584a981b is invalid, OK
84949cc5-4701-4a84-895b0354c584a981b is invalid, OK
g4949cc5-4701-4a84-895b-354c584a981b is invalid, OK
84949cc5-4701-4a84-895b-354c584a981g is invalid, O
使用
./configure,make编译
简单代码示例:
#include
#include "uuid.h"
using namespace std;
int main(int argc, char* argv[])
{
uuid_t id1;
char str[100];
/* 生成uuid */
uuid_generate(id1);
uuid_unparse(id1, str);
cout << str << endl;
return 0;
}
编译:clang++ check.cpp -I uuid.h .libs/libuuid.a
Comments