老师布置了个作业,让我们做一个crc编码解码程序,crc是循环冗余校验的英文简称,在互联网中很常用。
我个人思考问题向来都比较复杂,刚拿到题目,我就想到要经过crc校验的数据会不会很大,考虑到这一点,我采用了字符移位的方法,然而后来的事实证明,这个选择让我吃了不少苦头,字符移位的方法虽然可以处理很大的数据,但是在细节处理方面实在很复杂,移位时不能像数字一样直接移位,必须写一个移位函数(需要头脑清晰)或者是把字符串转化后移位(这个方案几乎不可行,如果你不介意舍近求远的话)。
我写了个移位函数,但是字符的初始化和每次求余后的结果位数和原字符串剩余的位数没有处理好,可能用掩码的方案可以解决,不过我后来还是放弃了,掩码的方案等会会提到。
我最终采用的方案还是舍弃了大数据,虽然输入时还是使用字符获取(也可以直接输入长整型,但是我这一步是为了检验数据的有效性,最后会提到),但是中途转为长整型进行处理,牺牲了一定的时间,不过转为长整型后移位很方便,可以写一个函数将它作为二进制转换成十进制数,然后对转换出的十进制数移位就可以很简单的达到目的,核心代码如下:
- gD<<=mN-gN;
- MASK<<=gN+mN-2;
- printf("%d,%d,%d",gN,mN,MASK);
- }
- for(mD=mD^gD;mD!=0;mD=mD^gD)
- {
- for(i=0;(mD&MASK)!=MASK;i++)
- MASK>>=1;
- gD>>=i;
- if(g>gD)
- break;
- }
当然数据读出时还得将十进制转换成二进制,可以采用递归调用,核心代码如下:
- void result_printf(unsigned s,int n)
- {
- if(n!=1)
- result_printf(s/2,n-1);
- printf("%d",s%2);
- }
该谈谈我读入数据时用字符型的目的了,因为互联网中的数据都是二进制,所以这个程序要作为模拟程序的话必须也要输入数据二进制,所以我特地加了个判断,而且crc的多项式必须满足首尾两位的数据都是一,用字符型的话判断起来很方便。最后,为了给我的老师展示一下我的小创意或者说是我想增加程序的复杂性,我还运用了标号实现程序遇到错误后的循环询问处理,哈哈,最近看内核看多了,部分代码如下:
- #include <setjmp.h>
- jmp_buf jmpbuffer;
- void jmp()
- {
- if(...)longjmp(jmpbuffer, 1);
- }
- void main{
- ...
- }