CRC-16-CCITT-FALSE 算法,java与C的生成逻辑

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;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值