当前位置: 首页 > 知识库问答 >
问题:

正在生成v5UUID。什么是名称和命名空间?

上官斌
2023-03-14

我已经阅读了man页面,但我不明白name和namespace是用来做什么的。

对于版本3和版本5的UUID,必须给出额外的命令行参数命名空间和名称。命名空间要么是字符串表示中的UUID,要么是内部预定义命名空间UUID的标识符(目前已知的是“ns: DNS”、“ns: URL”、“ns: OID”和“ns: X500”)。名称是任意长度的字符串。

命名空间:

命名空间可以是字符串表示形式的UUID,也可以是

这是否意味着我需要将其(UUID v4)存储在与生成的UUID v5相关的某个位置?在这两种情况下,为什么不自动执行此操作?

名称是任意长度的字符串。

一个完全随机的字符串?那么它的目的是什么呢?可以从UUID v5解码吗?

共有3个答案

李康安
2023-03-14

名称只不过是某个命名空间中唯一的标识符。问题是名称空间通常很小,其中一个名称空间中的名称经常与其他名称空间中的名称冲突。例如,我的汽车牌照号码(名称)在我所在州的DMV名称空间中是唯一的,但在世界上可能不是唯一的;其他州的DMV可能在其自己的命名空间中使用了相同的名称。见鬼,其他人的电话号码(名称)也可能匹配,因为这是另一个名称空间,等等。

UUID可以被视为驻留在一个非常庞大的名称空间中,它可以为所有内容提供唯一的名称;这就是“普遍”的含义。但如何将其他名称空间中的现有名称映射到UUID?

一个明显的解决方案是为每个项目生成一个UUID(V1或V4),以替换不相交名称空间中的旧名称。缺点是它们要大得多,您必须将所有新名称传达给拥有数据集副本的每个人,更新所有API等。无论如何,您实际上都无法完全摆脱旧名称,这意味着现在每个项目都有两个名称,那么您是让事情变得更好还是更糟?

这就是V3/V5的用武之地。UUID看起来就像V4一样随机,但实际上是确定性的;然后,任何拥有名称空间的正确UUID的人都可以为该名称空间中的任何给定名称独立生成相同的UUID。您根本不需要发布它们,甚至不需要预生成它们,因为任何人都可以根据需要动态创建它们!

DNS名称和URL是非常常用的名称空间,因此针对这些名称空间发布了标准UUID;ASN。1 OID和X.500名称并不常见,但标准机构喜欢它们,所以他们也为它们发布了标准命名空间UUID。

对于所有其他名称空间,您必须生成自己的名称空间UUID(V1或V4),并将其传达给任何需要它的人。如果您有多个名称空间,那么必须为每个名称空间发布UUID显然是不理想的。

这就是层次结构的用武之地:创建一个“基本”UUID(任何类型),然后将其用作命名其他名称空间的名称空间!这样,您只需发布基本UUID(或使用一个明显的UUID),其余的都可以计算。

例如,我们想为StackOverflow创建一些UUID;在DNS命名空间中有一个明显的名称,因此基础很明显:

uuid ns_dns = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
uuid ns_base = uuidv5(ns_dns, 'stackoverflow.com');

StackOverflow本身为用户、问题、答案、评论等提供了单独的命名空间,但这些也相当明显:

uuid ns_user     =  uuidv5( ns_base, 'user'     );
uuid ns_question =  uuidv5( ns_base, 'question' );
uuid ns_answer   =  uuidv5( ns_base, 'answer'   );
uuid ns_comment  =  uuidv5( ns_base, 'comment'  );

这个特殊的问题是#10867405,因此其UUID应该是:

uuid here = uuidv5(ns_question, '10867405');

请注意,这个过程中没有随机性,因此任何遵循相同逻辑的人都会得到相同的答案,但UUID名称空间如此庞大,以至于它(实际上,考虑到122位加密哈希的安全性)永远不会与任何其他名称空间/名称对生成的UUID发生冲突。

辛龙野
2023-03-14

名称和命名空间可用于创建(很可能)唯一UUID的层次结构。

粗略地说,类型3或类型5 UUID是通过将名称空间标识符与名称散列在一起生成的。类型3 UUID使用MD5,类型5 UUID使用SHA1。只有128位可用,5位用于指定类型,因此所有哈希位都不会进入UUID。(同样,MD5被认为是加密破坏的,而SHA1已经处于最后阶段,所以不要用它来验证需要“非常安全”的数据)。这就是说,它为您提供了一种创建可重复/可验证的“哈希”函数的方法,该函数将可能的层次名称映射到概率唯一的128位值,可能起到层次哈希或MAC的作用。

假设您有一个(key, value)存储,但它只支持一个命名空间。您可以使用类型3或类型5的UUID生成大量不同的逻辑命名空间。首先,为每个命名空间创建一个根UUID。这可以是类型1(主机时间戳)或类型4(随机)UUID只要您将其存储在某个地方。或者,您可以为根创建一个随机UUID(或使用nullUUID:00000000-0000-0000-0000-000000000000作为根),然后使用“uuid-v5$ROOTUID$NAMESPACENAME”为每个命名空间创建一个可重复的UUID。现在,您可以使用“uuid-v5$NAMESPACEUID$KEY”为命名空间中的键创建唯一的UUID。这些UUID可以抛入单个键值存储中,以避免冲突的高概率。这个过程可以递归重复,例如,如果与UUID键关联的“值”依次表示某种逻辑“命名空间”,如桶、容器或目录,那么它的UUID可以依次用于生成更分层的UUID。

生成的类型3或类型5 UUID在名称空间(键)中保存名称空间id和名称的(部分)哈希。它不保存名称空间UUID,就像消息MAC不保存它所编码的消息的内容一样。从uuid算法的角度来看,该名称是一个“任意”(八位字节)字符串。但其含义取决于您的应用程序。它可以是逻辑目录中的文件名,对象存储中的对象id,等等。

虽然这适用于数量适中的命名空间和键,但如果您的目标是非常大数量的键,并且很有可能是唯一的,那么它最终会失去动力。Wikipedia的生日问题条目(又名生日悖论)包括一个表格,该表格给出了不同数量的键和表格大小的至少一次冲突的概率。对于128位,以这种方式散列260亿键的碰撞概率为p=10^-18(可忽略不计),但26万亿键,将至少一次碰撞的概率增加到p=10^-12(一万亿分之一),而散列26*10^15键,将至少一次碰撞的概率增加到p=10^-6(百万分之一)。调整为编码UUID类型的5位,它会更快耗尽,因此一万亿个键大约有一万亿分之一的机会发生一次碰撞。

看见http://en.wikipedia.org/wiki/Birthday_problem#Probability_table用于概率表。

看见http://www.ietf.org/rfc/rfc4122.txt有关UUID编码的更多详细信息。

董俊
2023-03-14

类型3和类型5 UUID只是将哈希填充到UUID中的一种技术:

  • 类型1:将MAC地址写入128位

编辑:非官方类型6现在有官方rfc

SHA1哈希输出160位(20字节);哈希的结果将转换为UUID。

来自SHA1的20字节摘要:

SHA1 Digest:   74738ff5 5367 e958 1aee 98fffdcd1876 94028007
UUID (v5):     74738ff5-5367-5958-9aee-98fffdcd1876
                             ⭡    ⬑first two bits set to 1 and 0, respectively
                             ╰─low nibble is set to 5, to indicate type 5

你可能想知道我该怎么处理。基本上,您可以对以下内容的串联进行哈希运算:

sha1(名称空间UUID);

您可以使用所谓的名称空间作为字符串的前缀,以防止名称冲突。

UUIDRFC为您预先定义了四个命名空间:

  • <代码>名称空间\u DNS:{6ba7b810-9dad-11d1-80b4-00c04fd430c8}

所以,您可以一起散列:

StackOverflowDnsUUID = sha1(Namespace_DNS + "stackoverflow.com");
StackOverflowUrlUUID = sha1(Namespace_URL + "stackoverflow.com");

RFC然后定义如何:

  • 从SHA1取160位

基本要点是只取前128位,在类型记录中填入一个5,然后将clock\u seq\u hi\u和\u reserved部分的前两位分别设置为1和0。

现在您有了一个生成所谓名称的函数,您就可以拥有该函数(在伪代码中):

UUID NameToUUID(UUID NamespaceUUID, String Name)
{
    //Note: All code on stackoverflow is public domain - no attribution required.

    Byte[] hash = sha1(NamespaceUUID.ToBytes() + Name.ToBytes());
    Uuid result;

    //Copy first 16-bytes of the hash into our Uuid result
    Copy(hash, result, 16);

    //set high-nibble to 5 to indicate type 5
    result[6] &= 0x0F; 
    result[6] |= 0x50; 

    //set upper two bits to "10"
    result[8] &= 0x3F; 
    result[8] |= 0x80; 

    return result;
}

(注意:系统的尾数会影响上述字节的索引)

现在您可以拨打电话:

uuid = NameToUUID(Namespace_DNS, 'www.stackoverflow.com');
uuid = NameToUUID(Namespace_DNS, 'www.google.com');
uuid = NameToUUID(Namespace_URL, 'http://www.stackoverflow.com');
uuid = NameToUUID(Namespace_URL, 'http://www.google.com/search&q=rfc+4112');
uuid = NameToUUID(Namespace_URL, 'http://stackoverflow.com/questions/5515880/test-vectors-for-uuid-version-5-converting-hash-into-guid-algorithm');

对于版本3和版本5的UUID,必须给出额外的命令行参数命名空间和名称。命名空间要么是字符串表示中的UUID,要么是内部预定义命名空间UUID的标识符(目前已知的是“ns: DNS”、“ns: URL”、“ns: OID”和“ns: X500”)。名称是任意长度的字符串。

名称空间是您喜欢的任何UUID。它可以是预定义的,也可以自己创建,例如:

UUID Namespace_RectalForeignExtractedObject = '8e884ace-bee4-11e4-8dfc-aa07a5b093db'

名称是任意长度的字符串。

名称只是您希望附加到命名空间,然后散列并填充到UUID中的文本:

uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'screwdriver');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'toothbrush');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'broomstick');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'orange');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'axe handle');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'impulse body spray');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'iPod Touch');

 类似资料:
  • 问题内容: 什么是PHP命名空间? 一般而言,命名空间是什么? 一个有例子的Layman答案会很棒。 问题答案: Namespacing对函数和类起作用,而作用域对变量起作用。它允许您在同一程序的不同部分中使用相同的函数或类名称,而不会引起名称冲突。 简单来说, 将名称空间视为一个人的姓氏 。如果有两个人名为“ John”,则可以使用他们的姓氏来区分他们。 场景 假设您编写了一个使用名为的函数的应

  • 问题内容: 我刚刚开始学习Python,并在Python中遇到了 “命名空间” 概念。虽然我了解了它的本质,但无法理解这个概念的严重性。 网上的一些浏览显示,反对PHP的原因之一是它没有对名称空间的本地支持。 有人可以解释如何使用名称空间以及此功能如何使编程更好 (不只是在Python中,因为我假设名称空间的概念不限于特定语言)。 我主要来自Java和C编程背景。 问题答案: 命名空间是一种实现范

  • 尝试基于两个唯一的字符串生成客户端Id。这应该与服务器中从相同的ID生成的UUID相同。 使用Javascript,它看起来像这样: 似乎找不到在Swift上生成这个的方法,NSUUID只能从无到有生成UUID 我正在寻找这样的东西: 编辑 例:

  • 抱歉,如果我问的是新手问题,但名称空间对我来说真的很费解。 我试图从一个XML/XSLT生成多个SVG文档。 我的样式表: 这样做会产生以下输出: 但我希望能够根据计算的内容指定高度和宽度属性 我尝试将“ ”创建为 http://www.w3.org/2000/svg 这将失败,因为它(xmlspy)不允许我分配xmlns属性。 如果不在根(svg)上指定名称空间,则xmlns将自动添加到根 节点

  • 我们知道命名空间: 但是什么是全局命名空间呢?