这甚至可能吗?我甚至都不认为,但是我看到了一些尝试这样做的代码。但是,我的单元测试表明它无法正常工作。我确实看到了类似的想法:
只是为了澄清。 Guid创作超出了我的控制范围;因此,我不能将值存储在其中一个Guid集中。
答案 0 :(得分:15)
GUID永远不会长,因为, 正如我所说,GUID的大小是16个字节, 长的大小是8个字节。您 高兴地丢掉了8个字节 GUID,即使它们是零! : - )
Guid只是一个128位数据结构,long是一个64位数据结构......
这意味着只要高64位为零,我们就可以安全地丢弃它们,稍后重建它们,因为在这种情况下,零不代表完整数据。所以是的,它是数据丢失,但在某些情况下,它是可以重建的数据丢失。 (考虑压缩)
当你说:
时,这没有什么不同long x = 5000;
//Converting 64 bit data structure into a 32 bit, discarding the upper 32 bits.
int y = (int)x;
//Converting 32 bit data structure into a 64 bit.
long z = (long)y;
这些显式转换不会内置到系统中,因为它不是必须以不同方式进行的。
public static Guid ToGuid(long value)
{
byte[] guidData = new byte[16];
Array.Copy(BitConverter.GetBytes(value), guidData, 8);
return new Guid(guidData);
}
public static long ToLong(Guid guid)
{
if (BitConverter.ToInt64(guid.ToByteArray(), 8) != 0)
throw new OverflowException("Value was either too large or too small for an Int64.");
return BitConverter.ToInt64(guid.ToByteArray(), 0);
}
显然,这绝不应该与GUID一起使用,但只要GUID只有64位的“实际数据”就可以安全使用,最好的方法是确保永远不要在GUID上使用它,除非它们在哪里用很长的时间创建。
作为预防措施,我已经添加了抛出OverflowException,以防Guid在最后64位中实际存储除了0'之外的所有内容,因为生成的long将无法转换回相同的Guid。
所以......
只要创建的guid适合 这很长,有可能吗?它的 只是当它超过了长期的时候 指定大小。正确的吗?
是真的......显然GUID的相应长值不容易阅读,这里有一些例子(long = guid):
1.340 = 0000053c-0000-0000-0000-000000000000
98.605 = 0001812d-0000-0000-0000-000000000000
149.957 = 000249c5-0000-0000-0000-000000000000
218.125.225 = 0d0053a9-0000-0000-0000-000000000000
4.249.596.910 = fd4bb3ee-0000-0000-0000-000000000000
23.139.913.545 = 633f0f49-0005-0000-0000-000000000000
9.223.372.036.854.775.807 = ffffffff-ffff-7fff-0000-000000000000
-9.223.372.036.854.775.808 = 00000000-0000-8000-0000-000000000000
-1 = ffffffff-ffff-ffff-0000-000000000000
是的,那些转换既可以双向运作,也可以考虑任何长期价值......
但是因为你声明:
Guid的创作超出了我的控制范围。
你实际上做这件事的可能性极小,相反,你所拥有的Guid最有可能是用任何常用算法生成的,这会使Guid在这种情况下无法使用。
现在这样做有什么意义吗?......这需要洞察特定情况,并且是另一个讨论...
答案 1 :(得分:9)
GUID长度为16个字节。 “长”通常被理解为64位(即8字节)长。您无法在不丢失或提供额外数据的情况下进行转换。
答案 2 :(得分:1)
我知道这个问题真的很旧,但它是第一个Google结果,我想提供我的答案。
Guid不是其他人已经说过的Int64,而是它的两个UInt64。
我写了一个UInt128类,有一个高,一个低UInt64。从那里你需要在这些之间进行转换:
public static UInt128 ToUInt128(this Guid g)
{
var array = g.ToByteArray();
var hi = BitConverter.ToUInt64(array, 8);
var lo = BitConverter.ToUInt64(array, 0);
return new UInt128(hi, lo);
}
public static Guid ToGuid(this UInt128 i)
{
byte[] data = new byte[16];
Array.Copy(BitConverter.GetBytes(i.hi), 0, data, 8, 8);
Array.Copy(BitConverter.GetBytes(i.lo), 0, data, 0, 8);
return new Guid(data);
}
也许对某人有帮助!
答案 3 :(得分:0)
您可以使用Guid
构造函数,这是一个简单但不完美的示例:
Guid g1;
long g2;
// {00000001-0000-0000-0000-000000000000}
g1 = new Guid(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// 00000001
g2 = Convert.ToInt64(g1.ToString().Split('-')[0]);
// 1 + 5 = 6
g2 += 5;
// {00000006-0000-0000-0000-000000000000}
g1 = new Guid((uint)g2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
第一组最多可以处理4294967295
(int)。如果你需要更多,那么你必须使用另一套。
每个集合都是无符号整数的十六进制表示,因此您可以使用各种可能性。
答案 4 :(得分:0)
public static Guid ToGuid(long value)
{
byte[] bytes = new byte[16];
BitConverter.GetBytes(value).CopyTo(bytes, 0);
return new Guid(bytes);
}
希望,这段代码可以为您提供帮助!
答案 5 :(得分:0)
只要您必须使用不超过 Guid 大小的正整数值进行操作,您就可以像这样将数字转换为 Guid:
var guid = new Guid(ulong.MaxValue.ToString("00000000-0000-0000-0000-000000000000"));
并将其转换回:
var uint64 = Convert.ToUInt64(guid.ToString("N"))
在其他情况下,最好使用上面提到的字节转换。可以在此处查看示例:https://dotnetfiddle.net/Zx7faI