I'm trying to convert this code (from David Clunie) to C#, for the purposes of creating OIDs from UUID (or GUID) in my program
public static String createOIDFromUUIDCanonicalHexString(String hexString) throws IllegalArgumentException {
UUID uuid = UUID.fromString(hexString);
long leastSignificantBits = uuid.getLeastSignificantBits();
long mostSignificantBits = uuid.getMostSignificantBits();
BigInteger decimalValue = makeBigIntegerFromUnsignedLong(mostSignificantBits);
decimalValue = decimalValue.shiftLeft(64);
BigInteger bigValueOfLeastSignificantBits = makeBigIntegerFromUnsignedLong(leastSignificantBits);
decimalValue = decimalValue.or(bigValueOfLeastSignificantBits); // not add() ... do not want to introduce question of signedness of long
return OID_PREFIX+"."+decimalValue.toString();
I don't understand why make the longs (leastSignificantBits, mostSignificantBits) from the parts of the UUID, and then make the bigint from them - why not just directly make a BigInt? (since he's shifting the most significant digits left anyway).
Can anyone give me any insight into why this is written the way it is? (disclaimer: I have not tried to run the java code, I'm just trying to implement this in C#)
[EDIT]
Turns out there were several problems - a big one, as Kevin Coulombe points out, is the byte order Microsoft stores GUIDs in. The java code seems to get the bytes in the obvious (left to right) order, but in two separate chunks, apparently (also thanks to Kevin) because there's no easy way to get the whole byte array in Java.
Here is working C# code, forwards and (partially) backwards:
class Program
{
const string OidPrefix = "2.25.";
static void Main(string[] args)
{
Guid guid = new Guid("000000FF-0000-0000-0000-000000000000");
//Guid guid = new Guid("f81d4fae-7dec-11d0-a765-00a0c91e6bf6");
Console.WriteLine("Original guid: " + guid.ToString());
byte[] guidBytes = StringToByteArray(guid.ToString().Replace("-", ""));
BigInteger decimalValue = new BigInteger(guidBytes);
Console.WriteLine("The OID is " + OidPrefix + decimalValue.ToString());
string hexGuid = decimalValue.ToHexString().PadLeft(32, '0');//padded for later use
Console.WriteLine("The hex value of the big int is " + hexGuid);
Guid testGuid = new Guid(hexGuid);
Console.WriteLine("This guid should match the orginal one: " + testGuid);
Console.ReadKey();
}
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
}