我陷入了一个奇怪的困境。我需要在我的 Linux 程序(我使用 RPM 分发)中生成 UUID。我不想通过要求用户安装 libuuid 来向我的应用程序添加另一个依赖项(似乎 libuuid 不包含在大多数 Linux 发行版中,如 CentOS)。
是不是有一个标准的 Linux 系统调用来生成 UUID(比如,在 Windows 中有 CoCreateGuid)?uuidgen 命令有什么用?
我错过了什么吗?你不能:
cat /proc/sys/kernel/random/uuid
谢谢你们的评论!
我经历了每一个,这是最适合我要求的:
我需要的只是简单的基于时间的 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
我发现(对于 linux 开发人员)的一个好方法是#include <uuid/uuid.h>
. 然后,您可以调用一些函数:
void uuid_generate(uuid_t out);
void uuid_generate_random(uuid_t out);
有什么理由不能静态链接到 libuuid?
也许 ooid 会有所帮助?http://ooid.sourceforge.net/
POSIX 中不存在用于生成 UUID 的系统调用,但我想您可以在某处找到 BSD/MIT 代码来生成 UUID。ooid 是在 Boost 软件许可证下发布的,根据维基百科,它是 BSD/MIT 风格的许可许可证。然后您可以将其粘贴到您的应用程序中,而无需添加任何依赖项。
uuidgen
在我的 ubuntu linux dist 上工作得很好。
我还不能对答案发表评论,但我只想指出,接受的答案对 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;
}