我一直在与此争斗一段时间,我正在尝试计算字节[]的校验和作为数组中16位字的1s补码和的1s补码。总和相当容易(虽然我确信我可以更高效)但是当我翻转位并获得“负”值时,它的符号扩展到4个字节。按位执行并使用0xff给出正确的值,但因为我试图将校验和包含在另一个字节数组中,所以我需要它作为一个字节。回到一个字节再次给我4字节int。奇怪的是,我可以将这个(4字节)值存储在一个字节数组中并打印它而不会引起问题。有没有办法迫使Java只留下一个带有负号位的字节?在这个特定的例子中,字节是0xef和0xfd。
我的计算校验和的代码是:
public byte[] checksum (byte[] b) {
byte[] check = new byte[3] ;
check[1] += b[0];
check[2] += b[1];
check[1] += b[2];
check[2] += b[3];
check[1] += b[4];
check[2] += b[5];
check[1] += b[6];
check[2] += b[7];
check[1] += b[8];
check[2] += b[9];
check[1] += b[10];
check[2] += b[11];
check[1] += b[12];
check[2] += b[13];
check[1] += b[14];
check[2] += b[15];
check[1] += b[16];
check[2] += b[17];
check[1] += b[18];
check[2] += b[19];
check[2] += check[0] ;
byte[] ret = new byte[2] ;
ret[0] = (byte)~check[1];
ret[1] = (byte)~check[2];
return ret ;
}
再次清楚,这给了我一个大小为2的byte [],其中每个元素似乎是4个字节。
使用
打印返回的数组byte[] r = checksum (b);
for (int i = 0; i < r.length; ++ i) {
System.out.println (String.format("0x%2s", Integer.toHexString(r[i])).replace(' ', '0')) ;
}
显示
0xffffffef
0xfffffffd
这怎么可能,我怎么能避免呢?如果它只是一个显示问题,那很好,但看起来我返回的数组的每个元素实际上都是4个字节。
答案 0 :(得分:6)
问题不在你的字节数组中,而在于你如何打印它。 Integer.toHexString()
需要int
。当您将byte
作为int
传递时,会执行自动扩展转换,其中包括符号扩展。您可以撤消符号扩展的效果,如下所示:
Integer.toHexString(r[i] & 0xFF)