簡體   English   中英

C#BitConverter到Java

[英]C# BitConverter to Java

我正在嘗試將一些使用BitConverter的現有C#代碼移植到Java。 我發現了其他各種線程,但隨后遇到了一個看起來有用的github類。 但是,ToUInt16與我的C#代碼的輸出不匹配。 ToInt16和ToInt32似乎返回相同的值。 您能否幫助我了解此實現的問題(或可能是我做錯了)?

代碼參考: Java BitConverter

ToUInt16:

public static int ToUInt16(byte[] bytes, int offset) {
        int result = (int)bytes[offset+1]&0xff;
        result |= ((int)bytes[offset]&0xff) << 8;
        if(Lysis.bDebug)
            System.out.println(result & 0xffff);
        return result & 0xffff;
    }

ToUInt32:

public static long ToUInt32(byte[] bytes, int offset) {
    long result = (int)bytes[offset]&0xff;
    result |= ((int)bytes[offset+1]&0xff) << 8;
    result |= ((int)bytes[offset+2]&0xff) << 16;
    result |= ((int)bytes[offset+3]&0xff) << 24;
    if(Lysis.bDebug)
        System.out.println(result & 0xFFFFFFFFL);
    return result & 0xFFFFFFFFL;
}

MyCode代碼段:

byte[] byteArray = from some byte array
int offset = currentOffset
int msTime = BitConverter.ToUInt16(byteArray, offset)

msTime與C#的內容不匹配

C#示例(使用Convert.FromBase64String從供應商的字符串轉換為字符串)

byte[] rawData = Convert.FromBase64String(vendorRawData);
    byte[] sampleDataRaw = rawData;

    Assert.AreEqual(15616, sampleDataRaw.Length);

    //Show byte data for msTime
    Console.WriteLine(sampleDataRaw[7]);
    Console.WriteLine(sampleDataRaw[6]);

    //Show byte data for msTime
    Console.WriteLine(sampleDataRaw[14]);
    Console.WriteLine(sampleDataRaw[13]);

    var msTime = BitConverter.ToUInt16(sampleDataRaw, 6);
    var dmWindow = BitConverter.ToUInt16(sampleDataRaw, 13);
    Assert.AreEqual(399, msTime);
    Assert.AreEqual(10, dmWindow);

C#控制台輸出的字節值:

1
143
0
10

Groovy示例(使用groovy encodeBase64()從供應商的字符串轉換為字符串)

    def rawData = vendorRawData.decodeBase64()
    def sampleDataRaw = rawData
    Assert.assertEquals(15616, rawData.length)

    //Show byte data for msTime
    println sampleDataRaw[7]
    println sampleDataRaw[6]

    //Show byte data for dmWindow
    println sampleDataRaw[14]
    println sampleDataRaw[13]

    def msTime = ToUInt16(sampleDataRaw, 6)
    def dmWindow = ToUInt16(sampleDataRaw, 13)
    Assert.assertEquals(399, msTime)
    Assert.assertEquals(10, dmWindow)

**Asserts fail with** 

    399 fro msTime is actually 36609
    10 from dmWindow is actually 2560

從println中的字節值進行Groovy輸出

1
-113
0
10

兩種方法之間存在差異。 第一個ToUInt16假定使用大端字節順序。 即第一個字節是最高有效字節。

但是ToUInt32假定使用ToUInt32字節順序(一個奇怪的選擇)。 因此,第一個字節是最低有效的。

更正后的實現如下所示:

public static long toUInt32(byte[] bytes, int offset) {
    long result = Byte.toUnsignedLong(bytes[offset+3]);
    result |= Byte.toUnsignedLong(bytes[offset+2]) << 8;
    result |= Byte.toUnsignedLong(bytes[offset+1]) << 16;
    result |= Byte.toUnsignedLong(bytes[offset]) << 24;
    return result;
}

數組索引被“反向”的地方。

(我還更改了看上去很笨拙的位掩碼,以使對Byte.toUnsignedLong調用更清晰,這也執行相同的操作。)

我真正發現的是,ToInt16實際上在給我想要的結果,而不是解決方案中的ToUInt16。 我檢查了很多結果,它們都與.Net輸出匹配。

我可以從@ pinkfloydx33看到源代碼的鏈接實際上是促使我嘗試使用ToInt16而不是ToUInt16的鏈接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM