首页 > 其他 > 详细

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

时间:2015-10-07 00:58:27      阅读:480      评论:0      收藏:0      [点我收藏+]

 

CRC冗余校验

技术分享
package com.hjzgg.crc;

import java.util.ArrayList;

public class CrcCheck {
    /*
       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;
    
    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

 

奇偶校验

技术分享
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

 

海明校验

技术分享
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;
    }
    @Override
    public 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(); //关闭Socket
                if(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 stub
        MainFrame 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

 

实验结果: 有图有真相!

技术分享

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

原文:http://www.cnblogs.com/hujunzheng/p/4858103.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!