我目前正在编写一个JAVA程序,它必须通过套接字(P3协议)将数据发送到MyLaps解码器。二进制数据必须包括一个2字节的CRC代码。在MyLaps文档中有C代码来计算CRC。它还说WORD被定义为一个无符号的16位类型。
C代码
WORD CRC16Table[256] ;
// initialize the CRC16 table
extern void InitCRC16( void ) {
WORD i, j ;
WORD crc ;
for ( i = 0 ; i < 256 ; i += 1 ) {
for ( crc = i << 8, j = 0 ; j < 8 ; j += 1 )
crc = ( crc << 1 ) ^ ( ( crc & 0x8000 ) ? 0x1021 : 0 ) ;
CRC16Table[ i ] = crc ;
}
}
// calculate the crc of a char array pointed at by p
extern WORD CalcCRC16( unsigned char * p, WORD size ) {
WORD crc = 0xFFFF ;
WORD i ;
for ( i = 0 ; i < size ; i++, p++ ) // for all chars
crc = CRC16Table[ ( ( crc >> 8 ) & 255 ) ] ^ ( crc << 8 ) ^ *p ;
return crc ;
}
我想把这个C代码转换成java代码,因为java不知道无符号的2字节数,所以我使用了char数据类型,它也是2字节的
JAVA代码
// initialize the CRC16 table
public static char[] InitCRC16() {
char i, j;
char crc;
char[] CRC16Table = new char[256];
for (i = 0; i < 256; i++) {
crc = (char) (i << 8);
for (j = 0; j < 8; j++) {
crc = (char) ((crc << 1) ^ (((crc & 0x8000) != 0) ? 0x1021 : 0));
}
CRC16Table[i] = crc;
}
return CRC16Table;
}
// calculate the crc of a char array
public static char CalcCRC16(byte[] p, char[] CRC16Table) {
char CRC;
CRC = 0xFFFF;
for (int ptr = 0; ptr < p.length; ptr++) {
CRC = (char) (CRC16Table[(( (char) CRC >> 8) & 0xFF)] ^ ((char) CRC << 8) ^ p[ptr]);
}
return (char) CRC;
}
发送数据到MyLaps解码器我总是得到一个CRC错误,所以一定是在我从C到JAVA的代码转换中有错误。
有人能帮忙吗?
1条答案
按热度按时间mnemlml81#
在Java版本中有很多不必要的强制转换,这很讽刺,因为问题似乎出在您 * 没有 * 正确地适应所涉及的类型转换的地方之一。
考虑到所涉及的数据类型,这个C代码...
......不等同于此Java代码......
。您不需要这些
(char)
类型转换中的大多数类型转换,但是C版本中的*p
(即Cunsigned char
)与Java版本中的p[ptr]
(即Javabyte
)并不等效(有符号)。在C和Java中,算术操作数都自动提升为int
。在C中,*p
总是以0为前导,但在Java中当p[ptr]
的值为负时,它将以前导1位扩展p[ptr]
。其中一些位位于即使使用逻辑&
操作也会影响结果的数字部分(模拟结果的截断以适合char
)。你似乎想要这个: