How to Combine Two GUID Values

强颜欢笑 提交于 2019-12-04 17:16:57

Not Pretty, but it works..

 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);
 }

and yes, I can deal with the non-unique-guarantee in my case

What about splitting the Guids into 2 chunks of 8 bytes each, convert them to ulong (8 bytes), XOR combine them and then concat the 2 results.

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());
        }

You can't convert 2 128-bit GUIDs into a 16-bit or 32-bit value and maintain uniqueness. For your stated application (use value in URL) this doesn't seem to make sense, as a given value in the URL could map to any number of GUID combinations. Have you considered this?

The best approach would be to use an URL-shortening lookup where you generate a unique ID and map it to the GUIDs if needed - similarly to bit.ly or tinyurl.com.

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;
    }
}

Assuming you want to generate a 32 byte value you can just concatenate the GUIDs since they are 16 byte each. If you really need a 32 bit value the only solution I see is generating your own 32 bit values and storing the related GUIDs in a database so you can retrieve them later.

Depends on the platform and details of what you are trying to do.

In .NET/C# you could jus take avery simple approach:

var result = g1.GetHashCode() ^ g2.GetHashCode();
AAA

Why not try a simple operator i.e. AND, OR, XOR etc. To combine the two. XOR would be your best bet hear I would imagine as it has the nice property of when xoring the result with either of the two inputs you will get the other.

Edit: having just looked at this solution, there is a problem with it. The values would have to be normalised. Take a look at Vinay's Answer for a better solution.

Here's a one-liner for you:

g1.ToByteArray().Concat(g2.ToByteArray()).GetHashCode()

I actually did have a need to merge two Guids together to create a third Guid. Where the third Guid (not necessarily unique) would be the same regardless of the order the two original Guids were supplied. So I came up with this:

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);
}
public static string Merge(Guid one, Guid two)
    {
        return new List<Guid>() { one, two }
            .OrderBy(x => x.GetHashCode())
            .Select(y => y.ToString().ToLowerInvariant())
            .Aggregate((a, b) => ${a.ToLowerInvariant()}_{b.ToLowerInvariant()}");
    }

So in my situation i needed to maintain order in order to make sure that the 2 Guids could be merged regardless of order. Therefore they have to be ordered. That was step one. Then, it's simply selecting the guids to string and for consitency (super important), I used string.ToLowerInvariant(). Then concatenated them using the .Aggregate function.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!