How to Convert Long to Guid and Vice Versa?

A GUID can never fit a long, because, as I say, a GUID's size is 16 bytes, and a long's size is 8 bytes. You cannoy happily discard 8 bytes off a GUID, even if they are zeroes! :-)

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:

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;

These explicit conversions are not built into the system as it is not so one must do it differently.

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

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...

As long as the guid created fits in the the long, it is possible? It's just when it goes over the long's specified size. Correct?

Is true... Obviously the corresponding long value of the GUID is not easy readable, here are some examples (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

And yes conversion of those works both ways and for any long value you can think off...

But because you state that:

The Guid creation is outside of my control.

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...


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.