3

我正在尝试通过引用函数(http://www.ietf.org/rfc/rfc4122.txt)来生成 v5 UUID:

/* uuid_create_sha1_from_name -- create a version 5 (SHA-1) UUID
   using a "name" from a "name space" */
void uuid_create_sha1_from_name(
    uuid_t *uuid,         /* resulting UUID */
    uuid_t nsid,          /* UUID of the namespace */
    void *name,           /* the name from which to generate a UUID */
    int namelen           /* the length of the name */
);

uuid_t nsid我已经阅读了帮助,但我仍然不清楚上述函数的 2nd( ) 和 3rd ( void *name) 参数有什么区别?

有人可以用一个例子解释我上面的内容吗?

我还想了解以下在 RFC4122 链接中的含义,它对第二个参数有什么意义吗?

/* Name string is a URL */
uuid_t NameSpace_URL = { /* 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */
    0x6ba7b811,
    0x9dad,
    0x11d1,
    0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
};
4

2 回答 2

4

name是您生成 uuid 的任何东西的唯一键

namespace是一个常量 UUID,用于标识生成 UUID 的上下文

如果您查看 RFC,您会看到第 4.3 节定义了基于名称的 UUID 的这些特征:

  • 在不同时间从同一命名空间中的相同名称生成的 UUID 必须相等。
  • 从同一个命名空间中的两个不同名称生成的 UUID 应该是不同的(很有可能)。
  • 在两个不同的命名空间中从相同名称生成的 UUID 应该不同(非常可能)。
  • 如果从名称生成的两个 UUID 相等,则它们是从同一命名空间中的相同名称生成的(概率非常高)。

这些都是在基于名称的 UUID 中具有的重要属性。例如,假设您和我正在为我们各自的公司实施人力资源系统。这些系统彼此完全不相关,但由于 UUID 非常棒,我们都使用基于名称的 UUID 来识别员工。而且因为这是一件相当明显的事情,我们使用员工姓名作为name生成 UUID 的依据。

如果没有命名空间,我们都会为任何名为“John Smith”的人创建相同的 UUID……但这会很糟糕(tm),因为我们的系统是不相关的,而且我们正在处理不同的 John Smiths。“那又怎样,”你说!...但是当我们的公司明年合并并且我们必须合并我们的人力资源数据库时会发生什么?好吧,到那时,我们发现自己正在合并具有相同 ID 的数据库记录,很快公司中每个 John Smith 的薪水都在邮寄中,HR 递给我们我们的粉红单。

为了防止这种事情发生,RFC 规定我们每个人都独立地选择一个 UUID作为我们的namespace. 命名空间通常是固定的,并与生成 UUID 的特定系统相关联,因此我们可能只是将其硬编码为某个配置文件中的某个常量。因此,在我的命名空间(例如87c9cdf7-101d-4c05-a89d-c7aaff3a3fcf)中,我可以相信我为其生成的 UUIDJohn Smith将始终相同。但我也可以指望它与您创建的任何 UUID 不同,因为您将使用不同的命名空间。因此,如果/当我们的系统合并时,就不会有任何问题。

于 2013-01-30T21:31:44.653 回答
1

引用 RFC 的第 4.3 节,有这个步骤:

为从该名称空间中的名称生成的所有 UUID 分配一个 UUID 以用作“名称空间 ID”;有关一些预定义值,请参见附录 C。

据我了解,这个命名空间的目的是确保使用具有相同含义的相同名称将导致相同的 UUID,而使用具有不同含义的相同名称将导致不同的 UUID。命名空间 UUID 与实际名称连接在一起,并且两者都被散列在一起。

关于 6ba7b811-9dad-11d1-80b4-00c04fd430c8 UUID 的代码片段来自 C 部分。因此,当您将其用作命名空间时,您应该使用 URL 作为名称。例如,您将函数称为

uuid_t result_uuid;
const char* url = "http://www.example.com/document.txt";
uuid_create_sha1_from_name(&result_uuid, NameSpace_URL, url, strlen(url));

与此相反,整个 example.com 域的 UUID 将使用

uuid_t result_uuid;
const char* domain = "example.com";
uuid_create_sha1_from_name(&result_uuid, NameSpace_DNS, domain, strlen(domain));
于 2013-01-30T21:09:22.027 回答