.NET Native GUID conversion
Asked Answered
S

3

6

I have an external database that is feeding information to me. One saves their data as native GUID format and my other data source supplies standard .NET GUID format string.

Is there a tidy way to convert from Native GUID to GUID Structure?

Also is there any validation bit to determine if a provided value is a Native GUID or not? I can't seem to find any if there is one.

The difference is as follows:

typedef struct _GUID 
{  
   DWORD Data1;  
   WORD Data2;  
   WORD Data3;  
   BYTE Data4[8];
} GUID;

Data1, Data2 and Data3 get their byte order reversed but Data4 remains the same, see http://en.wikipedia.org/wiki/Globally_unique_identifier for more info

Sulphathiazole answered 9/11, 2011 at 11:56 Comment(4)
Sorry, clueless - what's the difference? Isn't a GUID just 16 bytes of data either way?Boone
The first 8 bytes of a GUID can change their byte endianness, but there doesn't seem to be a clean way in .NET to accept data that has this reversed order. For more info: #1645489Sulphathiazole
Thanks, I'd never seen that. I'd assumed the endianness was mandated like IP stuff. I think it'd be simplest to write your own parser for the hex string for the native case then.Boone
Bit order reversal seems very unlikely. Byte order is possible but still a stretch. Ultimately it is up to the data provider you use to make this conversion. Contact the vendor for support. Don't discount the possibility of a bug in whatever viewer you use to look at the dbase table.Rarefied
B
1

If I understand the question correctly, I posted extension methods that do this in How to read a .NET Guid into a Java UUID.

Beaird answered 14/4, 2012 at 0:7 Comment(0)
J
17

To see if the input is in little Endian or not BitConverter.IsLittleEndinan() helps.

I just had to do this same thing and using Paul Smith's answer above I got it working with this code. Derived off his code but with a fix on last byte swap order and condensed to one flip ensuring guid.FlipEndian().FlipEndian() == guid.

C# Code:

public static class Extensions
{
    /// <summary>
    /// A CLSCompliant method to convert a big-endian Guid to little-endian
    /// and vice versa.
    /// The Guid Constructor (UInt32, UInt16, UInt16, Byte, Byte, Byte, Byte,
    ///  Byte, Byte, Byte, Byte) is not CLSCompliant.
    /// </summary>
    [CLSCompliant(true)]
    public static Guid FlipEndian(this Guid guid)
    {
        var newBytes = new byte[16];
        var oldBytes = guid.ToByteArray();

        for (var i = 8; i < 16; i++)
            newBytes[i] = oldBytes[i];

        newBytes[3] = oldBytes[0];
        newBytes[2] = oldBytes[1];
        newBytes[1] = oldBytes[2];
        newBytes[0] = oldBytes[3];
        newBytes[5] = oldBytes[4];
        newBytes[4] = oldBytes[5];
        newBytes[6] = oldBytes[7];
        newBytes[7] = oldBytes[6];

        return new Guid(newBytes);
    }
}

VB.net code (Translated from online service):

Imports System.Runtime.CompilerServices

Module ModuleExtension

    ''' <summary>
    ''' A CLSCompliant method to convert a big-endian Guid to little-endian
    ''' and vice versa.
    ''' The Guid Constructor (UInt32, UInt16, UInt16, Byte, Byte, Byte, Byte,
    '''  Byte, Byte, Byte, Byte) is not CLSCompliant.
    ''' </summary>
    <Extension()>
    Public Function FlipEndian(guid As Guid) As Guid
        Dim newBytes = New Byte(15) {}
        Dim oldBytes = guid.ToByteArray()

        For i As Integer = 8 To 15
            newBytes(i) = oldBytes(i)
        Next

        newBytes(3) = oldBytes(0)
        newBytes(2) = oldBytes(1)
        newBytes(1) = oldBytes(2)
        newBytes(0) = oldBytes(3)
        newBytes(5) = oldBytes(4)
        newBytes(4) = oldBytes(5)
        newBytes(6) = oldBytes(7)
        newBytes(7) = oldBytes(6)

        Return New Guid(newBytes)
    End Function

End Module
Jampacked answered 18/6, 2013 at 12:7 Comment(6)
I had the same problem pulling Binary(16) UUID from MySQL using LINQ (the latter 2 parts of the GUID were as expected, but the first 2 snippets were different). This fcn restores my sanity. Thanks.Defloration
@Jampacked Are you sure about the order? I think it is: 3 2 1 0 5 4 7 6Offenseless
@Andres it's been working for me since I posted this. I literally just used it five minutes back to query active directory. Its been too long since I read the theory of this and can't remember the flip order OTOMH.Jampacked
@Andres - I think, in essence, it is as you suggest. If you look at the array subscripts for oldBytes, it goes .... 5 7 6 which would result in what you are expecting anyway.Diagnostician
much simpler when using Array.Reverse() as ``` var bytes = guid.ToByteArray(); Array.Reverse(bytes, 0, 4); Array.Reverse(bytes, 4, 2); Array.Reverse(bytes, 6, 2); return bytes; ```Enchantress
Just rearrange the bytes in-place. No need to have another byte[] buffer. See #9196051Enchantress
B
1

If I understand the question correctly, I posted extension methods that do this in How to read a .NET Guid into a Java UUID.

Beaird answered 14/4, 2012 at 0:7 Comment(0)
G
0

If in fact you are dealing with Endian issues, you'll have no choice but to parse the string yourself into the constituent parts of the Guid switch the Endianness, and then create a Guid that you would then use.

Gualtiero answered 9/11, 2011 at 13:18 Comment(1)
I suppose I'll have to write my own wrapper to reverse the valuesSulphathiazole

© 2022 - 2024 — McMap. All rights reserved.