循环冗余校验码

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,则认为码字在传输过程中没有出错。

packagecom.hjzgg.crc;importjava.util.ArrayList;public classCrcCheck {/*CRC-4 x4+x+1 3 ITU G.704

CRC-8 x8+x5+x4+1 0x31

CRC-8 x8+x2+x1+1 0x07

CRC-8 x8+x6+x4+x3+x2+x1 0x5E

CRC-12 x12+x11+x3+x+1 80F

CRC-16 x16+x15+x2+1 8005 IBM SDLC

CRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS

CRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS

CRC-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;publicString getMsg(){returnmsg;

}public intgetPolynomeChoose() {returnpolynomeChoose;

}public void setPolynomeChoose(intpolynomeChoose) {this.polynomeChoose =polynomeChoose;

}private static final int[] polynome = {0x3, 0x31, 0x07, 0x5E, 0x80F, 0x8005, 0x1021, 0x04C11DB7, 0x1EDC6F41};public void toCrcCode(ArrayListcode){

msg= "信息源码: ";for(int i=0; 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<

poly |=highBit;for(int i=0; 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<

}

msg+= ", CRC校验码: ";for(int i=0; i

msg+=code.get(i);

}public boolean crcCheck(ArrayListcode){

msg+= ", 接收到信息码: ";int poly = polynome[polynomeChoose];//选择的多项式

int r = (int)(Math.log(poly)/Math.log(2) + 0.5)+1;//多项式的位数

int crc = 0;//余数

int highBit = 1<

poly |=highBit;for(int i=0; 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 voidmain(String[] args) {int cd[]={1,0,1,1,0,0,1};

ArrayList code = new ArrayList();for(int i=0; i

code.add(cd[i]);newCrcCheck().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   校验

packagecom.hjzgg.even_odd_check;importjava.util.ArrayList;public classEvenOddCheck {private final boolean EVEN_CHECK = true;private final boolean ODD_CHECK = false;private boolean flag =ODD_CHECK;private String msg = null;publicString getMsg(){returnmsg;

}public voidsetEvenCheck(){

flag=EVEN_CHECK;

}public voidsetOddCheck(){

flag=ODD_CHECK;

}public void toEvenOddCode(ArrayListcode){

msg= "信息源码: ";for(int i=0; i

msg+=code.get(i);int cnt1 = 0;//数字1的个数

for(int i=0; i

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

msg+=code.get(i);

}public boolean evenOddCheck(ArrayListcode){

msg+= ", 接收到信息码: ";int cnt1 = 0;//数字1的个数

for(int i=0; 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 voidmain(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

packagecom.hjzgg.hammingcheck;importjava.util.ArrayList;importjava.util.Collections;public classHammingCheck {private String msg = null;publicString getMsg(){returnmsg;

}private int checkNumber_k(intn){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)returnk;

}public void toHammingCode(ArrayListcode){

msg= "信息源码: ";for(int i=0; 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

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

msg+=code.get(i);

}public boolean hammingCheck(ArrayListcode){

msg+= ", 接收到信息码: ";

Collections.reverse(code);

ArrayList s = new ArrayList();//校验的结果值

int k=1;while(k <= code.size()){//si的每一位初值为校验位pi的值

s.add(code.get(k-1));

k<<=1;

}for(int i=0; i

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

ret+= s.get(i)*radix;

radix<<=1;

}if(ret == 0){

msg+= ", 校验结果: 正确!";return true;

}else{

Collections.reverse(s);

msg+= ", 校验结果: " + s + ", 第" + ret + "位出错!";return false;

}

}public static voidmain(String[] args) {int cd[]={1,0,1,0};

ArrayList code = new ArrayList();for(int i=0; i

code.add(cd[i]);

HammingCheck hc= newHammingCheck();

hc.toHammingCode(code);

System.out.println("海明码: " +code);//假设cdd中的是接受到的信息,然后利用海明码纠错检验

int cdd[]={1, 0, 1, 0, 0, 1, 1};

code.clear();for(int i=0; i

code.add(cdd[i]);

hc.hammingCheck(code);

}

}

View Code

执行程序部分:

packagecom.hjzgg.thread;importjava.io.BufferedReader;importjava.io.InputStreamReader;importjava.net.ServerSocket;importjava.net.Socket;importjava.util.ArrayList;importjava.util.Map;importjava.util.TreeMap;importjavax.swing.JOptionPane;importcom.hjzgg.frame.MainFrame;public class MyThread implementsRunnable{privateString xxxCode;privateMainFrame mainFrame;private static final Map mp = new TreeMap();static{

mp.put("HammingCode", 5210);

mp.put("CrcCode", 5211);

mp.put("EvenOddCode", 5212);

}publicMyThread(MainFrame mainFrame, String xxxCode){this.mainFrame =mainFrame;this.xxxCode =xxxCode;

}

@Overridepublic voidrun() {

ServerSocket server=null;

Socket socket=null;

BufferedReader is= null;if(mp.get(xxxCode) == null) return;try{

server= newServerSocket(mp.get(xxxCode));while(true){

socket=server.accept();

is= new BufferedReader(newInputStreamReader(socket.getInputStream()));

String codeText=is.readLine();

ArrayList code = new ArrayList();for(int i=0; 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();//关闭Socket

if(server != null)

server.close();//关闭ServerSocket

} catch(Exception e){

System.out.println("Error:" +e.toString());

}

}

}

}

View Code

packagecom.hjzgg.frame;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.PrintWriter;importjava.net.Socket;importjava.util.ArrayList;importjava.util.Random;importcom.hjzgg.crc.CrcCheck;importcom.hjzgg.even_odd_check.EvenOddCheck;importcom.hjzgg.hammingcheck.HammingCheck;public class MyActionListener implementsActionListener{privateMainFrame mainFrame;publicMyActionListener(MainFrame mainFrame){this.mainFrame =mainFrame;

}private void myRandom(ArrayListcode){

Random random= newRandom();if(random.nextInt()%2 == 0){//出错

int index = Math.abs(random.nextInt())%code.size();

code.set(index, code.get(index)^1);

}

}public voidactionPerformed(ActionEvent e) {

String codeText=mainFrame.getCodeText().getText();

ArrayList code = new ArrayList();for(int i=0; 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=newPrintWriter(socket.getOutputStream());

mainFrame.getHc().toHammingCode(code);

myRandom(code);

codeText= "";for(int i=0; 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=newPrintWriter(socket.getOutputStream());

mainFrame.getCc().toCrcCode(code);

myRandom(code);

codeText= "";for(int i=0; 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=newPrintWriter(socket.getOutputStream());

mainFrame.getEoc().toEvenOddCode(code);

myRandom(code);

codeText= "";for(int i=0; i

codeText+=code.get(i);

os.print(codeText);

os.flush();

socket.close();//关闭Socket

}catch(Exception ex) {

System.out.println("Error:"+ex); //出错,则打印出错信息

}

}

}

}

View Code

主程序:

packagecom.hjzgg.frame;importjava.awt.BorderLayout;importjava.awt.Color;importjava.awt.Dimension;importjava.awt.FlowLayout;importjava.awt.HeadlessException;importjava.awt.TextField;importjavax.swing.JButton;importjavax.swing.JComboBox;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JPanel;importcom.hjzgg.crc.CrcCheck;importcom.hjzgg.even_odd_check.EvenOddCheck;importcom.hjzgg.hammingcheck.HammingCheck;importcom.hjzgg.thread.MyThread;public class MainFrame extendsJFrame{private TextField codeText;//传输的信息码

private HammingCheck hc = newHammingCheck();private EvenOddCheck eoc = newEvenOddCheck();private CrcCheck cc = newCrcCheck();publicHammingCheck getHc() {returnhc;

}publicEvenOddCheck getEoc() {returneoc;

}publicCrcCheck getCc() {returncc;

}publicTextField getCodeText() {returncodeText;

}private JButton crcBtn = new JButton("CRC冗余校验");private JButton hammingBtn = new JButton("海明校验");private JButton evenOddBtn = new JButton("奇偶校验");private JComboBox evenOddComboBox=newJComboBox();private JComboBox crcComboBox=newJComboBox();private JComboBox hammingComboBox=newJComboBox();private voidinit(){

JPanel topPanel= new JPanel(), downPanel = newJPanel();

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= newFlowLayout();

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= newFlowLayout();

downFlowLayout.setHgap(10);

downPanel.setLayout(downFlowLayout);

JPanel evenOddPanel= new JPanel(), crcPanel = new JPanel(), hammingPanel = newJPanel();

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

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() throwsHeadlessException {super();

init();

}public MainFrame(String title) throwsHeadlessException {super(title);

init();

}public static voidmain(String[] args) {//TODO Auto-generated method stub

MainFrame mainFrame = newMainFrame();

{//开启服务端,准备接受信息码//"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

实验结果: 有图有真相!

java 奇偶校验_校验码(海明校验,CRC冗余校验,奇偶校验)相关推荐

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

    循环冗余校验码 CRC码利用生成多项式为k个数据位产生r个校验位进行编码,其编码长度为n=k+r所以又称 (n,k)码. CRC码广泛应用于数据通信领域和磁介质存储系统中. CRC理论非常复杂,一般书 ...

  2. 计算机网络之数据链路层:3、差错控制(奇偶校验、CRC冗余校验、海明校验)

    差错控制 思维导图: 什么是差错: 位错: 位错之检错编码:奇偶校验码 位错之检错编码:循环冗余码 位错之纠错编码:海明校验码 思维导图: 什么是差错: 产生差错的原因主要是噪声:噪声分为全局性噪声和 ...

  3. 【计算机网络】数据链路层 : 差错控制 ( 纠错编码 | 海明码 | “海明码“ 原理 | “海明码“ 工作流程 | 确定校验啊位数 | 确定校验码和数据位置 | 求校验码值 | 检错纠错 )★

    文章目录 一. "海明码" 工作原理 二. "海明码" 工作流程 三. 确定校验码位数 四. 确定校验码和数据位置 0. 确定校验码位置 1. 引入二进制位 2 ...

  4. CRC冗余校验码及查表法

    CRC冗余校验码及查表法 什么是CRC编码 它将一个长度为k的位串看作是系数是0或者1的k-1次多项式 使用一个长度为r+1的生成多项式进行模2计算,生成一个长度为r的字符序列,能检测长度小于等于r的 ...

  5. java crc 校验码_java实现CRC校验码

    这两天项目中要使用到CRC校验功能,网上大量的例子是针对c.delphi的例子,前期没有做过,理论上也欠缺很多知识,在这里对java如何实现我们想要的crc校验功能做一下自己的总结,以下内容有本分转自 ...

  6. CRC冗余校验码源码代码c语言,循环冗余校验码(CRC)应用总结(包括C++源码)

    最近在实习期间需要用到数据的校验,所选为CRC16,那么就在此总结一番吧. 现在此说明下什么是CRC:循环冗余码校验 英文名称为Cyclical Redundancy Check,简称CRC,它是利用 ...

  7. 校验码——海明码及码距,码距

    相关文章: 校验码--码距   https://blog.csdn.net/weixin_44330072/article/details/106860286 校验码--奇偶校验码   https:/ ...

  8. 2.1.5-2校验码—海明(汉明)校验码

    XYXZNB (҂◔∀◐҂)☆万圣节快乐♬☆◥(ฅº₩ºฅ)◤ 不给糖就捣蛋 ☆(●⁰౪⁰●)没钱 好的,在这个小节中我们会继续探讨数据校验的问题,我们会学习海明教研嘛,那海明教研嘛又可以称为汉民教研 ...

  9. CRC冗余校验举例和原理

    什么是CRC校验? CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并 ...

最新文章

  1. UML从需求到实现---类图(2)
  2. 茫茫IT,我们努力,在努力。
  3. 计算机计算各科及格率,某两个班数学考试成绩如下,要求计算分析指标,用..._投资分析考试_帮考网...
  4. 巨头拼杀下的IM市场,网易云信如何站上终极对决?
  5. c++ 的makefile文件实例
  6. 【001:这条路很漫长,但出发了就不要想还有多远】
  7. OJ1069: 向Z同学学习
  8. Thinkphp内核无限坐席在线客服系统源码
  9. centos7安装xterm_CentOS 7使用x-manager中Xstart工具报缺少xterm包错误
  10. SpringBoot Cache 深入
  11. oracle11g 时间失效,关于oracle11g RAC 的CTSS与ntp时间同步的疑问
  12. JPG png GIF BMP常见图像格式的介绍与区别
  13. The RSpec Book笔记《四》Describing Code with RSpec用RSpec描述代码
  14. hp 服务器 修复,Hp服务器 raid 磁盘故障数据库数据恢复过程
  15. 华为手撕代码+剑指offer总结 (python+c语言)
  16. 脑科学磁共振成像(MRI)初学者必看——功能脑网络、小世界网络、FDR校正、脑电信号频率变换、模板、假设检验、广义线性模型、独立成分分析、影像组学、任务态和静息态方法汇总
  17. 我的世界服务器自动被踢怎么可以进去,我的世界中国版服务器中如何解决玩家作弊的简单方法...
  18. MyBatis 02
  19. 华为鸿蒙源自那句话,华为鸿蒙系统名字源自山海经它的很多自主专利都源于这本古籍,为什么?...
  20. 电脑快捷键你知道多少个?QQ截图快捷键ctrl加什么

热门文章

  1. River Hopscotch问题(二分)
  2. 【Python全栈开发从入门到实战】持续更新中......
  3. Fink异步IO的实战(关联维表)
  4. 在阿里云备案成功网站域名可以使用腾讯云服务器吗?恐怕不行
  5. 服务监控系统(客户端实现)
  6. python asyncio_python3.8 异步 asyncio 执行顺序
  7. 杭电联赛六 7034 Array
  8. 8个数据分析方法,指导营销策略
  9. 19_ue4进阶末日生存游戏开发[关联UI和数据]
  10. 一篇就够 编程常用英语单词 程序员都要知道单词