java实现循环冗余检测 ,计网课程实验 附有源码及APi
CRC使用java实现循环冗余检测 ,计网课程实验
原文链接:CRC生成算法原理原文
一、CRC生成算法原理
1.1 多项式编码
多项式编码(polynomial code),也称为CRC(cyclic redundancy check,循环冗余校验码),多项式编码的思想是:将位串看成是系数为0或1的多项式。CRC校验保护的单位是数据块。数据块的大小根据实际情况而定。每一个数据块均被看作是一个二进制多项式,即所有系数均为二进制(即1或0)的多项式。
当使用多项式编码时,发送方和接受方必须预先商定一个生成多项式(generator polynomial)G(x)。生成多项式的最高位和最低位必须为1。
1.2 CRC原理
将待发送的位串看成系数为 0 或 1 的多项式
收发双方约定一个生成多项式 G(x)
(其最高阶和最低阶系数必须为1),发送方用位串及 G(x)进行某种运算得到校验和,并在帧的末尾加上校验和,使带校验和的帧的多项式能被 G(x) 整除; 接收方收到后,用 G(x) 除多项式,若有余数,则传输有错。
1.3 CRC校验和计算法
1.3.1 若生成多项式 G(x) 为 r 阶(即r+1位位串),原帧为 m 位, 其多项式为 M(x),则在原帧后面添加 r 个 0,即循环左移r位,帧成为 m+r 位,相应多项式成为 xrM(x)xrM(x);
1.3.2按模2除法用 G(x)对应的位串去除对应于xrM(x)xrM(x) 的位串, 得余数 R(x);
1.3.3 按模2减法(即模2加)从对应于 xrM(x)xrM(x)的位串中减去(加上)余数 R(x),结果即传送的带校验和的帧多项式T(x)。
T(x)=xrM(x)+R(x)
T(x)=xrM(x)+R(x)
1.3.4 例子

1.4 CRC冗余检测源码,有java窗体版本
这里使用的是字符串判断实现,没有长度限制,第一次发csdn,各位路过的大佬们轻点,你们的支持就是我最大的动力,感谢!!!
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;/*** @author czy* @create 2021-11-24 8:33*/
public class CRCFrame extends JFrame {private JLabel lbl_1 = new JLabel("请输入二进制字符:");private JLabel lbl_2 = new JLabel("请输入除数:");private JLabel lbl_3 = new JLabel("加零后的被除数:");private JLabel lbl_4 = new JLabel("冗余码:");private JLabel lbl_5 = new JLabel("加冗余码之后的被除数:");private JLabel lbl_6 = new JLabel("验算结果:");private JLabel lbl_7 = new JLabel("输入需要转化为二进制的字符:");private JTextField field_字符串 = new JTextField();private JTextField field_二进制 = new JTextField();private JTextField field_除数 = new JTextField();private JTextField field_加零被除数 = new JTextField();private JTextField field_冗余码 = new JTextField();private JTextField field_加冗余码的被除数 = new JTextField();private JTextField field_结果 = new JTextField();private JButton btn_start = new JButton("开始计算");private JButton btn_start_result = new JButton("开始验算");private JButton btn_start_turn = new JButton("转化为二进制");private JButton btn_clear = new JButton("清空所有");/*** 计算过程面板,注释掉然后吧所有的panel去掉即可,* 其他地方要改就再自己改改*/private JPanel panel = new JPanel();private int count = 0;public CRCFrame() {this.add(lbl_1);this.add(lbl_2);this.add(lbl_3);this.add(lbl_4);this.add(lbl_5);this.add(lbl_6);this.add(lbl_7);this.add(field_字符串);this.add(field_二进制);this.add(field_除数);this.add(field_加零被除数);this.add(field_冗余码);this.add(field_加冗余码的被除数);this.add(field_结果);this.add(btn_start_turn);this.add(btn_start);this.add(btn_start_result);this.add(btn_clear);this.add(panel);field_字符串.setBounds(300, 40, 300, 40);int initx = 150;int inity = 140;int initxx = 300;int inityy = 140;lbl_7.setBounds(initx - 30, inity - 100, 200, 40);lbl_1.setBounds(initx, inity, 200, 40);lbl_2.setBounds(initx, inity + 100, 200, 40);lbl_3.setBounds(initx, inity + 200, 200, 40);lbl_4.setBounds(initx, inity + 300, 200, 40);lbl_5.setBounds(initx, inity + 400, 200, 40);lbl_6.setBounds(initx, inity + 500, 200, 40);field_二进制.setBounds(initxx, inityy, 300, 40);field_除数.setBounds(initxx, inityy + 100, 300, 40);field_加零被除数.setBounds(initxx, inityy + 200, 300, 40);field_冗余码.setBounds(initxx, inityy + 300, 300, 40);field_加冗余码的被除数.setBounds(initxx, inityy + 400, 300, 40);field_结果.setBounds(initxx, inityy + 500, 300, 40);btn_start_turn.setBounds(700, 100, 200, 40);btn_start.setBounds(700, 300, 100, 40);btn_start_result.setBounds(700, 540, 100, 40);btn_clear.setBounds(700, 640, 100, 40);panel.setBounds(1000, 0, 700, 1000);field_二进制.setText("101001");field_除数.setText("1101");//绑定单击事件btn_start.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {count = 0;panel = new JPanel();CRCFrame.this.add(panel);panel.setBounds(1000, 0, 700, 1000);//开始计算结果getResult();}});btn_start_result.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//开始验算getIsNotError();}});btn_start_turn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String s = translateToBinary(field_字符串.getText());field_二进制.setText(s);}});btn_clear.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {clearContents();}});}/*** 冗余检测,求出冗余码*/public void getResult() {System.out.println("开始计算结果");//获取除数String 被除数 = field_二进制.getText().trim();String 除数 = field_除数.getText().trim();for (int i = 0; i < 除数.length() - 1; i++) {被除数 += 0;}field_加零被除数.setText(被除数);showTitle();//101001000//1101System.out.println(field_加零被除数.getText());int current = 0;int str_length = 被除数.length();while (current + 除数.length() != str_length + 1) {除数 = field_除数.getText().trim();//获取当前需要进行计算的字符串String current_str = 被除数.substring(0, 除数.length());//获取剩余的字符串String current_str_residue = 被除数.substring(除数.length());//记录每一次进行模二运算的结果String moer = "";for (int i = 0; i < current_str.length(); i++) {//被除数被选中计算的第一位数大于等于除数,则需要用于计算的是 原除数 ,否则是除数 位数个0,也就是商能不能取1if (Integer.parseInt(current_str.substring(0, 1)) < Integer.parseInt(除数.substring(0, 1))) {int length = 除数.length();除数 = "";for (int i1 = 0; i1 < length; i1++) {//商不能取1之后设置除数除数 += 0;}}String 除数_s = 除数.substring(i, i + 1);String current_s = current_str.substring(i, i + 1);//如果相等if (current_s.equals(除数_s)) {moer += 0;//不相等} else {moer += 1;}}//输出当前需要进行模二运算的字符System.out.println(current_str);System.out.println(除数);System.out.println("====");showDetail(current_str, 除数);//取出n-1位模运算的结果被除数 = moer.substring(1) + current_str_residue;//输出每次的余数System.out.println(被除数);current++;}field_冗余码.setText(被除数);showDetail("", 被除数);field_加冗余码的被除数.setText(field_二进制.getText() + field_冗余码.getText());}/*** 将字符串中的字符逐个读取出来转化为二进制再拼接** @param string* @return*/public String translateToBinary(String string) {char[] strChar = string.toCharArray();String result = "";for (int i = 0; i < strChar.length; i++) {result += Integer.toBinaryString(strChar[i]) + "";}System.out.println(string + "转换为二进制是:\n" + result);return result;}/*** 验算** @return*/public boolean getIsNotError() {System.out.println("\n\n\n开始验算");String 被除数 = field_加冗余码的被除数.getText();String 除数 = field_除数.getText();System.out.println(被除数);int current = 0;int str_length = 被除数.length();while (current + 除数.length() != str_length + 1) {除数 = field_除数.getText();//获取当前需要进行计算的字符串String current_str = 被除数.substring(0, 除数.length());//获取剩余的字符串String current_str_residue = 被除数.substring(除数.length());//记录每一次进行模二运算的结果String moer = "";for (int i = 0; i < current_str.length(); i++) {//被除数被选中计算的第一位数大于等于除数,则需要用于计算的是 原除数 ,否则是除数 位数个0,也就是商能不能取1if (Integer.parseInt(current_str.substring(0, 1)) < Integer.parseInt(除数.substring(0, 1))) {int length = 除数.length();除数 = "";for (int i1 = 0; i1 < length; i1++) {//商不能取1之后设置除数除数 += 0;}}String 除数_s = 除数.substring(i, i + 1);String current_s = current_str.substring(i, i + 1);//如果相等if (current_s.equals(除数_s)) {moer += 0;//不相等} else {moer += 1;}}//输出当前需要进行模二运算的字符System.out.println(current_str);System.out.println(除数);System.out.println("====");//取出n-1位模运算的结果被除数 = moer.substring(1) + current_str_residue;//输出每次的余数System.out.println(被除数);current++;}field_结果.setText(被除数);return false;}/*** 清空所有*/public void clearContents() {field_字符串.setText("");field_二进制.setText("");field_除数.setText("");field_加零被除数.setText("");field_冗余码.setText("");field_加冗余码的被除数.setText("");field_结果.setText("");field_二进制.setText("");field_除数.setText("");}public void showTitle() {JLabel lab = new JLabel("计算过程如下:");JLabel label = new JLabel(field_除数.getText() + " ) " + field_加零被除数.getText());panel.add(lab);panel.add(label);label.setBounds(50, 100, 400, 20);lab.setBounds(50, 70, 400, 20);}/*** 页面显示详细的计算过程*/public void showDetail(String out, String 除数) {System.out.println("");String null_str = "^^^^^ ";for (int i = 0; i < count; i++) {null_str += "^";}JLabel label = new JLabel(null_str + out);JLabel label_1 = new JLabel(null_str + 除数);JLabel label_line = new JLabel("____________________________________");panel.add(label);panel.add(label_1);panel.add(label_line);label.setBounds(50, 120 + count * 60, 400, 20);label_1.setBounds(50, 140 + count * 60, 400, 20);label_line.setBounds(50, 160 + count * 60, 400, 20);count++;}
}
**
代码运行结果
太长的二进制计算会导致计算过程显示不全

如果输入的字符较短时可以得出具体的过程

注意
上面的源码是完整的窗体源码, 需要直接拉取代码的可以去gitee
- CRC冗余检测带窗体版
需要API版本可以点击一下连接直接拉取
- CRC冗余检测带API接口版本,springboot实现
接口访问可以使用
http://localhost:8080/getResult/{{被除数}}/{{除数}}
访问可以得出冗余码
http://localhost:8080/checking/{{被除数}}/{{除数}}
通过手动修改被除数之后,就是在原除数最后添加上冗余码
再进行访问。
结果如图所示
这里的出的冗余码是:011

将冗余添加到最后在进行检测,得出结果是000,这就证明了冗余检测通过,
其中有具体每一步的计算结果(在传输的序列中),可以自行解析json整合到自己的项目中
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
