Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
102 views
in Technique[技术] by (71.8m points)

c# - Convert from Oracle's RAW(16) to .NET's GUID

I'm having difficulties manually debugging an .NET application where the Guid values differ from .NET to Oracle.

  • Where C# reads:
    • 17D89D326C2142D69B989F5201288DBF
  • Oracle reads:
    • 329DD817216CD6429B989F5201288DBF

How would I be able to manually debug, i.e., from C#'s GUID be able to paste that value in an oracle query and get the correct results (and viceversa)?

question from:https://stackoverflow.com/questions/7289734/convert-from-oracles-raw16-to-nets-guid

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If you look at the values involved (in pairs) of hex digits you can see that the last 7 bytes are the same in both cases, but the first 9 are switched around a bit.

Going from your example, but rewriting each pair in the .NET as 00, 11, 22 etc and switching the relevant byte of Oracle as well we get:

  • .NET:

    00112233445566778899AABBCCDDEEFF
    
  • Oracle:

    33221100554477668899AABBCCFFEEFF
    

So it should be fairly easy to write code to switch round the relevant bytes. (I'm pretty sure I wrote some code to do this in a previous job, in fact.)

To switch round the bytes, you'll just want to call Guid.ToByteArray() and new Guid(byte[]) to get back to a Guid.

EDIT: As it happens, the switch-round above is exactly what the Guid constructor does when you pass it a byte array:

using System;
using System.Linq;

class Test
{
    static void Main()
    {
        byte[] bytes = Enumerable.Range(0, 16)
                                 .Select(x => x * 16 + x)
                                 .Select(x => (byte) x)
                                 .ToArray();

        Console.WriteLine(BitConverter.ToString(bytes).Replace("-", ""));
        Console.WriteLine(new Guid(bytes).ToString().Replace("-", ""));
    }
}

Prints:

00112233445566778899AABBCCDDEEFF
33221100554477668899aabbccddeeff

That may well make it considerably simpler to perform the switching... how were you getting hold of the values to start with? Is it just "how they're displayed in Oracle"?

EDIT: Okay, here are a couple of conversion functions - if you've got the data as text, they'll convert each way...

using System;
using System.Linq;

class Test
{
    static void Main()
    {
        string oracle = "329DD817216CD6429B989F5201288DBF";
        string dotNet = "17D89D326C2142D69B989F5201288DBF";

        Console.WriteLine(oracle == DotNetToOracle(dotNet));
        Console.WriteLine(dotNet == OracleToDotNet(oracle));
    }

    static string OracleToDotNet(string text)
    {
        byte[] bytes = ParseHex(text);
        Guid guid = new Guid(bytes);
        return guid.ToString("N").ToUpperInvariant();
    }

    static string DotNetToOracle(string text)
    {
        Guid guid = new Guid(text);
        return BitConverter.ToString(guid.ToByteArray()).Replace("-", "");
    }

    static byte[] ParseHex(string text)
    {
        // Not the most efficient code in the world, but
        // it works...
        byte[] ret = new byte[text.Length / 2];
        for (int i = 0; i < ret.Length; i++)
        {
            ret[i] = Convert.ToByte(text.Substring(i * 2, 2), 16);
        }
        return ret;
    }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...