如何用C语言生成GUID?
我想生成插入 SQLite 数据库的 guid(即数据库本身不支持)。但是,我想控制某些属性:
- 用于生成增加的 guid 值的有序性。
- 计算机独立性。数据库是公共的,可能/可能不希望 guid 允许某人将数据追溯到特定机器。
- “足够”的随机性。 guid 是数据库中的键,它将与许多其他数据库合并,并且可能变得相当大,这意味着像许多算法那样伪造 guid 是不好的。
- 我可以使用系统特定的 API 来处理,但请链接 Windows 和 Linux 函数,并且首选 SQLite 之类的东西,我可以在其中使用其他人编写的代码。
- 我还更喜欢可以在商业应用程序中使用的代码。
I want to generate guids to insert into a SQLite database (i.e. no support from the db itself). However, I would like to have control over certain properties:
- Orderedness for generating increasing guid values.
- Computer independence. The db is public and may/may not want guids to allow someone to trace data back to a specific machine.
- 'Enough' randomness. The guids are keys in the db which is going to be merged with a lot of other dbs and can get quite large, meaning that faking a guid like many algorithms do is no good.
- I can deal with using system specific APIs but please link both Windows and Linux functions, and something like SQLite is preferred, where I can just use code someone else wrote.
- I would also prefer code which is OK to use in a commercial application.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(4)
您可以使用或查看 Boost.Uuid 的代码:
http://www.boost.org/doc/libs/1_47_0/libs/uuid/index.html
它是一个 C++ 库,但仍然可以在里面找到代码作者在多个系统上检索了 Uuid。上次我检查时(2010 年 1 月),我至少发现了 Windows 和 Linux/Solaris 的以下实现(此信息可能已过时):
Linux/Solaris 上的 UUID/GUID
打开文件到 /dev/urandom 并读取足够的字节 (16) 来组成 GUID/UUID。
Windows 上的 UUID/GUID
使用以下 WinAPI 函数
- CryptAcquireContext 获取随机上下文
- CryptReleaseContext 释放获取的随机上下文
- CryptGenRandom 生成足够的字节来组成 GUID/UUID
其他实现
关于 GUID/UUID 的维基百科页面有一个可供选择的实现列表使用/研究:
https://en.wikipedia.org/wiki/UUID#Implementations
关于您的条件
有一个 GUID/UUID 类型始终是随机的(版本 4),表示与其他 GUID 兼容/UUID 语义,你应该尊重它。
现在,您希望及时订购 GUID/UUID。在不削弱 GUID/UUID 随机性的情况下做到这一点的唯一方法是在 16 字节 GUID/UUID 前面添加一个无符号整数(这将使您的标识符数据成为 20 字节或更多,具体取决于您的整数)。只需生成一个 GUID/UUID,并增加整数即可。
首先,GUID 不是随机的,它们在数学上有很好的定义。
至于你的问题,将 GUID 创建作为存储过程放入数据库本身,这样系统就独立于平台。然后,使 GUID 成为以数据库 ID 为前缀的自动递增整数。该前缀允许轻松合并数据库。每个数据库的数据库 ID 必须是唯一的。如果您控制每个数据库,那么就很容易确保它们是唯一的。否则,您可能需要一个查找系统,将数据库 IP 地址(或其他一些唯一标识符)映射到唯一的数据库 ID。
如果您没有存储过程,则创建一个包含“NextIndex”和“DatabaseID”字段的表,并在添加新记录时更新它们:
read NextIndex and DatabaseID
increment NextIndex
ID = NextIndex + DatabaseID
add new record, setting "GUID" to the ID value
这是一个 Linux 示例。 Linux 有一个用于 uuid 生成的头文件 uuid.h。对于我的 Ubuntu 20.x 操作系统,uuid.h 头文件位于 /usr/include/uuid/ 中。
/* uuid.c
*
* Defines function uuid
*
* Print a universally unique identifer, created using Linux uuid_generate.
*
*
* Compile
*
* gcc uuid.c -o uuid -luuid -Wall -g
*
*
* Run
*
* ./uuid
*
*
* Debug
*
* gdb uuid
* b main
* r
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <uuid/uuid.h>
char* uuid(char out[UUID_STR_LEN]){
uuid_t b;
uuid_generate(b);
uuid_unparse_lower(b, out);
return out;
}
int main(){
char out[UUID_STR_LEN]={0};
puts(uuid(out));
return EXIT_SUCCESS;
}
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
寻找创建包含作者正在寻找的许多元素的 GUID 答案的一个地方是 PHP .. https://www.php.net/uniqid .. 在他们的示例中,他们讨论了如何将服务器名称、数据库名称和其他元素添加到 GUID。
但是,为了满足基于 C 的 GUID 函数的需求,这里是基于 JavaScript 函数的代码.. 如何创建 GUID / UUID? .. 此示例使用 RegEx 创建 GUID。
下面的代码将基于 JavaSCript 示例创建 GUID。我确信还有更优雅的解决方案。这是一些拼凑在一起的东西,有助于为其他人提供一个清晰的榜样。
注意:字符串以 0x00 字符结尾。
One place to look for an answer to creating a GUID that contains many of the elements the author is looking for is in PHP .. https://www.php.net/uniqid .. In their examples, they discuss how to add server names, database names, and other elements to a GUID.
However, to address the need for a C based GUID function, here is code based on a JavaScript function .. How do I create a GUID / UUID? .. this example uses RegEx to create the GUID.
Below is code that will create a GUID based on the JavaSCript example. I'm sure there are more elegant solutions out there. This is something cobbled together to help give a clean example for others to follow.
Note: strings end with a 0x00 character.