Java:将“unsigned”字节转换为int的正确方法

时间:2013-12-25 20:10:02

标签: java int byte

我花了几个小时寻找third-party implementation of stream cipher Rabbit中的错误。有几个错误,但其中一个:

/**
 * @param IV An array of 8 bytes
 */
public void setupIV(final byte[] IV) {
    short[] sIV = new short[IV.length>>1];
    for(int i=0;i<sIV.length;++i) {
        sIV[i] = (short)((IV[i << 1] << 8) | IV[(2 << 1) + 1]);
    }
    setupIV(sIV);
}

这里的问题是字节IV[i << 1]被转换为int,但由于Java没有无符号类型,因此任何值>= 0x80都是错误的。比方说,字节0xff变为0xffffffff,而不是0x000000ff上述代码的作者如何预期。

所以我添加了简单的功能:

   private int byte2int(byte b){
      int ret = b;
      if (ret < 0){
         ret += 256;
      }
      return ret;
   }

它有效,但我想知道这是否是正确的方法来做我需要的?这种解决方案似乎有些愚蠢。

2 个答案:

答案 0 :(得分:7)

我不确定这会有多大帮助,但您可以通过使用0xFF运行二进制AND操作将有符号字节转换为无符号值。

进一步考虑这个逻辑,你可以通过在int上使用相应的操作数运行类似的AND来检查转换后的溢出。当然,这假设您总是期望正数或零值数,或者换句话说无符号数。

(short)(((IV[i << 1] & 0xFF) << 8) | (IV[(2 << 1) + 1] & 0xFF))

以上是将所有内容放在一起的结果,由 Radiodef 提供。

答案 1 :(得分:0)

使用库函数进行此操作(在ByteBuffer类中)。您将能够控制字节序作为奖励。这将依赖于Java创建者的效率。

package tests.StackOverflow.q20776371;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;

public class q20776371 {


    public static void main(String[] args) {

        byte[] bb = { (byte)0xFF, (byte)0x01, (byte)0x02, (byte)0x03 };

        ByteBuffer buffer1 = ByteBuffer.wrap(bb);

        // set endianness
        // buffer1.order(ByteOrder.BIG_ENDIAN);
        // buffer1.order(ByteOrder.LITTLE_ENDIAN);

        ShortBuffer buffer2 = buffer1.asShortBuffer();

        short[] ss = new short[bb.length>>1];
        buffer2.get(ss);

        for(int i=0; i<ss.length; ++i) {
            System.out.println(String.format("%04x", ss[i]));
        }
    }


}