将 GUID 转换为等效数字
Posted
技术标签:
【中文标题】将 GUID 转换为等效数字【英文标题】:Convert GUID to Numeric Equivalent 【发布时间】:2012-08-04 16:15:04 【问题描述】:我被要求从 ActiveDirectory 中导出用户列表,并将 GUID 转换为数字等价物以进行显示(因此我将在之后使用 .ToString)。我已经进行了一些搜索,但大多数问题都是关于将某些东西转换为 GUID,或将 GUID 转换为 Int 或一些愚蠢的东西(我知道 Ints 太小等等),这并不合适。
我已经对 AD 内容进行了排序并导出了数据,但是我想知道使用什么数据类型/格式来将 GUID 转换为,以及它是否可能。只要数字仍然是“唯一的”(我知道 GUID 并不是真正唯一的等等),我并不在意使用什么确切的数字类型。
GUID 是基于十六进制的格式吗?是否有任何合适的数字类型我可以将它们转换为显示?
我正在使用 VB.Net 和 .Net Framework 4。我尝试过使用 BigInteger,但这似乎也变成了负数,如果我必须使用它,我会使用它,但如果有什么我宁愿不使用其他更合适。
编辑 这是我尝试过的:
使用以下 GUID:f02c7caf-7e5a-491b-9f23-9476174bdda1
还有这段代码:
Dim Foo As String = (New System.Numerics.BigInteger(adUserDirectoryRecord.Guid.ToByteArray())).ToString
结果如下: -125127638954164478915246035839554388817
注意:完成后,我将以 .csv 格式输出,以便另一个团队获取并导入另一个系统,这可能是他们希望它以数字而不是数字的原因比字母数字格式。
解决方案:
由于无需将数字 GUID 转换回来,BigInteger 是用于此目的的正确方法。更改是调整 ByteArray 的大小以仅将其强制为正值:
'Gets the User's GUID from the Active Directory record, converts it to a Byte Array and Resizes it to Force Positive Values Only:
Dim bytGUIDBytes As Byte() = adUserDirectoryRecord.Guid.ToByteArray()
Array.Resize(bytGUIDBytes, 17)
'Converts the User's GUID Bytes into a Numeric Equivalent, and Returns the String version of the Numerical value.
Return New System.Numerics.BigInteger(bytGUIDBytes).ToString
【问题讨论】:
如果您认为 GUID 并不是真正唯一的,为什么转换为数字表示会改变这一点? 您需要一个 128 位无符号整数数据类型。请看这个问题,例如:***.com/questions/7283200/… 我不想改变“唯一性”,我被要求将它们转换为数字等价物的原因是它更适合显示/输入到另一个系统.我只提到了关于它们是“唯一”的部分,以表明这不是一个要求,因为我理解它们不是,(因为它们只是一个很大的 128 位值,碰撞的可能性很小)。BigInteger
看起来是您唯一真正的选择。不知道你从哪里得到它能够成为负面的想法 - 这完全取决于你如何表示 GUID。
编辑了我尝试用于 BigInteger 的代码,以及它是如何产生的。让我知道我是否是一个完整的 nab 嘿。我现在也要看看 128 位无符号的。顺便说一句,只有一些值为负,这个:“1c30c658-7da4-4d04-be57-cc8412c91868”出来为:“138368404917772402407527972134244632152”
【参考方案1】:
“数字”在 VB w.r.t Guid
中没有意义。 .net 中没有 128 位数字类型。唯一的 128 位类型是十进制;但是将Guid
转换为Decimal
似乎没有意义。我会简单地使用ToByteArray
并将字节值显示为十六进制。
或者,确保给 BigInteger 的数组中的最后一个字节为零以获得正值。例如::
var bytes = Guid.NewGuid().ToByteArray();
Array.Resize(ref bytes, 17);
var bigInt = new BigInteger(bytes);
var value = bigInt.ToString();
【讨论】:
嗯,我通过 BigInteger 转换做到了这一点(在顶部编辑了我的帖子以显示我使用的内容)。我相信他们要求我将其转换为数字,因为他们会将其导入另一个系统,该系统不允许该字段使用字母数字,因此准系统 Hex 可能不适合。那么这个要求完全疯了吗?基于 GUID 的结构。 我不相信他们想要将其转换回来,只将其存储为数值(而不是 GUID),在他们将其导入到的任何字段中。我会和他们核实一下,它会支持这么长的数字!否则他们可能不得不使用不同的字段。我正在检查的是您可以将 GUID 转换为数字等价物(不会丢失数据),以及最适合的类型。我使用过 BigInt,但正如我在最初的帖子中所编辑的那样,对于某些 ID,它会将它们转换为负值。 :S 谢谢,我已经与团队核实过,他们将其导入到的字段将采用大小。我刚刚尝试过这样的方法:Dim GUIDBytes As Byte() = adUserDirectoryRecord.Guid.ToByteArray() Array.Resize(bytGUIDBytes, 17) Dim Blah As String = New System.Numerics.BigInteger(bytGUIDBytes).ToString
并得到:“215154727966773984548128571592213822639”之前是:“-125127638954164478915246035839554388817”。这仍然正确吗?
它确实至少给出了所有正值,这很棒。因为只要“唯一性”仍然保留,它就不会以任何一种方式转换回来,所以顺便说一句。
谢谢!我已将解决方案编辑到我的初始帖子中。任务完成。为帮助干杯! :)【参考方案2】:
您可以使用 ToString("n") 简单地将 Guid 转换为数字表示:
Guid.NewGuid().ToString("n")
将返回类似“5ee575bd995b419499aff6d6967c4a35”的内容
【讨论】:
那是字母数字。 不,这是十六进制的数字 啊哈当然。有趣的。代码也会稍微少一些。 如果你想要十进制的结果:Convert.ToInt64(Guid.NewGuid().ToString("n"), 16);
不会抛出异常吗?我的意思是 Guid 是 128,而您正在转换为 int64。以上是关于将 GUID 转换为等效数字的主要内容,如果未能解决你的问题,请参考以下文章