【IoT物联网平台设备集成】【软件升级】CCITT标准CRC16(1021)算法 Java代码【转】
【摘要】 转自https://blog.csdn.net/ywb201314/article/details/52083036
转自https://blog.csdn.net/ywb201314/article/details/52083036
package
com.jst.util;
/**
* CRC-CCITT 算法校验类
*
* @author amadowang
* @version [版本号, Aug 29, 2011]
* @see [相关类/方法]
* @since [产品/模块版本]
* @date 2012-10-24
*/
public
class
CRCUtil {
/**
* CCITT标准CRC16(1021)余数表 CRC16-CCITT ISO HDLC, ITU X.25, x16+x12+x5+1 多项式
* 高位在先时生成多项式 Gm=0x11021 低位在先时生成多项式,Gm=0x8408 本例采用高位在先
*/
private
static
int
crc16_ccitt_table[] = {
0x0000
,
0x1021
,
0x2042
,
0x3063
,
0x4084
,
0x50a5
,
0x60c6
,
0x70e7
,
0x8108
,
0x9129
,
0xa14a
,
0xb16b
,
0xc18c
,
0xd1ad
,
0xe1ce
,
0xf1ef
,
0x1231
,
0x0210
,
0x3273
,
0x2252
,
0x52b5
,
0x4294
,
0x72f7
,
0x62d6
,
0x9339
,
0x8318
,
0xb37b
,
0xa35a
,
0xd3bd
,
0xc39c
,
0xf3ff
,
0xe3de
,
0x2462
,
0x3443
,
0x0420
,
0x1401
,
0x64e6
,
0x74c7
,
0x44a4
,
0x5485
,
0xa56a
,
0xb54b
,
0x8528
,
0x9509
,
0xe5ee
,
0xf5cf
,
0xc5ac
,
0xd58d
,
0x3653
,
0x2672
,
0x1611
,
0x0630
,
0x76d7
,
0x66f6
,
0x5695
,
0x46b4
,
0xb75b
,
0xa77a
,
0x9719
,
0x8738
,
0xf7df
,
0xe7fe
,
0xd79d
,
0xc7bc
,
0x48c4
,
0x58e5
,
0x6886
,
0x78a7
,
0x0840
,
0x1861
,
0x2802
,
0x3823
,
0xc9cc
,
0xd9ed
,
0xe98e
,
0xf9af
,
0x8948
,
0x9969
,
0xa90a
,
0xb92b
,
0x5af5
,
0x4ad4
,
0x7ab7
,
0x6a96
,
0x1a71
,
0x0a50
,
0x3a33
,
0x2a12
,
0xdbfd
,
0xcbdc
,
0xfbbf
,
0xeb9e
,
0x9b79
,
0x8b58
,
0xbb3b
,
0xab1a
,
0x6ca6
,
0x7c87
,
0x4ce4
,
0x5cc5
,
0x2c22
,
0x3c03
,
0x0c60
,
0x1c41
,
0xedae
,
0xfd8f
,
0xcdec
,
0xddcd
,
0xad2a
,
0xbd0b
,
0x8d68
,
0x9d49
,
0x7e97
,
0x6eb6
,
0x5ed5
,
0x4ef4
,
0x3e13
,
0x2e32
,
0x1e51
,
0x0e70
,
0xff9f
,
0xefbe
,
0xdfdd
,
0xcffc
,
0xbf1b
,
0xaf3a
,
0x9f59
,
0x8f78
,
0x9188
,
0x81a9
,
0xb1ca
,
0xa1eb
,
0xd10c
,
0xc12d
,
0xf14e
,
0xe16f
,
0x1080
,
0x00a1
,
0x30c2
,
0x20e3
,
0x5004
,
0x4025
,
0x7046
,
0x6067
,
0x83b9
,
0x9398
,
0xa3fb
,
0xb3da
,
0xc33d
,
0xd31c
,
0xe37f
,
0xf35e
,
0x02b1
,
0x1290
,
0x22f3
,
0x32d2
,
0x4235
,
0x5214
,
0x6277
,
0x7256
,
0xb5ea
,
0xa5cb
,
0x95a8
,
0x8589
,
0xf56e
,
0xe54f
,
0xd52c
,
0xc50d
,
0x34e2
,
0x24c3
,
0x14a0
,
0x0481
,
0x7466
,
0x6447
,
0x5424
,
0x4405
,
0xa7db
,
0xb7fa
,
0x8799
,
0x97b8
,
0xe75f
,
0xf77e
,
0xc71d
,
0xd73c
,
0x26d3
,
0x36f2
,
0x0691
,
0x16b0
,
0x6657
,
0x7676
,
0x4615
,
0x5634
,
0xd94c
,
0xc96d
,
0xf90e
,
0xe92f
,
0x99c8
,
0x89e9
,
0xb98a
,
0xa9ab
,
0x5844
,
0x4865
,
0x7806
,
0x6827
,
0x18c0
,
0x08e1
,
0x3882
,
0x28a3
,
0xcb7d
,
0xdb5c
,
0xeb3f
,
0xfb1e
,
0x8bf9
,
0x9bd8
,
0xabbb
,
0xbb9a
,
0x4a75
,
0x5a54
,
0x6a37
,
0x7a16
,
0x0af1
,
0x1ad0
,
0x2ab3
,
0x3a92
,
0xfd2e
,
0xed0f
,
0xdd6c
,
0xcd4d
,
0xbdaa
,
0xad8b
,
0x9de8
,
0x8dc9
,
0x7c26
,
0x6c07
,
0x5c64
,
0x4c45
,
0x3ca2
,
0x2c83
,
0x1ce0
,
0x0cc1
,
0xef1f
,
0xff3e
,
0xcf5d
,
0xdf7c
,
0xaf9b
,
0xbfba
,
0x8fd9
,
0x9ff8
,
0x6e17
,
0x7e36
,
0x4e55
,
0x5e74
,
0x2e93
,
0x3eb2
,
0x0ed1
,
0x1ef0
};
/**
*
* @param reg_init CRC校验时初值
* @param message 校验值
* @return
*/
private
static
int
do_crc(
int
reg_init,
byte
[] message) {
int
crc_reg = reg_init;
for
(
int
i =
0
; i < message.length; i++) {
crc_reg = (crc_reg >>
8
) ^ crc16_ccitt_table[(crc_reg ^ message[i]) &
0xff
];
}
return
crc_reg;
}
/**
* 根据数据生成CRC校验码
*
* @param message
* byte数据
*
* @return int 返校验码
*/
private
static
int
do_crc(
byte
[] message) {
// 计算CRC校验时初值从0x0000开始。
int
crc_reg =
0x0000
;
return
do_crc(crc_reg, message);
}
/**
* db44检验方法
*
* @param message 消息内容
* @param crc 检验码值
* @return
*/
private
static
boolean
do_crc(
byte
[] message,
byte
[] crc) {
// 计算CRC校验时初值从0x0000开始。
int
crc_reg =
0x0000
;
int
crc_value = (crc[
0
]&
0xff
)*
256
+(crc[
1
]&
0xff
);
return
crc_value ==do_crc(crc_reg, message);
}
/**
* 供db44结构代码使用,数组后两位为CRC-校验码值
* @param messages
* @return
*/
public
static
boolean
do_crc_db44(
byte
[] messages) {
// 计算CRC校验时初值从0x0000开始。
byte
[] messageArray =
new
byte
[messages.length-
2
];
byte
[] crcArray =
new
byte
[
2
];
System.arraycopy(messages,
0
, messageArray,
0
, messageArray.length);
System.arraycopy(messages, messages.length-
2
, crcArray,
0
,
2
);
return
do_crc(messageArray, crcArray);
}
public
static
void
main(String[] args) {
// 一个db44测试样本数据
byte
p[] = {
71
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
2
,
68
,
31
,
32
,
0
,
1
,
2
};
int
crc = do_crc(p);
// 计算前两位的CRC码
// 65336
System.out.println(crc);
}
}
最后main修改一下:
public static void main(String[] args) {
String test = "FFFE011300000000";
byte p[] = HexParser.parseHexStr2Byte(test);
int crc = do_crc(p); // 计算前两位的CRC码
System.out.println("==> " + Integer.toHexString(crc));
}
运行后的结果是:
也就是说使用“FFFE011300000000”计算出来的校验码是4C9A,把校验码替换到软件升级码流规定的位置得到:FFFE011300000000->FFFE01134C9A0000,这个就是平台下发的查询设备软件版本的码流了。
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)