首页 > Windows开发 > 详细

关于CRC循环冗余校验的总结(C#)

时间:2015-04-06 17:12:32      阅读:216      评论:0      收藏:0      [点我收藏+]

1. 实验要求

(1)通过CRC(循环冗余校对)序列的计算,掌握C#语言中类的静态方法与动态方法的区别。

(2)ShellWindows Form 的通信作为扩展提高内容。

2. 实验内容

  •  主要工作是:设计算法实现CRC序列的计算

 

            CRC的计算过程总结如下:

           1、  设置CRC寄存器,并给其赋值0xffff

           2、  读数据文件,并将数据的第一个8-bit字符与16CRC寄存器的低8位进行异或,并把 结果存入到CRC寄存器中。

           3、  将CRC寄存器的数据右移一位,高位补零,并检查溢出位。

           4、  如果移出位为0,重复第三步;若低位为1CRC寄存器与多项式码(此处取0xA001 即二进制1010 0000 0000 0001)相异或。

           5、  重复第3步与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。

           6、  重复第2至第5步直到所有数据所有数据全部处理完毕。

           7、  最后将寄存器的高8位数值与寄存器的低8位数值交换位置,即得到CRC的最终值。

  • 使用静态方法与动态方法,并比较区别
  • 设计windows 窗口程序

 

3. 详细设计

l 需要设计的主要内容如下:

1) 需要设计计算一次8-bit数据的算法calculate( byte data)

2) 使用文件输入流打开指定路径的文件,并使用readByte()方法,逐字节读入文件,调用上述calculate方法,直到文件尾;

3) 将最终CRC计算数值,高低位换位置,并将结果转化为16进制

 

l 设计好程序流程图如下:

    技术分享

 

l 因此,重点为设计calculate算法:

Calculate()代码如下:以静态方法为例

 

        static ushort CRC = 0xffff;

        static string result;

        // 静态函数计算CRC

        public static void calculate(byte y)

        {

            int count = 0;    // 统计移位次数

            ushort z = (ushort)(CRC ^ y);

            int temp = z;       // 移位前的数

            int temp2;

            while (count < 8)

            {

                temp2 = temp >> 1;  // 移位后的数

                count++;

                if (temp2 * 2 == temp) // 溢出的为0

                {

                    temp = temp2;

                }

                else  // 溢出的为1

                {

                    temp = temp2 ^ 0xA001;

                }

            }

            CRC = (ushort)temp;

        }

l 剩下的只需在main 函数中打开输入文件流,并读入数据,迭代计算即可

 

 

 

 

 

 

4. 上机实验步骤

l 调试的过程:

1、打开文件输出流,创建文本文件,将byte a = 02byte b = 07, 输出到该文件中,准备测试。

 技术分享

技术分享

 

2、程序调试结果为:

 

技术分享

多组数据验证了程序的正确性。

5. 实验结果

  • 源程序代码如下:

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace CALCULATING_CRC

{

    class Program

    {

        static ushort CRC = 0xffff;

        static string result;

 

        // 静态函数计算CRC

        public static void calculate(byte y)

        {

            int count = 0;    // 统计移位次数

            ushort z = (ushort)(CRC ^ y);

            int temp = z;       // 移位前的数

            int temp2;

            while (count < 8)

            {

                temp2 = temp >> 1;  // 移位后的数

                count++;

                if (temp2 * 2 == temp) // 溢出的为0

                {

                    temp = temp2;

                }

                else  // 溢出的为1

                {

                    temp = temp2 ^ 0xA001;

                }

            }

            CRC = (ushort)temp;

        }

 

        // 非静态函数计算CRC

        public void calculation(byte y)

        {

            int count = 0;

            ushort z = (ushort)(CRC ^ y);

            int temp = z;       // 移位前的数

            int temp2;

            while (count < 8)

            {

                temp2 = temp >> 1;  // 移位后的数

                count++;

                if (temp2 * 2 == temp) // 溢出的为0

                {

                    temp = temp2;

                }

                else  // 溢出的为1

                {

                    temp = temp2 ^ 0xA001;

                }

            }

            CRC = (ushort)temp;

        }

        // 静态函数将10进制数转化为16进制

        public static char changeToH(ref int num1)

        {

            if (num1 > 9)

            {

                return (char)(‘A‘ + num1 - 10);

            }

            else

                return (char)(‘0‘ + num1);

        }

        static void Main(string[] args)

        {

            Program example = new Program();

            ushort x = 0xffff;

            Console.WriteLine("请输入打开文件的路径:");

            string filePath = Console.ReadLine();

            while(!File.Exists(@filePath))  // 打开文件失败

            {

                Console.WriteLine("请重新输入打开文件的路径:");

                filePath = Console.ReadLine();

            } 

            // 文件存在

            FileStream Myfile = new FileStream(filePath, FileMode.Open, FileAccess.Read);

            int readByte = 0;

            readByte = Myfile.ReadByte();

            while (readByte != -1)

            {

                //Program.calculate((byte)readByte);   // 调用静态函数

                example.calculation((byte)readByte);   // 调用非静态函数,需要通过对象实 例调用

                readByte = Myfile.ReadByte();

            }

            Myfile.Close();

            int n1 = CRC % 16;

            CRC /= 16;

            int n2 = CRC % 16;

            CRC /= 16;

            int n3 = CRC % 16;

            CRC /= 16;

            int n4 = CRC % 16;

            // 交换高低位并产生CRC结果

            Program.result = (Program.changeToH(ref n2) + "" + Program.changeToH(ref n1) 

              + "" + Program.changeToH(ref n4) + "" + Program.changeToH(ref n3));

            Console.WriteLine("CRC运算结果:" + Program.result);

        }

    }

}

 

l 控制台应用程序测试数据及结果:(打开文件test2

    技术分享

 

l Windows窗口程序测试及结果:(打开文件test2

 技术分享

技术分享

技术分享

 

6. 结论

过程中遇到的问题:

 

  •  对与byte int short 数据类型的困惑,最后明白异或时对高位不会产生影响,因为int short而言高位补0,0不影响异或结果。
  •  看不懂题,所以百度了循环校验,好费劲
  •  可能在C#中有内置方法方便计算,由于缺乏了解,用到方法都是自己定义

学到的东西

  •   对windows 窗体应用程序的基本结构及开发有了初步的了解
  •   关于静态方法与动态方法:

          1.静态的方法在整个应用程序其间存储在内存中,速度快,但占用内存.  

          2.动态的方法在先声明类实例才能调用类中的方法. 

          3.一般使用频繁的方法用静态方法,用的少的方法用动态的。静态的速度快,占内存。动态的速度相对慢些,但调用完后,立即释放类,可以节省内存,可以根据自己的需要选择是用动态方法还是静态方法。

 

关于CRC循环冗余校验的总结(C#)

原文:http://www.cnblogs.com/1995hxt/p/4396177.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!