计算机网络数据链路层的错误检测与纠正之海明码的生成,解码


 /**
 * made by wangming 
 * 
 * 2013-10-28  pm
 */

package wang.ming.data;
 public class Analysis {

 //生成海明码    

public static int[] HaiMingMa(int original[],int len ){

int checkBits=length(len);    //计算需要多长的校验码
int size=len+checkBits;        //发送的数据长度
int send[]=new int[size];
int o_s=0;   //original当前的偏移量

//初始化
for(int i=0;i<size;i++){
    if(canFit(i+1, checkBits)){
        send[i]=original[o_s];
        o_s++;
    }else {
        send[i]=0;
    }
}

for(int i=0;i<checkBits;i++){
    int fill=0;
    for(int j=1;j<=size;j++){
        if(canFit(j, checkBits)){
            if(in(j, i, checkBits)){
                fill=XOR(fill, send[j-1]);
            }
        }
    }
    int id=(int)Math.pow(2, (double)i);
    send[id-1]=fill;
}   
return send;
  }

       /*
        * 接受海明码  并进行处理
        */
 public static int[]receive(int send[]){
        int size=send.length;
        int bits=codeLength(size);
        int errorBit=check(send, bits,size);
        int []receive = new int[size-bits];
        if(errorBit>0){
            System.out.println("第"+errorBit+"出错了");
        }
        if(!canFit(errorBit, bits)){
        System.out.println("出错的是校验码,不影响结果");
        }
        int index=0;
        for(int i=0;i<size;i++){
            if(canFit(i+1, bits)){
            if((i+1)!=errorBit){
               receive[index]=send[i];
            }else{
            receive[index]=XOR(send[i], 1);
            //对出错的地方进行处理   与1异或即可得到原来的值
            }
              index++;
        }
        }
    return  receive;
       }

        /*
         * 判断接受的海明码是否出错
         */
    public static int check(int receive[],int bits,int size){
        int errorBit=0;
        for(int j=0;j<bits;j++){
        int flag=0;
        for(int i=0;i<size;i++){
        if(canFit(i+1, bits)){
            if(in(i+1, j, bits)){
                flag=XOR(flag, receive[i]);
            }
        }
    }
    int index=(int)Math.pow(2, (double)j)-1;
    flag=XOR(flag, receive[index]);
    if(flag==1){
        errorBit+=(int)Math.pow(2, (double)j);
        }
        }
        return errorBit;
     }

    /*
     * x=a*(2*2...*2)+b*(2*2...*2)+...+c*2+d
     *     [-bits-1-]   [-bits-2-]      
     *     其中常数a,b,c..等于0,1
     *     如果 2的y次方前的常数为1   return true
     *     为0   return false 
     */
    public static boolean in(int x,int y,int bits){
        int dive[]=new int[bits];
        int index=0;
        for(int i=bits-1;i>=0;i--){
            if(x/(int)Math.pow(2, (double)i)>0){
        dive[index]=1;
    }else{
        dive[index]=0;
    }
    x=x%(int)Math.pow(2, (double)i);
    index++;
        }
        if(dive[bits-y-1]==1){
            return true;
        }
        return false;
        }
    /*
     * 对两个数做异或操作
     * 相等   return 0
     * 否则   return 1
     */
    public static int XOR(int x,int y){
        if((x-y)==0){
            return 0; 
        }else{
            return 1;
        }
    }
    /*
     * 返回 true   or   false
     * 如果index是2的n次方   false
     * 否则  true
     */
    public static boolean canFit(int index,int checkBits){
        for(int i=0;i<checkBits;i++){
            if(index==Math.pow(2, (double)i)){
                return false;
            }
        }
        return true;
    }

    /*
     * 由海明码反向推出校验码位数
     */
    public static int codeLength(int len){
        int num=0;
        while((++num)>0){
            //逆向判断
            if((double)(len)<=Math.pow(2, (double)num)){
                return num;
            }   
            if(num>20){
                return -1;
            }
        }
        return -1;
    }

    /*  给定需要传输的原始数据
     *  返回需要的校验码的位数
     *  len+x+1<=(2*2*2....*2)   
     *        [-----x-----]
     */
    public static int  length(int len){
        int num=0;
        while((++num)>0){
            //校验码位数的判断条件
            if((double)(num+len+1)<=Math.pow(2, (double)num)){
                return num;
            }   
            if(num>20){
                return -1;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        System.out.println( Analysis.in(1, 0, 4));
        int code[]={1,0,1,1,0};
        int receive[]= Analysis.HaiMingMa(code, 5);
        receive[6]=0;
        System.out.println(Analysis.check(receive, 4,9));
        int recovery[]=Analysis.receive(receive);
        for(int i=0;i<recovery.length;i++ ){
            System.out.print(recovery[i]);
        }

        }
    }

你可能感兴趣的:(海明码,java生成)