为什么.NET GUID中有破折号?

为什么.NET GUID中有破折号?,.net,guid,uuid,.net,Guid,Uuid,为什么.NET GUID中有破折号?GUID的大多数实现中是否都有破折号,或者它只是Microsoft的东西 签字 741ecf77-9c92-4435-8e6b-85975bd13452这只是一种方便 这是一个分组的例子,就像电话号码、信用卡号码等 我所看到的guid的几乎每个视觉表示都使用虚线格式。这对眼睛来说要容易得多。从技术上讲,一张照片中没有“破折号”。GUID是一个128位的值,通常以以下方式存储(此处使用C表示结构): 破折号是GUID的字符串表示形式 破折号是可选的,在GUID的

为什么.NET GUID中有破折号?GUID的大多数实现中是否都有破折号,或者它只是Microsoft的东西

签字


741ecf77-9c92-4435-8e6b-85975bd13452这只是一种方便


这是一个分组的例子,就像电话号码、信用卡号码等


我所看到的guid的几乎每个视觉表示都使用虚线格式。这对眼睛来说要容易得多。

从技术上讲,一张照片中没有“破折号”。GUID是一个128位的值,通常以以下方式存储(此处使用C表示结构):

破折号是GUID的字符串表示形式

破折号是可选的,在GUID的字符串表示形式中不是必需的


也就是说,它与Guid的生成方式有关,但历史语义不再适用。

NET的
Guid
类识别一系列不同的格式:破折号作为分隔符,没有分隔符,方括号作为分隔符,圆括号作为分隔符,没有分隔符,等等。GUID由16个字节组成,在十六进制文本表示法中由32个字符组成。没有连字符的Guid很难被人类察觉,也很难被识别为Guid,而不是一些随机的16字节数。

连字符表示Guid的字节结构

typedef struct _GUID 
{  
   DWORD Data1;  
   WORD Data2;  
   WORD Data3;  
   BYTE Data4[8];
} GUID;
用于:


你可以在保存之前把它们剥掉。至少在.NET中,Guid类型的构造函数将根据其字符串表示形式初始化Guid变量,而不管连字符是否仍然存在或已删除。

如果要将Guid存储在某个位置,请将其存储为16字节的数组,而不是文本表示形式。您将节省大量空间,并且不会出现连字符问题。

连字符用于分隔每个数字

E93416C5-9377-4A1D-8390-7E57D439C9E7

Hex digits  Description
8           Data1
4           Data2
4           Data3
4           Initial two bytes from Data4
12          Remaining six bytes from Data4

GUID实际上只是一个数字。连字符向您显示了各种组件是如何分解的,但实际上并不是数字的一部分。它就像一个IP地址——你可以存储一个32位的数字,也可以存储一个带点的字符串,它们是等效的。

hypens对值的唯一性或随机性没有任何影响。它们只不过是GUID定义的一种保留,在视觉上将构成GUID的数据的四个不同部分分开。

您可以获得各种格式的GUID

假设您正在使用c#:

63be6f7e4e564f0580229f958f492077

Console.WriteLine(guid.ToString("D"))
Console.WriteLine(guid.ToString("B"))
63be6f7e-4e56-4f05-8022-9f958f492077

Console.WriteLine(guid.ToString("D"))
Console.WriteLine(guid.ToString("B"))
{63be6f7e-4e56-4f05-8022-9f958f492077}

Console.WriteLine(guid.ToString("P"))

(63be6f7e-4e56-4f05-8022-9f958f492077)

在UUID(通用唯一标识符)规范的初始版本中,每个数据元素都具有语义含义:

{time\U low}{time\U mid}{time\U high\U版本}{clock\U SEQU\U low}{节点id}

这些元素旨在提供时间(时间位)和空间(主机位)的唯一性

版本历史 由于发现在2^1024个随机位的密钥空间中发生碰撞的数学概率在天文学上是不可能的,UUID规范的后续版本出于安全和隐私原因已逐步淘汰了时间和主机数据

唯一保留任何含义的元素是版本位和保留位

版本3 UUID派生自URI或其他可分辨名称的MD5哈希

版本4是使用随机数据生成的,目前是您在野外看到的最常见的实现

版本5是从SHA1散列派生的

存储格式 由于连字符是为RFC中UUID的ASCII格式指定的,即使各个部分不再保留其原始含义,如果需要互操作性,仍然需要连字符

UUID有时也存储为base64或ascii85编码字符串,以节省空间,以便通过非二进制安全的传输进行传输,并且不需要遵守RFC

Ascii: 3F2504E0-4F89-11D3-9A0C-0305E82C3301 Base64: 7QDBkvCA1+B9K/U0vrQx1A Ascii85: 5:$Hj:Pf\4RLB9%kU\Lj Ascii:3F2504E0-4F89-11D3-9A0C-0305E82C3301 Base64:7QDBkvCA1+B9K/U0vrQx1A Ascii85:5:$Hj:Pf\4RLB9%kU\Lj 参考文献:
(关于UUID格式的ABNF说明,请参见第3页)

维基百科

有趣的问题。我必须说,我从来没有停下来考虑过它。guid具有相同的熵,无论它们是否包含连字符。连字符仅在将一个显示为文本时使用。真正的UUID是一个16字节的二进制字符串/数组。这是真的,但你不能以任何有意义的方式使用该结构的某些部分,对吗?但是为什么在
Data4
中使用额外的连字符呢?请看这里的解释:更正,
Guid
不是类,而是值类型。这完全不正确,GUID的连字符ASCII十六进制表示形式中有5个连字符元素,包含二进制GUID元素的结构只有4个元素长。此外,历史语义学确实仍然适用,特别是在这个问题上,考虑到历史是连字符首先出现的确切原因。@Josh Perry你已经在回答中重申了我的观点。一个
Guid
只有128字节,句号。分隔符来自表示。此外,关于在表示中应用的历史语义,它们没有。正如你所说,这是出于历史原因。这些历史原因不再适用。根据您的回答,“这些数据元素不再具有任何特定的含义。”我不确定我在哪里重申GUID是128字节,但您的第二段(关于连字符与结构对应)显然是不准确的。之所以有连字符,是因为该布局是在UUID RFC中指定的,与该结构无关。的确,contempo中的段 Ascii: 3F2504E0-4F89-11D3-9A0C-0305E82C3301 Base64: 7QDBkvCA1+B9K/U0vrQx1A Ascii85: 5:$Hj:Pf\4RLB9%kU\Lj