我想组合两个guid值并生成一个32位的字母数字值(可以通过使用散列来完成)。
不漂亮,但它有效..
private static Guid MungeTwoGuids(Guid guid1, Guid guid2)
{
const int BYTECOUNT = 16;
byte[] destByte = new byte[BYTECOUNT];
byte[] guid1Byte = guid1.ToByteArray();
byte[] guid2Byte = guid2.ToByteArray();
for (int i = 0; i < BYTECOUNT; i++)
{
destByte[i] = (byte) (guid1Byte[i] ^ guid2Byte[i]);
}
return new Guid(destByte);
}
是的,在我的情况下,我可以处理非独特保证
如何将Guids分成两个8字节的块,将它们转换为ulong(8字节),XOR组合它们然后连接2个结果。
public static Guid Combine(this Guid x, Guid y)
{
byte[] a = x.ToByteArray();
byte[] b = y.ToByteArray();
return new Guid(BitConverter.GetBytes(BitConverter.ToUInt64(a, 0) ^ BitConverter.ToUInt64(b, 8))
.Concat(BitConverter.GetBytes(BitConverter.ToUInt64(a, 8) ^ BitConverter.ToUInt64(b, 0))).ToArray());
}
您不能将2个128位GUID转换为16位或32位值并保持唯一性。对于您声明的应用程序(URL中的使用值),这似乎没有意义,因为URL中的给定值可以映射到任意数量的GUID组合。你考虑过这个吗?
最好的方法是使用URL缩短查找,您可以在其中生成唯一ID并在需要时将其映射到GUID - 类似于bit.ly或tinyurl.com。
假设您要生成32字节值,您可以只连接GUID,因为它们各为16字节。如果你真的需要32位值,我看到的唯一解决方案是生成自己的32位值并将相关的GUID存储在数据库中,以便稍后检索它们。
取决于平台和您要做的事情的细节。
在.NET / C#中你可以采取一种非常简单的方法:
var result = g1.GetHashCode() ^ g2.GetHashCode();
为什么不尝试一个简单的运算符,即AND,OR,XOR等。将两者结合起来。 XOR将是你最好的选择,因为它具有很好的属性,当用两个输入中的任何一个输出结果时你将得到另一个。
编辑:刚刚看过这个解决方案,它有一个问题。这些值必须标准化。看看Vinay's Answer以获得更好的解决方案。
这是你的单行:
g1.ToByteArray().Concat(g2.ToByteArray()).GetHashCode()
我确实需要将两个Guids合并在一起以创建第三个Guid。如果第三个Guid(不一定是唯一的)将是相同的,无论订单如何,两个原始Guid都被提供。所以我想出了这个:
public static Guid Merge(Guid guidA, Guid guidB)
{
var aba = guidA.ToByteArray();
var bba = guidB.ToByteArray();
var cba = new byte[aba.Length];
for (var ix = 0; ix < cba.Length; ix++)
{
cba[ix] = (byte)(aba[ix] ^ bba[ix]);
}
return new Guid(cba);
}
var a = Guid.NewGuid();
var b = Guid.NewGuid();
var hashOfXor = Xor(a, b).GetHashCode();
public static Guid Xor(Guid a, Guid b)
{
unsafe
{
Int64* ap = (Int64*) &a;
Int64* bp = (Int64*) &b;
ap[0] ^= bp[0];
ap[1] ^= bp[1];
return *(Guid*) ap;
}
}