java:
// CRC-16-CCITT参数
private static final int POLYNOMIAL = 0x1021; // 多项式
private static final int INITIAL_VALUE = 0xFFFF; // 初始值
/**
* 计算数据的CRC-16-CCITT-FALSE校验值
* @param data 待校验的数据
* @return CRC校验值
*/
public static int calculate(byte[] data) {
int crc = INITIAL_VALUE;
for (byte b : data) {
crc ^= (b & 0xFF) << 8;
for (int i = 0; i < 8; i++) {
if ((crc & 0x8000) != 0) {
crc = (crc << 1) ^ POLYNOMIAL;
} else {
crc <<= 1;
}
}
}
return crc & 0xFFFF; // 确保结果为16位
}
/**
* 使用查表法计算CRC-16-CCITT校验值,提高性能
*/
public static class TableBased {
private static final int[] TABLE = new int[256];
static {
// 初始化查找表
for (int i = 0; i < 256; i++) {
int value = 0;
int temp = i << 8;
for (int j = 0; j < 8; j++) {
if (((value ^ temp) & 0x8000) != 0) {
value = (value << 1) ^ POLYNOMIAL;
} else {
value <<= 1;
}
temp <<= 1;
}
TABLE[i] = value;
}
}
/**
* 使用查表法计算CRC-16-CCITT-FALSE校验值
* @param data 待校验的数据
* @return CRC校验值
*/
public static int calculate(byte[] data) {
int crc = INITIAL_VALUE;
for (byte b : data) {
int index = ((crc >> 8) ^ (b & 0xFF)) & 0xFF;
crc = ((crc << 8) ^ TABLE[index]) & 0xFFFF;
}
return crc;
}
}
// 示例用法
public static void main(String[] args) {
byte[] testData = "123456".getBytes();
int crc1 = calculate(testData);
System.out.printf("CRC-16-CCITT-FALSE校验值 (直接计算): 0x%04X%n", crc1); //0x2EF4
int crc2 = TableBased.calculate(testData);
System.out.printf("CRC-16-CCITT-FALSE校验值 (查表法): 0x%04X%n", crc2); //0x2EF4
}
C
#include <stdio.h>
#include <stdint.h>
#include <string.h>
// CRC-16-CCITT参数
#define POLYNOMIAL 0x1021
#define INITIAL_VALUE 0xFFFF
/**
* 计算数据的CRC-16-CCITT校验值
* @param data 待校验的数据
* @param length 数据长度
* @return CRC校验值
*/
uint16_t crc16_ccitt(const uint8_t *data, size_t length) {
uint16_t crc = INITIAL_VALUE;
for (size_t i = 0; i < length; i++) {
crc ^= (uint16_t)(data[i] << 8);
for (int j = 0; j < 8; j++) {
if (crc & 0x8000) {
crc = (crc << 1) ^ POLYNOMIAL;
} else {
crc <<= 1;
}
}
}
return crc;
}
/**
* 使用查表法计算CRC-16-CCITT校验值,提高性能
*/
uint16_t crc16_ccitt_table(const uint8_t *data, size_t length) {
// CRC-16-CCITT查找表
static const uint16_t table[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
// 这里省略了部分表项,完整表应有256个值
// 实际使用时需要完整的表或动态生成
};
uint16_t crc = INITIAL_VALUE;
for (size_t i = 0; i < length; i++) {
uint8_t index = ((crc >> 8) ^ data[i]) & 0xFF;
crc = (crc << 8) ^ table[index];
}
return crc;
}
/**
* 动态生成CRC-16-CCITT查找表
*/
void generate_crc16_table(uint16_t *table) {
for (int i = 0; i < 256; i++) {
uint16_t value = 0;
uint16_t temp = (uint16_t)(i << 8);
for (int j = 0; j < 8; j++) {
if (((value ^ temp) & 0x8000) != 0) {
value = (value << 1) ^ POLYNOMIAL;
} else {
value <<= 1;
}
temp <<= 1;
}
table[i] = value;
}
}
int main() {
const char *testData = "123456";
size_t length = strlen(testData);
uint16_t crc1 = crc16_ccitt((const uint8_t*)testData, length);
printf("CRC-16-CCITT (直接计算): 0x%04X\n", crc1); //0x2EF4
// 动态生成表并使用
uint16_t table[256];
generate_crc16_table(table);
uint16_t crc2 = 0;
for (size_t i = 0; i < length; i++) {
uint8_t index = ((crc2 >> 8) ^ testData[i]) & 0xFF;
crc2 = (crc2 << 8) ^ table[index];
}
printf("CRC-16-CCITT (动态查表): 0x%04X\n", crc2); //0x2EF4
return 0;
}
343

被折叠的 条评论
为什么被折叠?



