在Linux中生成随机UUID

时间:2010-02-01 05:05:58

标签: c++ linux guid uuid

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

是否存在生成UUID的标准Linux系统调用(例如,在Windows中有CoCreateGuid)? uuidgen使用的命令是什么?

8 个答案:

答案 0 :(得分:14)

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

cat /proc/sys/kernel/random/uuid

答案 1 :(得分:7)

感谢您的所有评论!

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

我需要的只是简单的基于时间的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

答案 2 :(得分:6)

我找到的一个好方法(对于linux dev)是#include <uuid/uuid.h>。然后你可以调用一些函数:

void uuid_generate(uuid_t out);
void uuid_generate_random(uuid_t out);

答案 3 :(得分:3)

有什么理由不能直接链接到libuuid吗?

答案 4 :(得分:2)

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

答案 5 :(得分:2)

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

答案 6 :(得分:0)

uuidgen在我的ubuntu linux dist上工作正常。

答案 7 :(得分:0)

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

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

此外,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 位值,而不是与兼容的 128 位值 RFC 4122 UUID。

最后的评论:

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

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

这是代码的修订版:

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