RFID数据安全性实验:C#可视化实现奇偶校验、CRC冗余校验、海明码校验

源码下载链接

1.实验介绍

RFID中,读写区域标签间数据通信为保证通信的准确性,常采用奇偶校验、CRC冗余校验、海明码校验。本实验在学生掌握上述编码原理的基础上,设计软件模拟通信过程,实现数据监督码的计算,统计数据传输的结果。

2.实验目的

  • 掌握RFID通信中常采用的数据差错及纠错方法
  • 通过编程实现数据监督码的计算及对接收的数据进行检验

3.实验环境

操作系统:Windows 10

软件环境:Visual Studio 2019

4.实验流程

  • 设计系统工作流程
  • 编程实现
  • 观察实验结果,给出实验结论

5.实验内容

软件要求实现下面功能:

  1. 软件随机生成100个数据,每个数据含有8个二进制位,并且显示。
  2. 计算100个数据对应的监督码(分别实现奇偶校验、CRC冗余校验、海明校验),并显示
  3. 模拟数据传输中的干扰(对100个数据的若干二进制位随机干扰),显示干扰后的结果
  4. 模拟接收方对接收的数据进行校验,显示计算得到的监督码
  5. 判断哪些数据接收有误,哪些数据虽然验证无误但实际有误,统计传输正确率,并以适当的方式加以显示。

参考页面

1.奇偶校验

红色:检测出错误的数据

绿色:校验位正确但数据错误

2.海明校验

 

6.实验步骤 

6.1主页面

 6.2奇偶校验

6.2.1产生随机数函数代码

//获取数字
        public int GetNum(int[] arrNum, int tmp, int minValue, int maxValue, Random ra)
        {
            int n = 0;
            while (n <= arrNum.Length - 1)
            {
                if (arrNum[n] == tmp) //利用循环判断是否有重复
                {
                    tmp = ra.Next(minValue, maxValue); //重新随机获取。
                    GetNum(arrNum, tmp, minValue, maxValue, ra);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
                }
                n++;
            }
            return tmp;
        }
        //产生随机数字
        public int[] GetRandomNum(int num, int minValue, int maxValue)
        {
            Random ra = new Random(unchecked((int)DateTime.Now.Ticks));
            int[] arrNum = new int[num];
            int tmp = 0;
            for (int i = 0; i <= num - 1; i++)
            {
                tmp = ra.Next(minValue, maxValue); //随机取数
                arrNum[i] = GetNum(arrNum, tmp, minValue, maxValue, ra); //取出值赋到数组中
            }
            return arrNum;
        }

6.2.2奇偶校验计算校验位函数代码

//计算校验码
        public string GetNum_jy(int x, string s)
        {
            int jy;
            int sum_1 = 0;
            char[] a = s.ToCharArray();
            for(int i = 0; i < 8; i++)
            {
                if(a[i] == '1')
                {
                    sum_1++;
                }
            }
            if((x == 1 && sum_1 % 2 == 0) || (x == 0 && sum_1 % 2 != 0))
            {
                jy = 1;
            }
            else
            {
                jy = 0;
            }
            return jy.ToString();
        }

6.2.3模拟干扰函数代码

//模拟干扰
        private void Ganrao(string[] bin_r_string)
        {
            int num_c_sum = new Random().Next(0, 10); //出错总数

            Random ran = new Random(unchecked((int)DateTime.Now.Ticks));

            for (int i = 0; i < num_c_sum; i++)
            {
                int num_c = ran.Next(0, 100);   //出错的数
                int num_c_count = ran.Next(1, 3);      //出错位数
                int c1 = ran.Next(8);      //出错的第一位
                int c2 = ran.Next(8);      //出错的第二位
                char[] a = bin_r_string[num_c].ToCharArray();
                //第一位出错
                if (a[c1] == '0')
                {
                    a[c1] = '1';
                }
                else
                {
                    a[c1] = '0';
                }
                if(num_c_count > 1)
                {
                    //第二位出错
                    if (a[c2] == '0')
                    {
                        a[c2] = '1';
                    }
                    else
                    {
                        a[c2] = '0';
                    }
                }

                bin_r_string[num_c] = new string(a);

            }
        }

6.2.4校验代码

private void button4_Click(object sender, EventArgs e)
        {
            this.listView2.BeginUpdate();
            this.listView2.Items.Clear();

            int jo;         //表示奇校验或偶校验
            int sum_right = 0;  //记录正确的数据个数
            int jy_c = 0;       //记录校验位错误个数
            int bin_c = 0;      //记录数据错误个数

            if (comboBox1.Text.Trim() == "奇校验")
            {
                jo = 1;
            }
            else
            {
                jo = 0;
            }

            for (int i = 0; i < 100; i++)
            {
                string n = (i + 1).ToString();  //序号
                jy_r_string[i] = GetNum_jy(jo, bin_r_string[i]);//计算得出校验码
                ListViewItem lvi2 = new ListViewItem(n);
                lvi2.SubItems.Add(bin_r_string[i]);
                lvi2.SubItems.Add(jy_string[i]);
                lvi2.SubItems.Add(jy_r_string[i]);

                if (jy_string[i] != jy_r_string[i])     //校验位错误
                {
                    lvi2.ForeColor = Color.Red;
                    jy_c++;
                }
                else if(bin_string[i] != bin_r_string[i] && jy_string[i] == jy_r_string[i])       //数据错误
                {
                    lvi2.ForeColor = Color.Blue;
                    bin_c++;
                    sum_right++;
                }
                else
                {
                    lvi2.ForeColor = Color.Green;
                    sum_right++;
                }

                this.listView2.Items.Add(lvi2);
            }
            this.listView2.EndUpdate();

            this.textBox1.Clear();
            this.textBox1.Text = ("共传输数据100个,检测通过数据" + sum_right + "个,数据错误" + jy_c + "个,未检测出的错误" + bin_c + "个,出错率" + (jy_c + bin_c) + "%");
        }

6.2.5奇偶校验页面

可以选择奇校验或偶校验

 

正确的数据标为绿色,未检测出的错误数据标为蓝色,检测出的错误数据标为红色。

6.3 CRC冗余校验

6.3.1被除数赋值函数

//为被除数赋初值
        private void Get_bcs(char[] bin_char, char[] bcs)
        {
            for (int j = 0; j < 8 + xl_length; j++)
            {
                if (j < 8)
                {
                    bcs[j] = bin_char[j];
                }
                else
                {
                    bcs[j] = '0';
                }
            }
        }

6.3.2取余运算(计算校验位)函数

//取余运算
        private string Quyu(char[] bcs, char[] xl_char)
        {
            int count = 0;                      //用于记录被除数位数
            char[] jy_char = new char[8];
            for (int j = 0; j < 8 + xl_length-1; j++)
            {
                for(int k = j; k < 8 + xl_length-1; k++)
                {
                    //进行除法
                    if (bcs[k] == '0' && count == 0)
                    {
                        j = k+1;
                        continue;
                    }
                    else
                    {
                        if (bcs[k] != xl_char[count])
                        {
                            bcs[k] = '1';
                        }
                        else
                        {
                            bcs[k] = '0';
                        }
                        count++;
                    }
                    //完成一次除法,归零,进行下一次除法
                    if (count == xl_length)
                    {
                        //判断本次除法过后是否有余数
                        for (int i = j + 1; i < 8 + xl_length - 1; i++)
                        {
                            //判断该位是否为0,并且不是最后一位
                            if (bcs[i] == '0' && i < 8 + xl_length - 2)
                            {
                                continue;
                            }
                            //若该位为0,或该位为最后一位
                            else
                            {
                                if ((8 + xl_length - 1) - i < xl_length)
                                {
                                    int length = (8 + xl_length - 1) - i;//余数位数
                                    if(length == xl_length-1)            //余数位数刚好为校验位数时
                                    {
                                        for(int x = 0; x < length; x++)
                                        {
                                            jy_char[x] = bcs[i];
                                            i++;
                                        }
                                        break;
                                    }
                                    else                                 //余数位数少于校验位数时
                                    {
                                        for (int x = 0; x < xl_length-1; x++)
                                        {
                                            if(x+1 > xl_length-1 - length)
                                            {
                                                jy_char[x] = bcs[i];
                                                i++;
                                            }
                                            else
                                            {
                                                jy_char[x] = '0';
                                            } 
                                        }
                                        break;
                                    }

                                }
                                else
                                {
                                    if (i == 8 + xl_length - 2)
                                    {
                                        for (int x = 0; x < xl_length - 1; x++)
                                        {
                                            jy_char[x] = '0';
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                        count = 0;
                        break;
                    }
                }
                if(jy_char[0] == '0' || jy_char[0] == '1')
                {
                    break;
                }

            }
            string jy_char_string = new string(jy_char);
            return jy_char_string;
        }

6.3.3模拟干扰函数

//模拟干扰
        private void Ganrao(string[] bin_r_string)
        {
            int num_c_sum = new Random().Next(0, 10); //出错总数

            Random ran = new Random(unchecked((int)DateTime.Now.Ticks));

            for (int i = 0; i < num_c_sum; i++)
            {
                int num_c = ran.Next(0, 100);   //出错的数
                int num_c_count = ran.Next(1, 5);      //出错位数
                int c1 = ran.Next(8);      //出错的第一位
                int c2 = ran.Next(8);      //出错的第二位
                int c3 = ran.Next(8);      //出错的第三位
                int c4 = ran.Next(8);      //出错的第四位
                char[] a = bin_r_string[num_c].ToCharArray();
                //第一位出错
                if (a[c1] == '0')
                {
                    a[c1] = '1';
                }
                else
                {
                    a[c1] = '0';
                }
                //第二位出错
                if (num_c_count > 1)
                {
                    if (a[c2] == '0')
                    {
                        a[c2] = '1';
                    }
                    else
                    {
                        a[c2] = '0';
                    }
                }
                //第三位出错
                if(num_c_count > 2)
                {
                    if (a[c3] == '0')
                    {
                        a[c3] = '1';
                    }
                    else
                    {
                        a[c3] = '0';
                    }
                }
                //第四位出错
                if(num_c_count > 3)
                {
                    if (a[c4] == '0')
                    {
                        a[c4] = '1';
                    }
                    else
                    {
                        a[c4] = '0';
                    }
                }                

                bin_r_string[num_c] = new string(a);

            }
        }

6.3.4 计算校验位函数

//计算校验位
        private void button2_Click(object sender, EventArgs e)
        {
            if(textBox1.Text == "请输入二进制序列")
            {
                MessageBox.Show("请输入校验序列");
            }
            else
            {
                xl_string = textBox1.Text;   //校验序列
                char[] xl_char = xl_string.ToCharArray();
                xl_length = xl_char.Length;         //序列长度
                char[] bcs = new char[8 + xl_length]; //被除数

                this.listView1.BeginUpdate();
                this.listView1.Items.Clear();

                for (int i = 0; i < 100; i++)
                {
                    string n = (i + 1).ToString();      //序号
                    char[] bin_char = bin_string[i].ToCharArray();
                    Get_bcs(bin_char, bcs);         //实现当前二进制数的左移,获取被除数
                    jy_string[i] = Quyu(bcs, xl_char);      //取余运算
                    ListViewItem lvi = new ListViewItem(n);
                    lvi.SubItems.Add(bin_string[i]);
                    lvi.SubItems.Add(jy_string[i]);
                    this.listView1.Items.Add(lvi);
                }

                this.listView1.EndUpdate();
            }
        }

6.3.5 CRC冗余校验页面

 

 正确的数据标为绿色,检测出的错误数据标为红色。

6.4 海明校验

6.4.1 返回校验位(P5-P1)函数

//只返回校验位
        public string jy(int[] P, int[] D, char[] bin)
        {
            int j = 7;
            for(int i = 0; i < 8; i++)
            {
                D[i] = Convert.ToInt32(bin[j]) - 48;
                j--;
            }
            P[0] = D[6] ^ D[4] ^ D[3] ^ D[1] ^ D[0];
            P[1] = D[6] ^ D[5] ^ D[3] ^ D[2] ^ D[0];
            P[2] = D[7] ^ D[3] ^ D[2] ^ D[1];
            P[3] = D[7] ^ D[6] ^ D[5] ^ D[4];
            P[4] = P[3] ^ P[2] ^ P[1] ^ P[0] ^ D[7] ^ D[6] ^ D[5] ^ D[4] ^ D[3] ^ D[2] ^ D[1] ^ D[0];
            string a = "";
            a += Convert.ToString(P[0]);
            a += Convert.ToString(P[1]);
            a += Convert.ToString(P[2]);
            a += Convert.ToString(P[3]);
            a += Convert.ToString(P[4]);
            return a;
        }

6.4.2 返回发生数据函数

//返回待发送数据
        public string data_jy(int[] P, int[] D, char[] bin)
        {
            string a = Convert.ToString(P[4]);
            for (int i = 7; i >= 4; i--)
            {
                a += Convert.ToString(D[i]);
            }
            a += Convert.ToString(P[3]);
            for (int i = 3; i >= 1; i--)
            {
                a += Convert.ToString(D[i]);
            }
            a += Convert.ToString(P[2]);
            a += Convert.ToString(D[0]);
            a += Convert.ToString(P[1]);
            a += Convert.ToString(P[0]);
            return a;
        }

6.4.3 返回发送后校验码(S5-S1)函数

//返回发送后校验位
        public string jy_r(int[] H, int[] S, char[] data)
        {
            int j = 12;
            
            for (int i = 0; i < 13; i++)
            {
                H[i] = Convert.ToInt32(data[j]) - 48;
                j--;
            }
            S[0] = H[0] ^ H[10] ^ H[8] ^ H[6] ^ H[4] ^ H[2];
            S[1] = H[1] ^ H[10] ^ H[9] ^ H[6] ^ H[5] ^ H[2];
            S[2] = H[3] ^ H[11] ^ H[6] ^ H[5] ^ H[4];
            S[3] = H[7] ^ H[11] ^ H[10] ^ H[9] ^ H[8];
            S[4] = H[0] ^ H[1] ^ H[2] ^ H[3] ^ H[4] ^ H[5] ^ H[6] ^ H[7] ^ H[8] ^ H[9] ^ H[10] ^ H[11] ^ H[12];
            string c = "";
            for (int i = 4; i >= 0; i--)
                c += Convert.ToString(S[i]);
            return c;
        }

6.4.4模拟干扰函数

private void Ganrao(string[] data_r_string)
        {
            int num_c_sum = new Random().Next(0, 10); //出错总数

            Random ran = new Random(unchecked((int)DateTime.Now.Ticks));

            for (int i = 0; i < num_c_sum; i++)
            {
                int num_c = ran.Next(0, 100);   //出错的数
                int c1 = ran.Next(13);      //出错的位

                char[] a = data_r_string[num_c].ToCharArray();
                
                if (a[c1] == '0')
                {
                    a[c1] = '1';
                }
                else
                {
                    a[c1] = '0';
                }

                data_r_string[num_c] = new string(a);

            }
        }

6.4.5纠正数据函数

//校正数据
        private string jz(string data_r_string, char[] jy_s)
        {
            string data_jz;
            int x = 12;
            char[] data_jz_char = data_r_string.ToCharArray();

            for(int i = 1; i < 5; i++)
            {
                if(jy_s[i] == '1')
                {
                    switch (i)
                    {
                        case 1:
                            x -= 8;
                            break;
                        case 2:
                            x -= 4;
                            break;
                        case 3:
                            x -= 2;
                            break;
                        case 4:
                            x -= 1;
                            break;
                    }
                }   
            }
            //纠正数据
            if (x < 13 && data_jz_char[x + 1] == '1')
            {
                data_jz_char[x + 1] = '0';
            }
            else if(x < 13 && data_jz_char[x + 1] == '0')
            {
                data_jz_char[x + 1] = '1';
            }

            data_jz = new string(data_jz_char);
            return data_jz;
        }

6.4.6数据校验函数

//数据校验
        private void button4_Click(object sender, EventArgs e)
        {
            int item = 0;
            int[] H = new int[13];
            int[] S = new int[5];

            int sum_right = 0;  //记录正确的数据个数
            int jy_c = 0;       //记录错误个数

            //将初始值赋值到受干扰数组中
            for (int i = 0; i < 100; i++)
            {
                data_r_string[i] = data_string[i];
            }

            Ganrao(data_r_string);               //模拟干扰

            this.listView2.BeginUpdate();
            this.listView2.Items.Clear();

            for (int i = 0; i < 100; i++)
            {
                string n = (i + 1).ToString();      //序号
                char[] data_char = data_string[i].ToCharArray();
                char[] data_r_char = data_r_string[i].ToCharArray();
                jy_r_string[i] = jy_r(H, S, data_r_char);

                ListViewItem lvi2 = new ListViewItem(n);
                lvi2.SubItems.Add(data_r_string[i]);
                lvi2.SubItems.Add(jy_r_string[i]);

                char[] jy_s = jy_r_string[i].ToCharArray();
                if (jy_s[0] == '1')
                {
                    lvi2.ForeColor = Color.Red;
                    c[i] = "是";   //S5=1
                    item = 0;
                }
                else
                {
                    item = 1;
                }

                if (item == 0)
                {
                    jy_c++;
                }
                else
                {
                    c[i] = "否";       //S5=0
                    lvi2.ForeColor = Color.Green;
                    sum_right++;
                }

                lvi2.SubItems.Add(c[i]);
                this.listView2.Items.Add(lvi2);
            }

            this.listView2.EndUpdate();

            this.textBox1.Clear();
            this.textBox1.Text = ("共传输数据100个,检测通过数据" + sum_right + "个,数据错误" + jy_c + "个,出错率" + jy_c + "%");
        }

6.4.7海明校验页面

7.实验结果

使用C#可视化实现了随机生成二进制数,奇偶校验,CRC冗余校验,海明码校验。 

  • 12
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力敲代码呀~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值