如何将 Long 转换为 Guid,反之亦然?
这可能吗?我什至不认为是这样,但我看到一些代码试图做到这一点。然而,我的单元测试表明它不起作用。我确实看到了一些类似的想法:
只是为了澄清。 Guid 的创建不在我的控制范围内;因此,我不能只将值存储在其中一个 Guid 集中。
Is this even possible? I don't even think it is, but I saw some code that was trying to do it. However, my unit tests showed that it was not working. I did see some similar thoughts:
Just for clarification. The Guid creation is outside of my control; therefore, I can't just store the value in one of the Guid sets.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
Guid 只是一个 128 位数据结构,而 long 是一个 64 位数据结构...
这意味着只要高 64 位是零,我们就可以安全地丢弃它们并在以后重建它们因为在这种情况下,零并不意味着完整的数据。所以,是的,这是数据丢失,但在某些情况下,这是可以重建的数据丢失。 (从压缩的角度思考)
这与您说“做”时没有什么不同:
这些显式转换没有内置到系统中,因为它不是,所以必须以不同的方式进行。
显然,一般来说,这不应该与 GUID 一起使用,但只要 GUID 只有 64 位“实际数据”,就可以安全使用,确保这一点的最佳方法是永远不要在 guid 上使用它,除非它们是使用长的。
作为预防措施,我添加了在 Guid 实际上在最后 64 位中存储除 0 之外的任何内容的情况下抛出 OverflowException,因为生成的 long 无法转换回相同的 Guid。
所以就这样...
是的...显然,GUID 的相应长值不容易读取,这里有一些示例(长= guid):
是的,这些转换都是双向的,并且对于您可以想到的任何长值...
但是因为你说:
您实际上不可能做到这一点,相反,您拥有的 Guid 很可能是使用任何常见算法生成的,这将使 Guid 在这种情况下无法使用。
现在这样做有意义吗?...这需要对特定情况有深入的了解,并且是一个完全不同的讨论...
A Guid is merely a 128 bit data structure and a long is a 64 bit data structure...
That means that for as long as the upper 64 bits are Zeroes, we can safely discard them an at a later time reconstruct them as Zeroes are not meaning full data in this case. So yes it is loss of data, but under circumstances it is loss of data that can be reconstructed. (Think in terms of compression)
This is no different that when you say do:
These explicit conversions are not built into the system as it is not so one must do it differently.
Obviously this should never be used with GUID's in genneral, but is safe to use for as long as the GUID only has 64 bits of "actual data", best way to ensure that is to never use it on guids unless they where created using a long.
As a precaution I have added the throwing of an OverflowException in cases where the Guid actually stores anything but 0'es in the last 64 bits as the resulting long would not be able to be converted back to the same Guid.
So as such...
Is true... Obviously the corresponding long value of the GUID is not easy readable, here are some examples (long = guid):
And yes conversion of those works both ways and for any long value you can think off...
But because you state that:
It is extremely unlikely that you can actually do this, instead it is most likely that the Guid you have is generated with any of the common algorithms, and that will make the Guid unusable in this scenario.
Now does this make any sense to do?... That requires an insight to a specific situation, and is a whole other discussion...
GUID 的长度为 16 个字节。 “长”通常被理解为 64 位(即 8 字节)长。您无法在不丢失或提供额外数据的情况下在这些之间进行转换。
A GUID is 16 bytes long. A "long" is often understood as being 64 bits (i.e. 8 bytes) long. You cannot convert between those without losing or providing extra data.
我知道这个问题确实很老,但它是第一个谷歌结果,我想提供我正在讨论的答案。
Guid 不是 Int64,正如其他人已经说过的那样,而是它的两个 UInt64。
我编写了一个 UInt128 类,具有高 UInt64 和低 UInt64。从那里你需要在这些之间进行转换:
也许它可以帮助某人!
I know this Question is really old, but its the First Google Result, and i wanted to provide the answer im going with.
Guid isnt a Int64 as the others already stated, instead its two UInt64's.
I Wrote a UInt128 Class, with a High, and a Low UInt64. From there you need to just convert between those:
Maybe it helps someone!
您可以使用
Guid
构造函数,这是一个简单但并非完美的示例:第一组最多可以处理
4294967295
(int)。如果您需要更多,则必须使用另一套。每组都是无符号整数的十六进制表示,因此您可以尝试各种可能性。
You can using
Guid
constructor, a simple but not flawless example:The first set can handle up to
4294967295
(int). If you need more than it then you have to use another set.Each set is a hex representation of a unsigned integer, so you can play around with the possibilities.
希望这个代码对你有帮助!
Hope, this code helps you!!!
只要您必须使用不超过 Guid 大小的正整数值进行操作,您就可以将数字转换为 Guid,如下所示:
并将其转换回来,如下所示:
在其他情况下,最好使用上面提到的字节转换。可以在此处查看示例:https://dotnetfiddle.net/Zx7faI
As long as you have to operate with positive integer values that not exceed Guid size, you can convert number to Guid like this:
and convert it back like:
In other cases it is better to use bytes-conversion as mentioned above. Examples can be checked here: https://dotnetfiddle.net/Zx7faI
您可以做的是将长整型(64 位)映射到 GUID(128 位)。
您不能将 GUID(128 位)映射到 long(64 位)。
您真正想要的是将 GUID 映射到 uint128(或 int128)。
当然,将 long 映射到 GUID 需要用零填充 uint128 的上部。
您需要考虑的是 GUID 按字节的特殊排序顺序(每个字节的优先级),以便您可以像使用 long (long = int64) 一样对 GUID 进行范围比较。
为此,你必须看看这个答案:
SQL Server GUID 排序算法
了解如何将 long 映射到ulong 和 int 到 uint,请参阅:
在 C# 中将 ulong 映射到 long?
了解如何将 UInt128 转换为 GUID,请参阅 ToGuidBytes() 和github 上 UInt128.cs 中的 ToGuid() 以及将 long 转换为 UInt128 的方法,请参阅 UInt128.cs 的构造函数。
对于 System.Guid.NewGuid() 请参阅“NextUInt128< /a>":
以及一些测试来证明/检查它是否有效:
BigIntUidTests.cs
买者自负:
我不知道小端机与大端机将如何影响结果。
What you can do is map a long (64 bit) to a GUID (128 bit).
What you can't do is map a GUID (128 bit) to a long (64 bit).
What you actually want is mapping a GUID to a uint128 (or a int128).
Of course, mapping a long to a GUID requires a fillup of the upper part of uint128 with a zero.
What you need to consider is the special sort order of a GUID by its bytes (precendence of each byte), so that you can range-compare your GUIDs like you can with a long (long = int64).
For that you have to look at this answer:
SQL Server GUID sort algorithm
For how to map a long to a ulong, and a int to a uint, see:
Mapping a ulong to a long in C#?
For how to convert a UInt128 to a GUID, see ToGuidBytes() and ToGuid() in UInt128.cs on github and for converting a long into a UInt128, see the constructor of UInt128.cs.
For System.Guid.NewGuid() see "NextUInt128":
And some tests to proof/check this works:
BigIntUidTests.cs
Caveat emptor:
I don't know how a little vs. big endian machine will influence the result.