2010-03-21 180 views
0

我正在计算我需要发送到服务器的数据的16位校验和,它必须重新计算并与提供的校验和进行匹配。我得到的校验和值是在int中,但我只有2个字节用于发送值。所以我将int转换为short,同时调用shortToBytes方法。这工作正常,直到校验和值小于32767之后,我得到负值。java将int转换为short

事情是java没有无符号原语,所以我不能发送大于最大允许值short的值。

我该如何做到这一点,将int转换为short并通过网络发送而不用担心截断并签名为& unsigned int。

同时在两边我有Java程序运行。

private byte[] shortToBytes(short sh) { 
     byte[] baValue = new byte[2]; 
     ByteBuffer buf = ByteBuffer.wrap(baValue); 
     return buf.putShort(sh).array(); 
    } 

    private short bytesToShort(byte[] buf, int offset) { 
     byte[] baValue = new byte[2]; 
     System.arraycopy(buf, offset, baValue, 0, 2); 
     return ByteBuffer.wrap(baValue).getShort(); 
    } 

回答

1

您仍然获得与服务器相同的位值。因此,要查看正确的数值,请将ByteBuffer.wrap(baValue).getShort()替换为ByteBuffer.wrap(baValue).getInt()。这应该给你与服务器相同的数值。

1

首先,Java的intshortbyte类型都签署不无符号。其次,当您将Java int转换为short等时,您将得到无声截断。

这是否重要取决于校验和算法的性质。如果它是一个简单的总和,或者按位算法,那么当使用Java签名整数实现时,该算法很可能会很好。例如,这些“负”16位校验和可能是正确的,当被预期无符号值的东西解释时。

另一方面,乘法和除法的语义是这样的,有符号和无符号的味道必须分开处理。 (至少,这是我从不科学的方式看x86指令集...它有独立的指令有符号与无符号乘法和除法指令推断)

编辑我知道你正在计算CRC- 16。由于可以通过移位和XORing来计算,所以在计算过程中不应该担心有符号数和无符号数。

总之,你没有什么可担心的。

+0

对不起,我忘了具体的校验和是CRC16,所以我没有任何情况下它会有价值,不能适应16位。 – changed 2010-03-21 04:31:53

1

char是一个无符号的16位类型。实际上它是Java中唯一的无符号类型。您可以使用它来计算校验和,然后使用ByteBuffer来获取字节或者简单地使用按位和右移来获取字节。

请注意,byte s已签名。

0

当你说你得到的是负值时,我认为你的意思是当你读取16位值并将其转换为整数。原因在于当short被扩大为int时,符号扩展会导致最高位(即1)被复制。简单的解决方法是按位重新构造整数0xFFFF,这将确保只有最不重要的16位不为零。

+0

不,我的意思是当一个int被截断为在java中短路。 在我的情况下,存储在int中的值永远不会很大,不适合实际的16位短路。 – changed 2010-03-21 04:30:13