首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# BitConverter to Java

C# BitConverter to Java
EN

Stack Overflow用户
提问于 2017-02-21 14:20:14
回答 2查看 2K关注 0票数 0

我正在尝试将一些使用C#的现有BitConverter代码移植到Java。我已经找到了其他各种线程,但随后出现了一个github类,它似乎可以完成这个任务。但是,ToUInt16与我的C#代码的输出不匹配。ToInt16和ToInt32似乎返回相同的值。你能帮我理解这个实现有什么问题(或者我可能做错了什么)吗?

代码参考:Java BitConverter

ToUInt16:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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片段:

代码语言:javascript
复制
byte[] byteArray = from some byte array
int offset = currentOffset
int msTime = BitConverter.ToUInt16(byteArray, offset)

msTime与来自C#的内容不匹配

C#示例(来自供应商的字符串使用Convert.FromBase64String从字符串中转换)

代码语言:javascript
复制
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#控制台输出字节值:

代码语言:javascript
复制
1
143
0
10

Groovy示例(来自供应商的字符串使用groovy decodeBase64()从字符串中转换)

代码语言:javascript
复制
    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

Groovy来自println中字节值的输出

代码语言:javascript
复制
1
-113
0
10
EN

回答 2

Stack Overflow用户

发布于 2017-02-21 14:53:05

这两种方法之间存在差异。第一个ToUInt16采用大端字节顺序。也就是说,第一个字节是最重要的字节。

但是ToUInt32假设字节顺序很小(这是一个奇怪的选择)。所以第一个字节的意义最小。

修改后的实现如下:

代码语言:javascript
复制
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的更清晰的调用,后者做了同样的事情。)

票数 2
EN

Stack Overflow用户

发布于 2017-03-01 06:08:45

我真正发现的是,ToInt16实际上给了我我想要的结果,而不是解决方案中的ToUInt16。我检查了相当多的结果,它们都与.Net输出相匹配。

我可以看到源代码的@pinkfloydx33 33中的链接实际上是我尝试使用ToInt16而不是ToUInt16的原因。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42369863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档