UUID

UUID(通用唯一标识符)是一种标准化的格式,用于表示唯一的标识符。它通常表示为一个 32 位十六进制数字、以连字符分隔成 5 个部分的字符串,总共有 36 个字符。

UUID 的标准格式如下:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

其中,每个 x 代表一个十六进制数字,M 表示 UUID 版本号,N 表示 UUID 变体。

  • 第一部分是一个 8 字符的数字字符串。
  • 第二部分是一个 4 字符的数字字符串。
  • 第三部分是一个 4 字符的数字字符串,其中的最高有效位是特定标识符。
  • 第四部分是一个 4 字符的数字字符串,其中的最高有效位表示 UUID 变体号。
  • 第五部分是一个 12 字符的数字字符串。

例如,以下是一个标准的 UUID:

3ce0363a-fa7c-4c65-a0e0-6c79b1a0a29d

生成UUID示例(不用uuid库)

示例1

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

std::string generate_uuid()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> distrib(0, 255);

    std::stringstream ss;
    for (int i = 0; i < 16; ++i) {
        ss << std::hex << std::setfill('0') << std::setw(2) << distrib(gen);
        if (i == 3 || i == 5 || i == 7 || i == 9) {
            ss << "-";
        }
    }
    return ss.str();
}

int main()
{
    std::cout << "Generated UUID: " << generate_uuid() << std::endl;
    return 0;
}
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# 
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# g++ main.cpp
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# 
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# 
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# ./a.out 
Generated UUID: 0d585c36-7480-0b5c-c478-d1c46a4d1020
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# 

在此示例程序中,我们使用 std::random_device 和 std::mt19937 类来生成随机数。我们然后使用 std::uniform_int_distribution 来生成一个范围在 0 到 255 之间的随机数,并将其转换为 16 进制字符串。最后,我们将生成的 16 个随机数组合起来,并在第 4、6、8 和 10 个位置插入破折号,以生成符合 UUID 标准的字符串形式。

需要注意的是,这种方法生成的 UUID 不如使用专门的 UUID 库生成的 UUID 安全,因为在某些情况下,该方法可能会生成重复的 UUID。因此,如果需要生成安全的、唯一的 UUID,请使用专门的 UUID 库。

示例2

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

std::string generate_uuid()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> distrib(0, 15);

    const char* uuid_chars = "0123456789abcdef";

    std::stringstream ss;
    for (int i = 0; i < 32; ++i) {
        int nibble = distrib(gen);
        char c = uuid_chars[nibble];
        if (i == 8 || i == 12 || i == 16 || i == 20) {
            ss << "-";
        }
        ss << c;
    }
    return ss.str();
}

int main()
{
    std::cout << "Generated UUID: " << generate_uuid() << std::endl;
    return 0;
}
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# 
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# g++ main.cpp
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# ./a.out 
Generated UUID: 7dffd7e5-a893-979e-7ac3-ce3488c8f1ce
root@sx-virtual-machine:/userdata/testOtherPrj/20230324_testUUID# 

在这个示例程序中,我们使用 std::random_device 和 std::mt19937 来生成随机数。我们使用 std::uniform_int_distribution 来生成一个范围在 0 到 15 之间的随机数,并将其转换为 UUID 格式中的一个十六进制数字字符。我们使用 uuid_chars 数组来存储十六进制数字字符。最后,我们将生成的 32 个随机数(代表 UUID 的 16 个十六进制数字)组合在一起,并在第 9、13、17 和 21 个位置插入破折号,以生成符合 UUID 标准的字符串形式。

需要注意的是,使用这种方法生成的 UUID 虽然可能具有足够的唯一性,但不是安全的,因为它们是基于随机数生成器生成的,并且可能受到随机数生成器的攻击。如果需要生成安全的、唯一的 UUID,请使用专门的 UUID 库。

上面两个示例区别

这两段代码的区别在于生成 UUID 的方法略有不同。

第一段代码使用 16 个随机字节(即 128 位),每个字节的范围在 0 到 255 之间,然后将这 16 个字节转换为 UUID 格式的字符串形式,其中每个字节使用两个十六进制数字表示。生成的 UUID 长度为 36 个字符(包括破折号)。

第二段代码使用 32 个随机数字字符,每个字符的范围在 0 到 15 之间。然后将这些数字字符组合成 UUID 格式的字符串形式,其中每个数字字符使用一个十六进制数字表示。生成的 UUID 长度为 36 个字符(包括破折号)。

在实际使用中,这两种生成 UUID 的方法都可以用来生成 UUID,但第二种方法更加常见,因为它更符合 UUID 的规范,并且可以使用更简单的算法实现。而第一种方法可以生成更广泛的随机数范围,但生成的 UUID 不一定符合规范,因此可能不太适合在实际应用中使用。

(注意:代码未审查)

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐