校验码(海明校验,CRC冗余校验,奇偶校验)

循环冗余校验码

CRC码利用生成多项式为k个数据位产生r个校验位进行编码,其编码长度为n=k+r所以又称 (n,k)码. CRC码广泛应用于数据通信领域和磁介质存储系统中. CRC理论非常复杂,一般书就给个例题,讲讲方法.现在简单介绍下它的原理:

在k位信息码后接r位校验码,对于一个给定的(n,k)码。可以证明(数学高手自己琢磨证明过程)存在一个最高次幂为 n-k=r 的多项式g(x),根据g(x)可以生成k位信息的校验码,g(x)被称为 生成多项式

用C(x)=C(k-1)C(k-2)...C0表示k个信息位,把C(x)左移r位,就是相当于 C(x)*pow(2,r) 给校验位空出r个位来了.给定一个 生成多项式g(x),可以求出一个校验位表达式r(x) 。C(x)*pow(2,r) / g(x) = q(x) + r(x)/g(x) 用C(x)*pow(2,r)去除生成多项式g(x)商为q(x)余数是r(x)。所以有C(x)*pow(2,r) = q(x)*g(x) + r(x)。

C(x)*pow(2,r) + r(x)就是所求的n位CRC码,由上式可以看出它是生成多项式g(x)的倍式.所以如果用得到的n位CRC码去除g(x)如果余数是0,就证明数据正确. 否则可以根据余数知道出错位.
在CRC运算过程中,四则运算采用 mod 2运算(后面介绍),即不考虑进位和借位. 所以上式等价于C(x)*pow(2,r) + r(x) = q(x)*g(x)

继续前先说下基本概念吧.
1.多项式和二进制编码
x的最高次幂位对应二进制数的最高位.以下各位对应多项式的各幂次. 有此幂次项为1,无为0. x的最高幂次为r时, 对应的二进制数有r+1位 例如g(x)=pow(x,4) + pow(x,3) + x + 1 对应二进制编码是 11011

2.生成多项式是发送方和接受方的一个约定,也是一个二进制数,在整个传输过程中,这个数不会变.
在发送方利用 生成多项式 对信息多项式做模2运算生成校验码.
在接受方利用 生成多项式 对收到的 编码多项式 做模2运算校验和纠错.

生成多项式应满足:
a.生成多项式的最高位和最低位必须为1
b.当信息任何一位发生错误时,被生成多项式模2运算后应该使余数不为0
c.不同位发生错误时,应该使余数不同.
d.对余数继续做模2除,应使余数循环.

生成多项式很复杂,不过不用我们生成。

下面给出一些常用的生成多项式表
n k 二进制码(自己根据多项式和二进制编码 的介绍转)
7 4 1011 或 1101
7 3 11011 或 10111
15 11 1011
31 26 100101


3.模2运算
a.加减法法则
0 +/- 0 = 0
0 +/- 1 = 1
1 +/- 0 = 1
1 +/- 1 = 0
注意:没有进位和借位

b.乘法法则
利用模2加求部分积之和,没有进位

c.除法法则
利用模2减求部分余数,没有借位,每商1位则部分余数减1位,余数最高位是1就商1,不是就商0,当部分余数的位数小于余数时,该余数就是最后余数.

例 1110 
1011)1100000
1011
1110
1011
1010
1011
0010(每商1位则部分余数减1位,所以前两个0写出)
0000
010(当部分余数的位数小于余数时,该余数就是最后余数)
最后商是1110余数是010

  好了说了那么多没用的理论.下面讲下CRC的实际应用.例: 给定的生成多项式g(x)=1011, 用(7,4)CRC码对C(x)=1010进行编码.
由题目可以知道下列的信息:
C(x)=1010,n=7,k=4,r=3,g(x)=1011 C(x)*pow(2,3)=1010000 C(x)*pow(2,3) / g(x) = 1001 + 11/1011 所以r(x)=011.所以要求的编码为1010011
例2: 上题中,数据传输后变为1000011,试用纠错机制纠错. 1000011 / g(x) = 1011 + 110/1011

不能整除,所以出错了. 因为余数是110.查1011出错位表可以知道是第5位出错.对其求反即可.

  冗余码的计算方法是,先将信息码后面补0,补0的个数是生成多项式最高次幂;将补零之后的信息码除以G(X),注意除法过程中所用的减法是模2减法,即没有借位的减法,也就是异或运算。当被除数逐位除完时,得到比除数少一位的余数。此余数即为冗余位,将其添加在信息位后便构成CRC码字。

  例如,假设信息码字为11100011,生成多项式G(X)=X^5+X^4+X+1,计算CRC码字。

  G(X) = X^5+X^4+X+1,也就是110011,因为最高次是5,所以,在信息码字后补5个0,变为1110001100000。用1110001100000除以110011,余数为11010,即为所求的冗余位。

  因此发送出去的CRC码字为原始码字11100011末尾加上冗余位11010,即 1110001111010。接收端收到码字后,采用同样的方法验证,即将收到的码字除以G(X),发现余数是0,则认为码字在传输过程中没有出错。

package com.hjzgg.crc;import java.util.ArrayList;public class CrcCheck {/*CRC-4       x4+x+1                  3         ITU G.704CRC-8       x8+x5+x4+1              0x31                   CRC-8       x8+x2+x1+1              0x07                   CRC-8       x8+x6+x4+x3+x2+x1       0x5ECRC-12      x12+x11+x3+x+1          80FCRC-16      x16+x15+x2+1            8005      IBM SDLCCRC16-CCITT x16+x12+x5+1            1021      ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCSCRC-32      x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCSCRC-32c     x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP*/public static final String[] polynomeMsg = {"CRC-4 : x4+x+1", "CRC-8 : x8+x5+x4+1", "CRC-8 : x8+x2+x1+1", "CRC-8 : x8+x6+x4+x3+x2+x1", "CRC-12 : x12+x11+x3+x+1", "CRC-16 : x16+x15+x2+1", "CRC16-CCITT : x16+x12+x5+1","CRC-32 : x32+x26+x23+...+x2+x+1", "CRC-32c : x32+x28+x27+...+x8+x6+1"};private final int bits[] = {4,8,8,8,12,16,16,32,32};private int polynomeChoose = 0;private String msg = null;public String getMsg(){return msg;}public int getPolynomeChoose() {return polynomeChoose;}public void setPolynomeChoose(int polynomeChoose) {this.polynomeChoose = polynomeChoose;}private static final int[] polynome = {0x3, 0x31, 0x07, 0x5E, 0x80F, 0x8005, 0x1021, 0x04C11DB7, 0x1EDC6F41};public void toCrcCode(ArrayList<Integer> code){msg = "信息源码: ";for(int i=0; i<code.size(); ++i)msg += code.get(i);int poly = polynome[polynomeChoose];//选择的多项式int r = bits[polynomeChoose]-1;//多项式的位数for(int i=1; i<=r; ++i)//将原信息扩大 r-1 位,用来填充校验码code.add(0);int crc = 0;//余数int highBit = 1<<r;//获取crc的最高位poly |= highBit;for(int i=0; i<code.size(); ++i){crc |= code.get(i);if((crc&highBit) != 0)//最高位如果是1,则进行模2运算,即异或运算crc ^= poly;crc <<= 1;}crc>>=1;while(r > 0){code.set(code.size()-r, (crc&(1<<(r-1)))==0 ? 0 : 1);--r;}msg += ", CRC校验码: ";for(int i=0; i<code.size(); ++i)msg += code.get(i);}public boolean crcCheck(ArrayList<Integer> code){msg += ", 接收到信息码: ";int poly = polynome[polynomeChoose];//选择的多项式int r = (int)(Math.log(poly)/Math.log(2) + 0.5)+1;//多项式的位数int crc = 0;//余数int highBit = 1<<r;//获取crc的最高位poly |= highBit;for(int i=0; i<code.size(); ++i){msg += code.get(i);crc |= code.get(i);if((crc&highBit) != 0)//最高位如果是1,则进行模2运算,即异或运算crc ^= poly;crc <<= 1;}crc>>=1;if(crc == 0){msg += ", 校验结果: 0, 正确!";return true;}else{ msg += ", 校验结果: " + Integer.toBinaryString(crc) + ", 出错!";return false;}}public static void main(String[] args) {int cd[]={1,0,1,1,0,0,1};ArrayList<Integer> code = new ArrayList<Integer>();for(int i=0; i<cd.length; ++i)code.add(cd[i]);new CrcCheck().toCrcCode(code);}
}
View Code

奇偶校验码

奇偶校验码最简单,但只能检测出奇数位出错. 如果发生偶数位错误就无法检测. 但经研究是奇数位发生错误的概率大很多. 而且奇偶校验码无法检测出哪位出错.所以属于无法矫正错误的校验码。奇偶校验码是奇校验码偶校验码的统称. 它们都是通过在要校验的编码上加一位校验位组成. 如果是奇校验加上校验位后,编码中1的个数为奇数个。如果是偶校验加上校验位后,编码中1的个数为偶数个

例:
原编码 奇校验 偶校验
0000   0000 1 0000 0
0010   0010 0 0010 1
1100   1100 1 1100 0
1010   1010 1 1010 0

如果发生奇数个位传输出错,那么编码中1的个数就会发生变化. 从而校验出错误,要求从新传输数据。目前应用的奇偶校验码有3种.

水平奇偶校验码对每一个数据的编码添加校验位,使信息位与校验位处于同一行.

垂直奇偶校验码把数据分成若干组,一组数据排成一行,再加一行校验码. 针对每一行列采用奇校验 或 偶校验
例: 有32位数据10100101 00110110 11001100 10101011
垂直奇校验 垂直偶校验
10100101    10100101    数据
00110110    00110110
11001100    11001100
10101011    10101011
00001011    11110100    校验

水平垂直奇偶校验码就是同时用水平校验和垂直校验
例:
奇校验奇水平  偶校验 偶水平
 10100101 1     10100101 0   数据
 00110110 1     00110110 0
 11001100 1     11001100 0
 10101011 0     10101011 1
 00001011 0     11110100 1   校验

package com.hjzgg.even_odd_check;import java.util.ArrayList;public class EvenOddCheck {private final boolean EVEN_CHECK = true;private final boolean ODD_CHECK = false;private boolean flag = ODD_CHECK;private String msg = null;public String getMsg(){return msg;}public void setEvenCheck(){flag = EVEN_CHECK;}public void setOddCheck(){flag = ODD_CHECK;}public void toEvenOddCode(ArrayList<Integer> code){msg = "信息源码: ";for(int i=0; i<code.size(); ++i)msg += code.get(i);int cnt1 = 0;//数字1的个数for(int i=0; i<code.size(); ++i)if(code.get(i) == 1)++cnt1;if(flag == EVEN_CHECK){if((cnt1&1) == 1)code.add(0, 1);else code.add(0, 0);} else if(flag == ODD_CHECK){if((cnt1&1) == 1)code.add(0, 0);else code.add(0, 1);}msg += ", 奇偶校验码: ";for(int i=0; i<code.size(); ++i)msg += code.get(i);}public boolean evenOddCheck(ArrayList<Integer> code){msg += ", 接收到信息码: ";int cnt1 = 0;//数字1的个数for(int i=0; i<code.size(); ++i){msg += code.get(i);if(code.get(i) == 1)++cnt1;}if((cnt1&1)==1 && flag == ODD_CHECK || (cnt1&1)==0 && flag==EVEN_CHECK){msg += ", 校验结果: 正确!";return true;} else {msg += ", 校验结果: 错误!";return false;}}public static void main(String[] args) {}}
View Code

                               海明验码

海明码也是利用奇偶性来校验数据的. 它是一种多重奇偶校验检错系统,它通过在数据位之间插入k个校验位,来扩大码距,从而实现检错和纠错.

设原来数据有n位,要加入k位校验码.怎么确定k的大小呢? k个校验位可以有pow(2,k) (代表2的k次方) 个编码,其中有一个代表是否出错. 剩下pow(2,k)-1个编码则用来表示到底是哪一位出错. 因为n个数据位和k个校验位都可能出错,所以k满足pow(2,k)-1 >= n+k。

设 k个校验码为 P1,P2...Pk, n个数据位为D0,D1...Dn 产生的海明码为 H1,H2...H(n+k) 。如有8个数据位,根据pow(2,k)-1 >= n+k可以知道k最小是4。那么得到的海明码是:

H12 H11 H10 H9 H8 H7 H6 H5 H4 H3 H2 H1
D7 D6 D5 D4 P4 D3 D2 D1 P3 D0 P2 P1

然后怎么知道Pi校验哪个位呢. 自己可以列个校验关系表

海明码 下标 校验位组
H1(P1) 1 P1
H2(P2) 2 P2
H3(D0) 1+2 P1,P2
H4(P3) 4 P3
H5(D1) 1+4 P1,P2
H6(D2) 2+4 P2,P3
H7(D3) 1+2+4 P1,P2,P3
H8(P4) 8 P4
H9(D4) 1+8 P1,P4
H10(D5) 2+8 P2,P4
H11(D6) 1+2+8 P1,P2,P4
H12(D7) 4+8 P3,P4

从表中可以看出
P1校验 P1,D0,D1,D3,D4,D6
P2校验 P2,D0,D1,D2,D3,D5,D6
P3校验 P3,D2,D3,D7
P4校验 P4,D4,D5,D6,D7
其实上表很有规律很容易记,要知道海明码Hi由哪些校验组校验,可以把i化成二进制数数中哪些位k是1,就有哪些Pk校验

如H7 7=0111 所以由P1,P2,P3 H11 11=1011 所以由P1,P2,P4 H3 3=0011 所以由P1,P2

那看看Pi的值怎么确定,如果使用偶校验,则
P1=D0 xor D1 xor D3 xor D4 xor D6
P2=D0 xor D1 xor D2 xor D3 xor D5 xor D6
P3=D1 xor D2 xor D3 xor D7
P4=D4 xor D5 xor D6 xor D7
其中xor是异或运算,奇校验的话把偶校验的值取反即可.那怎么校验错误呢. 其实也很简单. 先做下面运算.
G1 = P1 xor D0 xor D1 xor D3 xor D4 xor D6
G2 = P2 xor D0 xor D1 xor D2 xor D3 xor D5 xor D6
G3 = P3 xor D1 xor D2 xor D3 xor D7
G4 = P4 xor D4 xor D5 xor D6 xor D7

package com.hjzgg.hammingcheck;import java.util.ArrayList;
import java.util.Collections;public class HammingCheck {private String msg = null;public String getMsg(){return msg;}private int checkNumber_k(int n){int kk = (int)(Math.log(n)/Math.log(2) + 0.5);for(int k=kk; ; ++k)if(n+k <= (int)(Math.pow(2.0, (double)k)+0.5)-1)return k;}public void toHammingCode(ArrayList<Integer> code){msg = "信息源码: ";for(int i=0; i<code.size(); ++i)msg += code.get(i);Collections.reverse(code);//海明码的编码是从右到左,由小到大的int n = code.size();int k = checkNumber_k(n);int index = 1;for(int i=1; i<=k; ++i){//插入校验位code.add(index-1, 0);index<<=1;}//校验位取值for(int i=0; i<code.size(); ++i){if(((i+1)&i) != 0){//如果这一位不是校验位,也就是数据位int x = i+1;//表示该有效数据是位于串中的几位int p_index = 1;//校验位的索引while(x != 0){if((x&1) == 1)code.set(p_index-1, code.get(p_index-1)^code.get(i));x>>=1;p_index<<=1;//下一个校验位的索引
                }}}Collections.reverse(code);msg += ", 海明校验码: ";for(int i=0; i<code.size(); ++i)msg += code.get(i);}public boolean hammingCheck(ArrayList<Integer> code){msg += ", 接收到信息码: ";Collections.reverse(code);ArrayList<Integer> s = new ArrayList<Integer>();//校验的结果值int k=1;while(k <= code.size()){//si的每一位初值为校验位pi的值s.add(code.get(k-1));k<<=1;}for(int i=0; i<code.size(); ++i){if(((i+1)&i) != 0){//如果这一位不是校验位,也就是数据位int x = i+1;//表示该有效数据是位于串中的第几位int p_index = 1;//校验位的索引while(x != 0){if((x&1) == 1){int s_index = (int)(Math.log(p_index)/Math.log(2.0) + 0.5)+1;//通过校验位找到 对应的校验结果s的索引s.set(s_index-1, s.get(s_index-1)^code.get(i));}x>>=1;p_index<<=1;//下一个校验位的索引
                }}}Collections.reverse(code);int ret = 0;int radix = 1;for(int i=0; i<s.size(); ++i){ret += s.get(i)*radix;radix<<=1;}if(ret == 0){msg += ", 校验结果: 正确!";return true;}else {Collections.reverse(s);msg += ", 校验结果: " +  s + ", 第" + ret + "位出错!";return false;}}public static void main(String[] args) {int cd[]={1,0,1,0};ArrayList<Integer> code = new ArrayList<Integer>();for(int i=0; i<cd.length; ++i)code.add(cd[i]);HammingCheck hc = new HammingCheck();hc.toHammingCode(code);System.out.println("海明码: " + code);//假设cdd中的是接受到的信息,然后利用海明码纠错检验int cdd[]={1, 0, 1, 0, 0, 1, 1};code.clear();for(int i=0; i<cdd.length; ++i)code.add(cdd[i]);hc.hammingCheck(code);}}
View Code

 

执行程序部分:

package com.hjzgg.thread;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;import javax.swing.JOptionPane;import com.hjzgg.frame.MainFrame;public class MyThread implements Runnable{private String xxxCode;private MainFrame mainFrame;private static final Map<String,Integer> mp = new TreeMap<String, Integer>();static{mp.put("HammingCode", 5210);mp.put("CrcCode", 5211);mp.put("EvenOddCode", 5212);}public MyThread(MainFrame mainFrame, String xxxCode){this.mainFrame = mainFrame;this.xxxCode = xxxCode;}@Overridepublic void run() {ServerSocket server=null;Socket socket=null;BufferedReader is = null;if(mp.get(xxxCode) == null) return;try{server = new ServerSocket(mp.get(xxxCode));while(true){socket = server.accept();is = new BufferedReader(new InputStreamReader(socket.getInputStream()));String codeText = is.readLine();ArrayList<Integer> code = new ArrayList<Integer>();for(int i=0; i<codeText.length(); ++i)code.add(Integer.parseInt(""+codeText.charAt(i)));if("HammingCode".equals(xxxCode)){mainFrame.getHc().hammingCheck(code);JOptionPane.showMessageDialog(null, mainFrame.getHc().getMsg(), "海明校验结果", JOptionPane.INFORMATION_MESSAGE);} else if("CrcCode".equals(xxxCode)){mainFrame.getCc().crcCheck(code);JOptionPane.showMessageDialog(null, mainFrame.getCc().getMsg(), "CRC校验结果", JOptionPane.INFORMATION_MESSAGE);} else {mainFrame.getEoc().evenOddCheck(code);JOptionPane.showMessageDialog(null, mainFrame.getEoc().getMsg(), "奇偶校验结果", JOptionPane.INFORMATION_MESSAGE);}}} catch(Exception e){System.out.println("Error:" + e.toString());} finally {try{if(is != null)is.close(); //关闭Socket输入流if(socket != null)socket.close(); //关闭Socketif(server != null)server.close(); //关闭ServerSocket} catch (Exception e){System.out.println("Error:" + e.toString());}}}
}
View Code
package com.hjzgg.frame;import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Random;import com.hjzgg.crc.CrcCheck;
import com.hjzgg.even_odd_check.EvenOddCheck;
import com.hjzgg.hammingcheck.HammingCheck;public class MyActionListener implements ActionListener{private MainFrame mainFrame;public MyActionListener(MainFrame mainFrame){this.mainFrame = mainFrame;}private void myRandom(ArrayList<Integer> code){Random random = new Random();if(random.nextInt()%2 == 0){//出错int index = Math.abs(random.nextInt())%code.size();code.set(index, code.get(index)^1);}}public void actionPerformed(ActionEvent e) {String codeText = mainFrame.getCodeText().getText();ArrayList<Integer> code = new ArrayList<Integer>();for(int i=0; i<codeText.length(); ++i)code.add(Integer.parseInt(""+codeText.charAt(i)));if(e.getActionCommand().equals("hammingBtn")){try{Socket socket=new Socket("127.0.0.1", 5210);PrintWriter os=new PrintWriter(socket.getOutputStream());mainFrame.getHc().toHammingCode(code);myRandom(code);codeText = "";for(int i=0; i<code.size(); ++i)codeText += code.get(i);os.print(codeText);os.flush();socket.close(); //关闭Socket}catch(Exception ex) {System.out.println("Error:"+ex); //出错,则打印出错信息
            }} else if(e.getActionCommand().equals("crcBtn")){try{Socket socket=new Socket("127.0.0.1", 5211);PrintWriter os=new PrintWriter(socket.getOutputStream());mainFrame.getCc().toCrcCode(code);myRandom(code);codeText = "";for(int i=0; i<code.size(); ++i)codeText += code.get(i);os.print(codeText);os.flush();socket.close(); //关闭Socket}catch(Exception ex) {System.out.println("Error:"+ex); //出错,则打印出错信息
            }} else {try{Socket socket=new Socket("127.0.0.1", 5212);PrintWriter os=new PrintWriter(socket.getOutputStream());mainFrame.getEoc().toEvenOddCode(code);myRandom(code);codeText = "";for(int i=0; i<code.size(); ++i)codeText += code.get(i);os.print(codeText);os.flush();socket.close(); //关闭Socket}catch(Exception ex) {System.out.println("Error:"+ex); //出错,则打印出错信息
            }}}
}
View Code

  主程序:

package com.hjzgg.frame;import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.TextField;import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;import com.hjzgg.crc.CrcCheck;
import com.hjzgg.even_odd_check.EvenOddCheck;
import com.hjzgg.hammingcheck.HammingCheck;
import com.hjzgg.thread.MyThread;public class MainFrame extends JFrame{private TextField codeText;//传输的信息码private HammingCheck hc = new HammingCheck();private EvenOddCheck eoc = new EvenOddCheck();private CrcCheck cc = new CrcCheck();public HammingCheck getHc() {return hc;}public EvenOddCheck getEoc() {return eoc;}public CrcCheck getCc() {return cc;}public TextField getCodeText() {return codeText;}private JButton crcBtn = new JButton("CRC冗余校验");private JButton hammingBtn = new JButton("海明校验");private JButton evenOddBtn = new JButton("奇偶校验"); private JComboBox evenOddComboBox=new JComboBox();private JComboBox crcComboBox=new JComboBox();private JComboBox hammingComboBox=new JComboBox();private void init(){JPanel topPanel = new JPanel(), downPanel = new JPanel();topPanel.setPreferredSize(new Dimension(400, 80));topPanel.setBackground(Color.blue);add(topPanel, BorderLayout.NORTH);downPanel.setPreferredSize(new Dimension(400, 180));downPanel.setBackground(Color.green);add(downPanel, BorderLayout.SOUTH);FlowLayout topFlowLayout = new FlowLayout();topFlowLayout.setAlignment(FlowLayout.CENTER);topFlowLayout.setVgap(20);topPanel.setLayout(topFlowLayout);JLabel label = new JLabel("信息码:");label.setForeground(Color.red);topPanel.add(label);codeText = new TextField(50);topPanel.add(codeText);FlowLayout downFlowLayout = new FlowLayout();downFlowLayout.setHgap(10);downPanel.setLayout(downFlowLayout);JPanel evenOddPanel = new JPanel(), crcPanel = new JPanel(), hammingPanel = new JPanel();evenOddPanel.setPreferredSize(new Dimension(90, 150));crcPanel.setPreferredSize(new Dimension(350, 150));hammingPanel.setPreferredSize(new Dimension(90, 150));downPanel.add(evenOddPanel);downPanel.add(crcPanel);downPanel.add(hammingPanel);evenOddPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 30));crcPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 30));hammingPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 30));for(int i=0; i<CrcCheck.polynomeMsg.length; ++i)crcComboBox.addItem(CrcCheck.polynomeMsg[i]);evenOddComboBox.addItem("奇校验");evenOddComboBox.addItem("偶校验");hammingComboBox.addItem("好看而已");crcPanel.add(crcComboBox);evenOddPanel.add(evenOddComboBox);hammingPanel.add(hammingComboBox);evenOddPanel.add(evenOddBtn);crcPanel.add(crcBtn);hammingPanel.add(hammingBtn);MyActionListener mcl = new MyActionListener(this);evenOddBtn.addActionListener(mcl);evenOddBtn.setActionCommand("evenOddBtn");crcBtn.addActionListener(mcl);crcBtn.setActionCommand("crcBtn");hammingBtn.addActionListener(mcl);hammingBtn.setActionCommand("hammingBtn");setBounds(50, 100, 600, 300);setVisible(true);}public MainFrame() throws HeadlessException {super();init();}public MainFrame(String title) throws HeadlessException {super(title);init();}public static void main(String[] args) {// TODO Auto-generated method stubMainFrame mainFrame = new MainFrame();{//开启服务端,准备接受信息码
//            "HammingCode"
//            "CrcCode"
//            "EvenOddCode"new Thread(new MyThread(mainFrame,"HammingCode")).start();new Thread(new MyThread(mainFrame,"CrcCode")).start();new Thread(new MyThread(mainFrame,"EvenOddCode")).start();}}}
View Code

 

实验结果: 有图有真相!

 

理论摘自:http://blog.sina.com.cn/s/blog_03f18e5e0100r25y.html

转载于:https://www.cnblogs.com/hujunzheng/p/4858103.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/531408.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(十二)linux内核定时器

目录&#xff08;一&#xff09;内核定时器介绍&#xff08;二&#xff09;内核定时器相关接口&#xff08;三&#xff09;使用步骤&#xff08;四&#xff09;实例代码&#xff08;一&#xff09;内核定时器介绍 内核定时器并不是用来简单的定时操作&#xff0c;而是在定时时…

java Proxy(代理机制)

我们知道Spring主要有两大思想&#xff0c;一个是IoC&#xff0c;另一个就是AOP&#xff0c;对于IoC&#xff0c;依赖注入就不用多说了&#xff0c;而对于Spring的核心AOP来说&#xff0c;我们不但要知道怎么通过AOP来满足的我们的功能&#xff0c;我们更需要学习的是其底层是怎…

(十三)linux中断底半部分处理机制

这篇文章介绍一下linux中断的底半部分的tasklet和workquene两种处理机制&#xff0c;其中tasklet中不能有延时函数&#xff0c;workquene的处理函数可以加入延时操作 目录&#xff08;一&#xff09;tasklet小任务处理机制&#xff08;1&#xff09;tasklet相关函数接口&#x…

vmware中装的ubuntu上不了网

本文章针对桥接方式进行讲解&#xff0c;如果需要另外两种连接方式请参考文末给出的链接 &#xff08;一&#xff09;问题 主机和虚拟机可以相互ping通&#xff0c;但是却不能ping网址 &#xff08;二&#xff09;解决办法 vmware为我们提供了三种网络工作模式&#xff0c;…

关于gedit的编码问题

今天由于gedit的编码格式导致LCD显示屏的问题&#xff0c;开始没有想到后来才发现&#xff0c;在这记录一下 #include <stdio.h> #include <unistd.h> #include <stdio.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h>…

c语言表白程序代码

双十一要到了&#xff0c;好激动啊&#xff01;&#xff01;&#xff01; 是时候准备出手了&#xff01; 花了一天的时间写的表白代码。 表示自己弱弱的..... 看了网上好多都是js写的&#xff0c;感觉碉堡了&#xff01;js用的不熟&#xff0c;前端不好&#xff0c;java&#x…

tiny4412移植tslib库

1、将tslib-1.4.tar.gz拷贝到虚拟机某个路径进行解压 2、进入解压路径tslib 3、执行#./autogen.sh 如果提示&#xff1a;./autogen.sh: 4: ./autogen.sh: autoreconf: not found 原因&#xff1a;没有安装automake工具, 解决办法:需要安装此工具&#xff1a; apt-get instal…

移植QT到tiny4412开发板

目录&#xff08;一&#xff09; 环境准备&#xff08;二&#xff09; Qt源代码下载&#xff08;三&#xff09; 移植tslib库&#xff08;四&#xff09;操作流程1.解压qt源码包2.配置编译环境3.生成Makefile4.编译安装5.安装一些库用来支持 qt6. 添加以下内容到开发板目录下的…

eclipse导入web项目之后项目中出现小红叉解决办法

项目中有小红叉我遇到的最常见的情况&#xff1a; 1、项目代码本身有问题。&#xff08;这个就不说了&#xff0c;解决错误就OK&#xff09; 2、项目中的jar包丢失。&#xff08;有时候eclipse打开时会出现jar包丢失的情况&#xff0c;关闭eclipse重新打开或者重新引入jar包就O…

windows下实现Git在局域网使用

1.首先在主机A上创建一个文件夹用于存放你要公开的版本库。然后进入这个文件夹&#xff0c;右键->Git create repository here&#xff0c;弹出的窗口中勾选Make it Bare&#xff01;之后将这个文件夹完全共享&#xff08;共享都会吧&#xff1f;注意权限要让使用这个文件夹…

lintcode 滑动窗口的最大值(双端队列)

题目链接&#xff1a;http://www.lintcode.com/zh-cn/problem/sliding-window-maximum/# 滑动窗口的最大值 给出一个可能包含重复的整数数组&#xff0c;和一个大小为 k 的滑动窗口, 从左到右在数组中滑动这个窗口&#xff0c;找到数组中每个窗口内的最大值。 样例 给出数组 [1…

适用于Linux的Windows子系统WSL

以前使用的都是在虚拟机里安装linux&#xff0c;最近才发现在win10提供了WSL(Windows Subsystem for Linux) &#xff0c;简单来说就是可以在win10里面直接使用Linux。 &#xff08;一&#xff09;首先打开Microsoft Store , 搜索 Linux &#xff08;二&#xff09;选择自己需…

jsp通过易宝方式实现在线支付

项目下载地址: https://github.com/hjzgg/OnlinePayment 参考&#xff1a;http://blog.csdn.net/jadyer/article/details/7380259?utm_sourcetuicool&utm_mediumreferral 效果图1&#xff1a;请求界面 效果图2&#xff1a;地支付请求和易宝之间建立连接之后跳转到相应的银…

nand flash和nor flash的这几点区别你知道吗?

这篇文章讲解nand flash和nor flash的特点和区别&#xff0c;不涉及存储原理的讲解 &#xff08;一&#xff09;Flash简介 FLASH是一种存储芯片&#xff0c;全名叫Flash EEPROM Memory&#xff0c;通地过程序可以修改数据&#xff0c;即平时所说的“闪存”。Flash又分为NAND f…

windows8建立局域网的方法

win8建立局域网的方法&#xff1a;1、首先笔记本有无线网卡且支持 虚拟WIFI ;2、按winX键&#xff0c;选择"命令提示符(管理员)A"; 3、输入"netsh wlan set hostednetwork modeallow ssid网络名称 key我的密码" ; 4、接着输入"netsh wlan start hoste…

内核移植出现:Kernel panic - not syncing: No init found.

今天在升级SDK的时候&#xff0c;升级到kernel时遇到如题所述的问题&#xff0c;花了天时间调通&#xff0c;在这里记录一下。 报错提示&#xff1a;(当时没有记录&#xff0c;错误的提示大概如下) Kernel panic - not syncing: No init found. Try passing init option to k…

32位和64位机器上C语言数据类型的大小

作为嵌入式开发的人员&#xff0c;是必须了解C语言在不同位数机器上占用的字节大小的&#xff0c;下面做下对比 不同位数平台对比&#xff1a; \16位平台32位平台64位平台char1个字节8位1个字节8位1个字节short2个字节16位2个字节16位2个字节int2个字节16位4个字节32位 4个字节…

lintcode最长回文子串(Manacher算法)

题目来自lintcode, 链接&#xff1a;http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串&#xff08;假设长度最长为1000&#xff09;&#xff0c;求出它的最长回文子串&#xff0c;你可以假定只有一个满足条件的最长回文串。…

全排列总结

接触全排列已经好长时间了&#xff0c;一直没有抽空总结一下全排列的相关问题&#xff0c;下面来说一下&#xff01; 排列 一般地&#xff0c;从n个不同元素中取出m&#xff08;m≤n&#xff09;个元素&#xff0c;按照一定的顺序排成一列&#xff0c;叫做从n个元素中取出m个元…

大小端问题傻傻分不清?

先来熟悉一下概念&#xff1a; 大端&#xff1a;数据的高位数据保存在低位地址&#xff0c;数据的低位数据保存在高地址 小端&#xff1a;数据的高位数据保存在高位地址&#xff0c;数据的低位数据保存在低地址为什么会存在大小端的问题&#xff1f; 这是因为在计算机系统中&a…