13

我陷入了一个奇怪的困境。我需要在我的 Linux 程序(我使用 RPM 分发)中生成 UUID。我不想通过要求用户安装 libuuid 来向我的应用程序添加另一个依赖项(似乎 libuuid 不包含在大多数 Linux 发行版中,如 CentOS)。

是不是有一个标准的 Linux 系统调用来生成 UUID(比如,在 Windows 中有 CoCreateGuid)?uuidgen 命令有什么用?

4

8 回答 8

21

我错过了什么吗?你不能:

cat /proc/sys/kernel/random/uuid
于 2013-04-03T21:59:24.850 回答
11

谢谢你们的评论!

我经历了每一个,这是最适合我要求的:

我需要的只是简单的基于时间的 UUID,它是为每个安装应用程序的用户从随机数生成的。RFC 4122 中指定的 UUID 版本 4 正是它。我通过了建议的算法,并提出了一个非常简单的解决方案,它可以在 Linux 和 Windows 中运行(也许它太简单了,但它确实满足了需求!):

srand(time(NULL));

sprintf(strUuid, "%x%x-%x-%x-%x-%x%x%x", 
    rand(), rand(),                 // Generates a 64-bit Hex number
    rand(),                         // Generates a 32-bit Hex number
    ((rand() & 0x0fff) | 0x4000),   // Generates a 32-bit Hex number of the form 4xxx (4 indicates the UUID version)
    rand() % 0x3fff + 0x8000,       // Generates a 32-bit Hex number in the range [0x8000, 0xbfff]
    rand(), rand(), rand());        // Generates a 96-bit Hex number
于 2010-02-02T06:34:03.423 回答
10

我发现(对于 linux 开发人员)的一个好方法是#include <uuid/uuid.h>. 然后,您可以调用一些函数:

void uuid_generate(uuid_t out);
void uuid_generate_random(uuid_t out);
于 2014-09-12T23:32:58.243 回答
3

有什么理由不能静态链接到 libuuid?

于 2010-02-01T05:47:49.817 回答
2

也许 ooid 会有所帮助?http://ooid.sourceforge.net/

于 2010-02-01T05:13:05.283 回答
2

POSIX 中不存在用于生成 UUID 的系统调用,但我想您可以在某处找到 BSD/MIT 代码来生成 UUID。ooid 是在 Boost 软件许可证下发布的,根据维基百科,它是 BSD/MIT 风格的许可许可证。然后您可以将其粘贴到您的应用程序中,而无需添加任何依赖项。

于 2010-02-01T05:18:34.920 回答
0

uuidgen在我的 ubuntu linux dist 上工作得很好。

于 2020-07-24T06:12:44.047 回答
0

我还不能对答案发表评论,但我只想指出,接受的答案对 rand() 的使用在 Windows 上根本无法正常工作,其中 RAND_MAX 定义为 0x7fff,只给出 15 位随机性。在 Linux 上它更高,但看起来像 0x7fffffff,提供 31 位随机性,仍然缺少 1 位到完整的 32 位长度。

使用 rand() 的最安全方法是依赖于这样一个事实,即任何地方的最低保证 RAND_MAX 值将是 0x7fff - 多次调用它,左移 15 位并使用新值进行 OR'ing,直到需要产生的随机位数。

此外,格式字符串中sprintf应指定宽度,因此要考虑前导零(宽度基于相应参数注释中提到的位):

sprintf(strUuid, "%08x%08x-%08x-%08x-%08x-%08x%08x%08x", 
    rand(), rand(),                 // Generates a 64-bit Hex number
    rand(),                         // Generates a 32-bit Hex number
    ((rand() & 0x0fff) | 0x4000),   // Generates a 32-bit Hex number of the form 4xxx (4 indicates the UUID version)
    rand() % 0x3fff + 0x8000,       // Generates a 32-bit Hex number in the range [0x8000, 0xbfff]
    rand(), rand(), rand());        // Generates a 96-bit Hex number

此外 - 代码生成 256 位值,而不是与 RFC 4122 UUID 兼容的 128 位值。

最后评论:

rand() % 0x3fff + 0x8000,       // Generates a 32-bit Hex number in the range [0x8000, 0xbfff]

由于模运算符,产生的实际范围是 [0x8000, 0xbffe]。%应该是(或者如果使用&0x3fff 应该是 0x4000 %,但除法总是比按位与更昂贵的操作)。

这是代码的修订版本:

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstdint>

uint32_t rand32()
{
    return ((rand() & 0x3) << 30) | ((rand() & 0x7fff) << 15) | (rand() & 0x7fff);
}

bool gen_uuid4(char dst[37], size_t len)
{
    int n = snprintf(dst, len, "%08x-%04x-%04x-%04x-%04x%08x", 
        rand32(),                         // Generates a 32-bit Hex number
        rand32() & 0xffff,                // Generates a 16-bit Hex number
        ((rand32() & 0x0fff) | 0x4000),   // Generates a 16-bit Hex number of the form 4xxx (4 indicates the UUID version)
        (rand32() & 0x3fff) + 0x8000,     // Generates a 16-bit Hex number in the range [0x8000, 0xbfff]
        rand32() & 0xffff, rand32());     // Generates a 48-bit Hex number
        
    return n >= 0 && n < len;             // Success only when snprintf result is a positive number and the provided buffer was large enough.
}

int main()
{
    char strUuid[37];
    srand(time(NULL));
    
    bool success = gen_uuid4(strUuid, sizeof(strUuid));
    
    printf("%s\n", success ? strUuid : "UUID generation failed!");
    
    return 0;
}
于 2021-05-11T21:38:36.733 回答