最近因为课业需要学习了CRC校验方面的一些知识,经过学习别人的笔记,结合自己的一些思考,对java和c有了新的认识。下面以查表CRC8算法为例:
c版本:
#include <stdio.h>
const unsigned char crc8_tab [] = { 0 , 94 , 188 , 226 , 97 , 63 , 221 , 131 , 194 , 156 , 126 , 32 , 163 , 253 , 31 , 65 , 157 , 195 , 33 , 127 , 252 , 162 , 64 , 30 , 95 , 1 , 227 , 189 , 62 , 96 , 130 , 220 , 35 , 125 , 159 , 193 , 66 , 28 , 254 , 160 , 225 , 191 , 93 , 3 , 128 , 222 , 60 , 98 , 190 , 224 , 2 , 92 , 223 , 129 , 99 , 61 , 124 , 34 , 192 , 158 , 29 , 67 , 161 , 255 , 70 , 24 , 250 , 164 , 39 , 121 , 155 , 197 , 132 , 218 , 56 , 102 , 229 , 187 , 89 , 7 , 219 , 133 , 103 , 57 , 186 , 228 , 6 , 88 , 25 , 71 , 165 , 251 , 120 , 38 , 196 , 154 , 101 , 59 , 217 , 135 , 4 , 90 , 184 , 230 , 167 , 249 , 27 , 69 , 198 , 152 , 122 , 36 , 248 , 166 , 68 , 26 , 153 , 199 , 37 , 123 , 58 , 100 , 134 , 216 , 91 , 5 , 231 , 185 , 140 , 210 , 48 , 110 , 237 , 179 , 81 , 15 , 78 , 16 , 242 , 172 , 47 , 113 , 147 , 205 , 17 , 79 , 173 , 243 , 112 , 46 , 204 , 146 , 211 , 141 , 111 , 49 , 178 , 236 , 14 , 80 , 175 , 241 , 19 , 77 , 206 , 144 , 114 , 44 ,109 , 51 , 209 , 143 , 12 , 82 , 176 , 238 , 50 , 108 , 142 , 208 , 83 , 13 , 239 , 177 , 240 , 174 , 76 , 18 , 145 , 207 , 45 , 115 , 202 , 148 , 118 , 40 , 171 , 245 , 23 , 73 , 8 , 86 , 180 , 234 , 105 , 55 , 213 , 139 , 87 , 9 , 235 , 181 , 54 , 104 , 138 , 212 , 149 , 203 , 41 , 119 , 244 , 170 , 72 , 22 , 233 , 183 , 85 , 11 , 136 , 214 , 52 , 106 , 43 , 117 , 151 , 201 , 74 , 20 , 246 , 168 , 116 , 42 , 200 , 150 , 21 , 75 , 169 , 247 , 182 , 232 , 10 , 84 , 215 , 137 , 107 , 53 };
unsigned char calc_crc8 ( const unsigned char * data , int len ) {unsigned char ret = 0 ;for (; len > 0 ; len -- ) {ret = crc8_tab [ ret ^ * data ];data ++ ;}return ( ret );}
int main ( int argc , const char * argv []){unsigned char d [] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };printf ( "crc8=0x%02x \n " , calc_crc8 ( d , sizeof ( d )));return 0 ;}java版本:可以看到二者大同小异。而唯一的区别就是c中操作数为指针,而java中操作数为byte[]数组。因为java为高级语言所以取消了可以对内存的直接操作的指针,
- public class CRC8 {
- static byte[] crc8_tab = { (byte) 0, (byte) 94, (byte) 188, (byte) 226, (byte) 97, (byte) 63, (byte) 221, (byte) 131, (byte) 194, (byte) 156, (byte) 126, (byte) 32, (byte) 163, (byte) 253, (byte) 31, (byte) 65, (byte) 157, (byte) 195, (byte) 33, (byte) 127, (byte) 252, (byte) 162, (byte) 64, (byte) 30, (byte) 95, (byte) 1, (byte) 227, (byte) 189, (byte) 62, (byte) 96, (byte) 130, (byte) 220, (byte) 35, (byte) 125, (byte) 159, (byte) 193, (byte) 66, (byte) 28, (byte) 254, (byte) 160, (byte) 225, (byte) 191, (byte) 93, (byte) 3, (byte) 128, (byte) 222, (byte) 60, (byte) 98, (byte) 190, (byte) 224, (byte) 2, (byte) 92, (byte) 223, (byte) 129, (byte) 99, (byte) 61, (byte) 124, (byte) 34, (byte) 192, (byte) 158, (byte) 29, (byte) 67, (byte) 161, (byte) 255, (byte) 70, (byte) 24,
- (byte) 250, (byte) 164, (byte) 39, (byte) 121, (byte) 155, (byte) 197, (byte) 132, (byte) 218, (byte) 56, (byte) 102, (byte) 229, (byte) 187, (byte) 89, (byte) 7, (byte) 219, (byte) 133, (byte) 103, (byte) 57, (byte) 186, (byte) 228, (byte) 6, (byte) 88, (byte) 25, (byte) 71, (byte) 165, (byte) 251, (byte) 120, (byte) 38, (byte) 196, (byte) 154, (byte) 101, (byte) 59, (byte) 217, (byte) 135, (byte) 4, (byte) 90, (byte) 184, (byte) 230, (byte) 167, (byte) 249, (byte) 27, (byte) 69, (byte) 198, (byte) 152, (byte) 122, (byte) 36, (byte) 248, (byte) 166, (byte) 68, (byte) 26, (byte) 153, (byte) 199, (byte) 37, (byte) 123, (byte) 58, (byte) 100, (byte) 134, (byte) 216, (byte) 91, (byte) 5, (byte) 231, (byte) 185, (byte) 140, (byte) 210, (byte) 48, (byte) 110, (byte) 237,
- (byte) 179, (byte) 81, (byte) 15, (byte) 78, (byte) 16, (byte) 242, (byte) 172, (byte) 47, (byte) 113, (byte) 147, (byte) 205, (byte) 17, (byte) 79, (byte) 173, (byte) 243, (byte) 112, (byte) 46, (byte) 204, (byte) 146, (byte) 211, (byte) 141, (byte) 111, (byte) 49, (byte) 178, (byte) 236, (byte) 14, (byte) 80, (byte) 175, (byte) 241, (byte) 19, (byte) 77, (byte) 206, (byte) 144, (byte) 114, (byte) 44, (byte) 109, (byte) 51, (byte) 209, (byte) 143, (byte) 12, (byte) 82, (byte) 176, (byte) 238, (byte) 50, (byte) 108, (byte) 142, (byte) 208, (byte) 83, (byte) 13, (byte) 239, (byte) 177, (byte) 240, (byte) 174, (byte) 76, (byte) 18, (byte) 145, (byte) 207, (byte) 45, (byte) 115, (byte) 202, (byte) 148, (byte) 118, (byte) 40, (byte) 171, (byte) 245, (byte) 23, (byte) 73, (byte) 8,
- (byte) 86, (byte) 180, (byte) 234, (byte) 105, (byte) 55, (byte) 213, (byte) 139, (byte) 87, (byte) 9, (byte) 235, (byte) 181, (byte) 54, (byte) 104, (byte) 138, (byte) 212, (byte) 149, (byte) 203, (byte) 41, (byte) 119, (byte) 244, (byte) 170, (byte) 72, (byte) 22, (byte) 233, (byte) 183, (byte) 85, (byte) 11, (byte) 136, (byte) 214, (byte) 52, (byte) 106, (byte) 43, (byte) 117, (byte) 151, (byte) 201, (byte) 74, (byte) 20, (byte) 246, (byte) 168, (byte) 116, (byte) 42, (byte) 200, (byte) 150, (byte) 21, (byte) 75, (byte) 169, (byte) 247, (byte) 182, (byte) 232, (byte) 10, (byte) 84, (byte) 215, (byte) 137, (byte) 107, 53 };
- /**
- * 计算数组的CRC8校验值
- *
- * @param data
- * 需要计算的数组
- * @return CRC8校验值
- */
- public static byte calcCrc8(byte[] data) {
- return calcCrc8(data, 0, data.length, (byte) 0);
- }
- /**
- * 计算CRC8校验值
- *
- * @param data
- * 数据
- * @param offset
- * 起始位置
- * @param len
- * 长度
- * @return 校验值
- */
- public static byte calcCrc8(byte[] data, int offset, int len) {
- return calcCrc8(data, offset, len, (byte) 0);
- }
- /**
- * 计算CRC8校验值
- *
- * @param data
- * 数据
- * @param offset
- * 起始位置
- * @param len
- * 长度
- * @param preval
- * 之前的校验值
- * @return 校验值
- */
- public static byte calcCrc8(byte[] data, int offset, int len, byte preval) {
- byte ret = preval;
- for (int i = offset; i < (offset + len); ++i) {
- ret = crc8_tab[(0x00ff & (ret ^ data[i]))];
- }
- return ret;
- }
- // 测试
- public static void main(String[] args) {
- byte crc = CRC8.calcCrc8(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- System.out.println("" + Integer.toHexString(0x00ff & crc));
- }
- }
但是这就造成了java对于二进制数按位操作的不方便。两种算法看起来差不多但运行结果并不相同,原因是CRC校验是通过原数据逐个移位与生成表达式异或得到最后的校验和,因此需要对data地址++按位偏移。而java按位操作通常通过byte[]数组,而此处byte数组的一次偏移实际上是原数据偏移了8位。因此求出的校验和肯定是错误的。目前没有想到可以用java按位依次操作的方式,还需继续学习!