将UUID转换为OID,将java代码转换为C#——这是如何工作的

本文关键字:转换 何工作 工作 OID java 代码 UUID | 更新日期: 2023-09-27 18:25:03

我正试图将此代码(来自David Clunie)转换为C#,以便在我的程序中从UUID(或GUID)创建OID

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

我不明白为什么要从UUID的部分中生成long(最小有效位,最大有效位),然后从中生成bigint——为什么不直接生成bigint呢?(因为他总是把最重要的数字移到左边)。

有人能告诉我为什么会这样写吗?(免责声明:我没有尝试运行java代码,我只是尝试在C#中实现它)

[编辑]

事实证明,存在几个问题-正如Kevin Coulombe所指出的,最大的问题是微软存储GUID的字节顺序。java代码似乎按明显的(从左到右)顺序获取字节,但分为两个单独的块,显然(也要感谢Kevin),因为在java中获取整个字节数组没有简单的方法。

这是工作的C#代码,向前和(部分)向后:

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

将UUID转换为OID,将java代码转换为C#——这是如何工作的

我认为他们这样做是因为在Java中没有简单的方法将UUID转换为字节数组以传递给BigInteger。

请参阅:GUID到ByteArray

在C#中,这应该是您正在寻找的:

String oid = "prefix" + "." + new System.Numerics.BigInteger(
        System.Guid.NewGuid().ToByteArray()).ToString();
String oid_prefix = "2.25"
String hexString = "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
UUID uuid = UUID.fromString(hexString);
long leastSignificantBits = uuid.getLeastSignificantBits();
long mostSignificantBits  = uuid.getMostSignificantBits();
mostSignificantBits = mostSignificantBits & Long.MAX_VALUE;
BigInteger decimalValue = BigInteger.valueOf(mostSignificantBits);
decimalValue = decimalValue.setBit(63);
decimalValue = decimalValue.shiftLeft(64);
leastSignificantBits = leastSignificantBits & Long.MAX_VALUE;
BigInteger bigValueLeastSignificantBit = BigInteger.valueOf(leastSignificantBits);
bigValueLeastSignificantBit = bigValueLeastSignificantBit.setBit(63);
decimalValue = decimalValue.or(bigValueLeastSignificantBit);
println "oid is = "+oid_prefix+"."+decimalValue