校驗碼(海明校驗,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.pswp.cn/news/531408.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/531408.shtml
英文地址,請注明出處:http://en.pswp.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…

Codeforces Round #326 (Div. 2) B. Pasha and Phone C. Duff and Weight Lifting

B. Pasha and PhonePasha has recently bought a new phone jPager and started adding his friends phone numbers there. Each phone number consists of exactly n digits. Also Pasha has a number k and two sequences of length n?/?k (n is divisible by k) a1,?a2,?…

vmware中裝的ubuntu上不了網

本文章針對橋接方式進行講解&#xff0c;如果需要另外兩種連接方式請參考文末給出的鏈接 &#xff08;一&#xff09;問題 主機和虛擬機可以相互ping通&#xff0c;但是卻不能ping網址 &#xff08;二&#xff09;解決辦法 vmware為我們提供了三種網絡工作模式&#xff0c;…

document.getElementById()與 $()區別

document.getElementById()返回的是DOM對象&#xff0c;而$()返回的是jQuery對象 什么是jQuery對象&#xff1f; ---就是通過jQuery包裝DOM對象后產生的對象。jQuery對象是jQuery獨有的&#xff0c;其可以使用jQuery里的方法。 比如&#xff1a; $("#test").html() 意…

關于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. 添加以下內容到開發板目錄下的…

c++面試常用知識(sizeof計算類的大小,虛擬繼承,重載,隱藏,覆蓋)

一. sizeof計算結構體 注&#xff1a;本機機器字長為64位 1.最普通的類和普通的繼承 #include<iostream> using namespace std;class Parent{ public:void fun(){cout<<"Parent fun"<<endl;} }; class Child : public Parent{ public:void fun(){…

嵌入式面試題(一)

目錄1 關鍵字volatile有什么含義&#xff1f;并給出三個不同的例子2. c和c中的struct有什么不同&#xff1f;3.進程和線程區別4.ARM流水線5.使用斷言6 .嵌入式系統的定義7 局部變量能否和全局變量重名&#xff1f;8 如何引用一個已經定義過的全局變量&#xff1f;9、全局變量可…

能ping通ip但無法ping通域名和localhost //ping: bad address 'www.baidu.com'

錯誤描述&#xff1a; ~ # ping localhost ping: bad address localhost原因&#xff0c;在/etc目錄下缺少hosts文件&#xff0c;將linux中的/etc hosts文件拷入即可 ~ # ping localhost PING localhost (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: seq0 ttl64 tim…

eclipse導入web項目之后項目中出現小紅叉解決辦法

項目中有小紅叉我遇到的最常見的情況&#xff1a; 1、項目代碼本身有問題。&#xff08;這個就不說了&#xff0c;解決錯誤就OK&#xff09; 2、項目中的jar包丟失。&#xff08;有時候eclipse打開時會出現jar包丟失的情況&#xff0c;關閉eclipse重新打開或者重新引入jar包就O…

arm開發板通過網線連接筆記本電腦上外網

需要工具&#xff1a;arm開發板&#xff0c;網線&#xff0c;一臺雙網卡的win7筆記本電腦&#xff08;筆記本電腦一般都是雙網卡&#xff09; 一、筆記本電腦需要先連上外網&#xff0c;可以連上家里的WIFI&#xff0c;或者手機開熱點&#xff08;本人未測試過連接手機的熱點&…

windows下實現Git在局域網使用

1.首先在主機A上創建一個文件夾用于存放你要公開的版本庫。然后進入這個文件夾&#xff0c;右鍵->Git create repository here&#xff0c;彈出的窗口中勾選Make it Bare&#xff01;之后將這個文件夾完全共享&#xff08;共享都會吧&#xff1f;注意權限要讓使用這個文件夾…

解決linux下QtCreator無法輸入中文的情況

安裝了QtCreator(Qt5.3.1自帶版本)后無法輸入中文&#xff0c;確切的說是無法打開輸入法。以前使用iBus輸入法的時候沒有這個問題&#xff0c;現在使用sougou輸入法才有的這個問題。 可以查看此文 http://www.cnblogs.com/oloroso/p/5114041.html 原因 有問題就得找原因&…

lintcode 滑動窗口的最大值(雙端隊列)

題目鏈接&#xff1a;http://www.lintcode.com/zh-cn/problem/sliding-window-maximum/# 滑動窗口的最大值 給出一個可能包含重復的整數數組&#xff0c;和一個大小為 k 的滑動窗口, 從左到右在數組中滑動這個窗口&#xff0c;找到數組中每個窗口內的最大值。 樣例 給出數組 [1…

你的main函數規范嗎?

在學習c語言的時候&#xff0c;有一個函數一直被我們使用&#xff0c;那就是main函數&#xff0c;但是你知道標準里面是怎么規定它的寫法嗎&#xff1f; 平時看見的main函數有下面這幾種&#xff1a; 1.int main(void){ }2.int main(){ }3.int main(int argc, char *argv[])…

lintcode 最長上升連續子序列 II(二維最長上升連續序列)

題目鏈接&#xff1a;http://www.lintcode.com/zh-cn/problem/longest-increasing-continuous-subsequence-ii/ 最長上升連續子序列 II 給定一個整數矩陣&#xff08;其中&#xff0c;有 n 行&#xff0c; m 列&#xff09;&#xff0c;請找出矩陣中的最長上升連續子序列。&a…