在C语言中生成随机UUID

15

如何在C语言中生成基于熵的UUID并将其存储为字符串(char指针)?

我希望有一种内部简单的方法来实现这一点,但如果没有,system("uuidgen -r") 也可以使用。


2
你的操作系统可能已经安装了libuuid。在我的系统上,man 3 uuid可以查看相关信息。使用man -k uuid命令可能会显示其他选项。 - 7 Reeds
2
当然,你需要将你的程序与libuuid链接。 - FBergo
1
看看其他的uuid_*手册页。 我猜你有一个UUID,但它以二进制格式存在。 你可能需要以某种方式将其转换为文本。 在我的计算机上,有一个库函数uuid_unparse()和其他函数。已编辑。 - 7 Reeds
2
@DavidC:这并不能保证一个有效的UUID,即使是有效的,它也可能与一个原本不应该发生冲突的非随机UUID发生冲突。使用库的原因就在于此。 - StephenS
UUID不仅仅是随机数字。其中一些数字包括版本和变体信息。请参见http://www.ietf.org/rfc/rfc4122.txt - Edward Falk
显示剩余7条评论
3个回答

27

这个功能由 libuuid 提供。(在 Debian 上需要安装 libuuid1uuid-dev 包。)

这是一个简单的程序,它生成基于熵(随机)的 UUID 并将其写入 stdout,然后以状态码 0 退出。

/* For malloc() */
#include <stdlib.h>
/* For puts()/printf() */
#include <stdio.h>
/* For uuid_generate() and uuid_unparse() */
#include <uuid/uuid.h>


/* Uncomment to always generate capital UUIDs. */
//#define capitaluuid true

/* Uncomment to always generate lower-case UUIDs. */
//#define lowercaseuuid true

/*
 * Don't uncomment either if you don't care (the case of the letters
 * in the 'unparsed' UUID will depend on your system's locale).
 */


int main(void) {
    uuid_t binuuid;
    /*
     * Generate a UUID. We're not done yet, though,
     * for the UUID generated is in binary format 
     * (hence the variable name). We must 'unparse' 
     * binuuid to get a usable 36-character string.
     */
    uuid_generate_random(binuuid);

    /*
     * uuid_unparse() doesn't allocate memory for itself, so do that with
     * malloc(). 37 is the length of a UUID (36 characters), plus '\0'.
     */
    char *uuid = malloc(37);

#ifdef capitaluuid
    /* Produces a UUID string at uuid consisting of capital letters. */
    uuid_unparse_upper(binuuid, uuid);
#elif lowercaseuuid
    /* Produces a UUID string at uuid consisting of lower-case letters. */
    uuid_unparse_lower(binuuid, uuid);
#else
    /*
     * Produces a UUID string at uuid consisting of letters
     * whose case depends on the system's locale.
     */
    uuid_unparse(binuuid, uuid);
#endif

    // Equivalent of printf("%s\n", uuid); - just my personal preference
    puts(uuid);

    return 0;
}

uuid_unparse()不会分配自己的内存;为了避免执行时出现分段错误,您必须手动使用uuid = malloc(37);进行分配(您也可以将UUID存储在长度为37的char数组中:char uuid[37];)。确保使用-luuid编译,以便链接器知道libuuid中定义了uuid_generate_random()uuid_unparse()


6
您可以使用相同 UUID 库中的 UUID_STR_LEN,而不是硬编码使用 37 - user3758232

4

由于大家都建议使用库,因此我想写一个只使用C语言的rand()函数来快速生成UUID的版本。请确保在某个地方调用srand函数,以便随机生成UUID。

不能保证不会生成两个相同的UUID,并且不能保证满足任何标准UUID。据我所知,它们只是带有连字符的随机十六进制字符串。此外,这种方法不支持多线程。

char* gen_uuid() {
    char v[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    //3fb17ebc-bc38-4939-bc8b-74f2443281d4
    //8 dash 4 dash 4 dash 4 dash 12
    static char buf[37] = {0};

    //gen random for all spaces because lazy
    for(int i = 0; i < 36; ++i) {
        buf[i] = v[rand()%16];
    }

    //put dashes in place
    buf[8] = '-';
    buf[13] = '-';
    buf[18] = '-';
    buf[23] = '-';

    //needs end byte
    buf[36] = '\0';

    return buf;
}

0
在Linux上,您可以使用<uuid/uuid.h>,对于我来说,在Ubuntu 20.x上它位于/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;
}

代码编译错误 - satyesht
嗯,按照提供的说明,这段代码在我的电脑上编译和运行得很好。我的gcc版本是11.3.0。你把代码复制到的文件名是不是像编译说明中期望的那样是“uuid.c”?如果不是,你使用的平台和编译器版本是什么? - angstyloop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接