宏日志和UUID

一个简单的宏日志,C++生成UUID

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define LDBG 0
#define LINF 1
#define LERR 2

#define LDEFAULT LDBG

#define LOG(level, format, ...) \
{ \
if (level >= LDEFAULT) \
{ \
time_t t = time(NULL); \
struct tm *lt = localtime(&t); \
char time_tmp[32] = {0}; \
strftime(time_tmp, 31, "%m-%d %T", lt); \
printf(stdout, "[%s][%s:%d] " format "\n", time_tmp, __FILE__, __LINE__, ##__VA_ARGS__); \
} \
}
#define DLOG(format, ...) LOG(LDBG, format, ##__VA_ARGS__);
#define ILOG(format, ...) LOG(LINF, format, ##__VA_ARGS__);
#define ELOG(format, ...) LOG(LERR, format, ##__VA_ARGS__);
  • #include <ctime>
    包含处理日期和时间的库,用于获取当前时间和格式化时间。

  • time_t t = time(NULL);:获取当前时间。

  • char time_tmp[32] = { 0 };:初始化一个字符数组,用于存储格式化后的时间字符串。

    • strftime(time_tmp,sizeof(time_tmp), "%m-%d %H:%M:%S", lt);:使用 strftime 函数将时间格式化为 "MM-DD HH:MM:SS" 的形式,并存入 time_tmp 数组。

    • 函数原型:size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);

`

  • format, …:这是一个带有可变参数的宏,format 是一个格式化字符串,…` 表示可以接受任意数量的参数(可变参数)。

  • __FILE__, __LINE__分别代表文件位置和哪一行。

  • ##__VA_ARGS__:可变参数,用于替换用户传入的其他参数。## 的作用是当可变参数为空时,删除前面的逗号。

UUID

UUID(Universally Unique Identifier)

  • 别名:通用唯一识别码
  • 组成:通常由32位16进制字符构成
  • 标准形式
    • 包含32个16进制数字字符
    • 以连字号分为五段,格式为8-4-4-4-12——十六进制位数,共32个字符
    • 示例:550e8400-e29b-41d4-a716-446655440000

生成UUID生成方法之一

  • 采用生成8个随机数字8字节序号相结合的方式,16字节数组⽣成32位16进制字符的组合形式来确保全局唯⼀的同时能够根据序号来分辨数据
    • 生成8个随机数 —— 每个随机数最多

生成方法 —— CPP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

#include <iostream>
#include <sstream>
#include <random>
#include <atomic>
#include <iomanip>

std::string generateUUID() {
std::stringstream ss; // 用于存放最终转换成的16进制UUID字符串

// 1. 创建一个随机数设备对象,用于生成高质量的随机种子
std::random_device rd;

// 2. 使用随机设备初始化一个Mersenne Twister伪随机数生成器
std::mt19937 generator(rd());

// 3. 创建一个均匀分布的整数生成器,范围在0到255之间
std::uniform_int_distribution<int> distribution(0, 255);

// 4. 生成UUID的前8个字节(128位中的前64位,也就是前16位十六进制)
for (int i = 0; i < 8; i++) {
// 在第5个和第7个字节位置插入"-"
if (i == 4 || i == 6) { //分别对应16进制的"8-4-4"
ss << "-"; //流插入
}
// 生成一个随机数,转换为16进制,宽度设为2,不足补0
ss << std::setw(2) << std::setfill('0') << std::hex << distribution(generator);
}
ss << "-"; //"8-4-4-"

// 5. 生成UUID的后8个字节(128位中的后64位),作为序列号逐字节加
// 使用静态原子变量保证线程安全地递增序列号
static std::atomic<size_t> seq(1);
size_t cur = seq.fetch_add(1); // 获取当前序列号并递增

// 从高位开始存放,保持和原本的二进制格式一样,逐字节处理序列号,并转换为16进制格式加入字符串
for (int i = 7; i >= 0; i--) {
if (i == 5) {
ss << "-"; //"8-4-4-4-"
}
// 提取当前字节,转换为16进制,宽度设为2,不足补0
ss << std::setw(2) << std::setfill('0') << std::hex << ((cur >> (i * 8)) & 0xFF);
}

// 返回生成的UUID字符串
return ss.str();
}

int main() {
// 测试生成UUID
std::string uuid = generateUUID();
std::cout << "Generated UUID: " << uuid << std::endl;
return 0;
}


宏日志和UUID
https://weihehe.top/2024/09/13/22-04/
作者
weihehe
发布于
2024年9月13日
许可协议