循环冗余码的生成和验证
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、题目
编写一个循环冗余码的生成和验证程序,并实现停等式ARQ,编程实现如何生成CRC码,传输,加入噪声,检错反馈,检测验证,信息重发的过程
二、概要设计
CRC校验码的编码方法是用待发送的二进制数据t(x)除以生成多项式g (x),将最后的余数作为CRC校验码。
其实现步骤如下:
设待发送的数据块是m位的二进制多项式t(x),生成多项式为r阶的g(x)。
在数据块的末尾添加r个0,数据块的长度增加到m+r位,对应的二进制多项式为。
用生成多项式g(x)去除,求得余数为阶数为r-1的二进制多项式y (x)。
此二进制多项式y(x)就是t(x)经过生成多项式g(x)编码的CRC 校验码。
用以模2的方式减去y(x),得到二进制多项式。
就是包含了CRC校验码的待发送字符串。
CRC编码实际上是将代发送的m位二进制多项式t(x)转换成了可以被g(x)除尽的m+r位二进制多项式,所以解码时可以用接受到的数据去除g(x),如果余数位零,则表示传输过程没有错误;如果余数不为零,则在传输过程中肯定存在错误。
CRC码可以看做是由t(x)和CRC校验码的组合,所以解码时将接收到的二进制数据去掉尾部的r位数据,得到的就是原始数据。
三、详细设计
如果生成码是10011
编码:
//reg 是一个5 bits 的寄存器
把reg 中的值置0.
把原始的数据后添加r 个0.
While (数据未处理完)
Begin
If (reg 首位是1)
reg = reg XOR 0011.
把reg 中的值左移一位,读入一个新的数据并置于register 的0 bit 的位置。
End
reg 的后四位就是我们所要求的余数。
解码验错:
//reg 是一个5 bits 的寄存器
把reg 中的值置0.
把循环冗余码作为原始的数据
While (数据未处理完)
Begin
If (reg 首位是1)
reg = reg XOR 0011.
把reg 中的值左移一位,读入一个新的数据并置于register 的0 bit 的位置。
If reg里的数据不为0则要求重发
Else 把循环冗余码去掉后四位即是原始数据
End
四、流程图
五、运行结果
六、心得体会
通过此次编程,我更加了解了循环冗余码,循环冗余校验码又称为多项式码,是一种线性分组码,广泛应用在计算机网络和数据通信中。
CRC码是由两部分组成,前部分是信息码,就是需要校验的信息,后部分是校验码,校验是从数据本身进行检查,它依靠某种数学上约定的形式进行检查,校验的结果是可靠或不可靠,如果可靠就对数据进行处理,如果不可靠,则要进行重发。
CRC 校验由于实现简单,检错能力强,被广泛使用在各种数据校验应用中。
占用系统资源少,
用软硬件均能实现,是进行数据传输差错检测地一种很好的手段。
此次编程,让我更加熟练的使用JAVA,并且让我知道了如何用JAVA来实现模2除法。
此次编程,收获颇丰。
七、源程序清单
import java.util.Random;
import java.awt.Event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.*;
import javax.swing.*;
public class t extends JFrame implements ActionListener {
String str1,ss;
int fla=0;
Panel p1=new Panel();
Panel p2=new Panel();
JLabel lab1=new JLabel("输入");
JTextField t1=new JTextField(20);
JButton bt1=new JButton("确定");
JButton bt2=new JButton("发送");
JButton bt3=new JButton("重输");
JTextArea t2=new JTextArea();
JTextArea t3=new JTextArea();
JScrollPane sp=new JScrollPane(t2,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTA L_SCROLLBAR_NEVER);
JScrollPane sp1=new JScrollPane(t3,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTA L_SCROLLBAR_NEVER);
public t(){
super("编码");
p1.setLayout(new FlowLayout());
p1.add(lab1);
p1.add(t1);
add(p1,"North");
add(sp);
p2.setLayout(new GridLayout(1,3));
p2.add(bt1);
p2.add(bt2);
p2.add(bt3);
add(p2,"South");
bt1.addActionListener((ActionListener) this);
bt2.addActionListener((ActionListener) this);
bt3.addActionListener((ActionListener) this);
setSize(350,350);
setVisible(true);
addWindowListener(new windowclose());
}
void tt2 (){
JFrame frame=new JFrame("解码");
setLayout(new GridLayout(0,1));
frame.add(sp1);
frame.setSize(350,350);
frame.setVisible(true); addWindowListener(new windowclose());
}
public class windowclose extends WindowAdapter{ public void windowClosing(WindowEvent e){ System.exit(0);
}
}
public void actionPerformed(ActionEvent e){ if(e.getActionCommand().equals("确定"))
{
t1.setEditable(false);
}
if(e.getActionCommand().equals("发送"))
{if(fla==0)
tt2();
str1=t1.getText();
send();
}
if(e.getActionCommand().equals("重输"))
{
t1.setText("");
t2.setText("");
ss="";
t1.setEditable(true);
t3.setText("");
fla++;
}
}
private void send() { // 数据处理求余发送int[] dat;
int[] reg = { 1, 0, 0, 1, 1 }; // 生成多项式
int[] res = { 0, 0, 0, 0, 0 }; // 存放校验和
int len1 = str1.length();
char[] a1 = str1.toCharArray();
t2.append("生成多项式是:");
t3.append("生成多项式是:");
for(int i=0;i<reg.length;i++){
t2.append(" "+reg[i]);
t3.append(" "+reg[i]);
}
t2.append("\n");
t3.append("\n");
for (int i = 0; i < len1; i++) {
String str = Integer.toBinaryString(a1[i]);
int len = str.length();
String s1 = "", s2;
dat = new int[len + 4];
for (int n = 0; n < len + 4; n++) {
dat[n] = 0;
}
char[] a2 = str.toCharArray();
for (int n = 0; n < len; n++) {
String s = String.valueOf(a2[n]);
dat[n] = Integer.parseInt(s);
for (int k = 0; k < 5; k++) {
res[k] = dat[k];
}
for (int k = 0; k < len; k++) {
int j = 0;
if (res[j] == 1) {
for (j = 0; j < 4; j++) {
res[j] = res[j + 1] ^ reg[j + 1];
}
} else {
for (j = 0; j < 4; j++) {
res[j] = res[j + 1];
}
}
if (k < len - 1) {
res[4] = dat[k + 5];
}
}
for (int k = 0; k < 4; k++) {
s2 = String.valueOf(res[k]);
s1 = s1.concat(s2);
t2.append("正在发送" + " " + a1[i] + ":" + str + s1 + "\n");
int f = receive(str + s1);// 接收方处理
if (f == 1) {
t2.append(" 发送成功!!" + "\n");
} else {
t2.append(" 发送失败,重发··" + "\n");
i=i-1;
}
}
}
private int receive(String str) { // 接收后校验返回信息
int flag, fg;
int[] dat;
int[] reg = { 1, 0, 0, 1, 1 }; // 生成多项式
int[] res = { 0, 0, 0, 0, 0 }; // 存放校验和
int len = str.length();
dat = new int[len];
char[] a3 = str.toCharArray();
for (int n = 0; n < len; n++) {
String s = String.valueOf(a3[n]);
dat[n] = Integer.parseInt(s);
}
Random random = new Random(); // 产生随机错误if (random.nextInt(9999) % 20 == 0) {
int i = random.nextInt(len - 1);
if (dat[i] == 1)
dat[i] = 0;
else
dat[i] = 1;
}
for (int k = 0; k < 5; k++) {
res[k] = dat[k];
}
for (int k = 0; k < len - 4; k++) { // 校验
int j = 0;
if (res[j] == 1) {
for (j = 0; j < 4; j++) {
res[j] = res[j + 1] ^ reg[j + 1];
}
} else {
for (j = 0; j < 4; j++) {
res[j] = res[j + 1];
}
}
if (k < len - 5) {
res[4] = dat[k + 5];
}
}
for (fg = 0; fg < 4; fg++) {
if (res[fg] != 0)
break;
}
if (fg == 4) // 接收成功则在接受窗口显示
{
t3.append("接收到: " + str + "\n");
flag = 1;
String ch = str.substring(0, len - 4);
Integer aa = Integer.valueOf(ch, 2);
byte[] b = new byte[1];
b[0] = (byte) aa.byteValue();
String s1 = new String(b);
ss = ss + s1;
t3.append(" " + s1 + " 接收成功!!" + "\n"); } else { // 接受失败
String ch = str.substring(0, len - 4);
Integer aa = Integer.valueOf(ch, 2);
byte[] b = new byte[1];
b[0] = (byte) aa.byteValue();
String s1 = new String(b);
flag = 0;
t3.append(""+ s1 +" 接收失败,重传··." +"\n");
}
return flag;
}
public static void main(String[] args){
new t();
}
}。