海明校验程序

#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include "resource.h"
#include "MainDlg.h"
/****************************************************************************************************************************************
  第一部分:8位信息生成13位海明校验码,并且假设传输过程中出现一位错位然后实现自动纠错
  **************************************************************************************************************************************/
/*********************************************
  变量定义  把8位信息位生成13位海明码所需变量
*********************************************/
TCHAR bwstr[256];//存放输入的八位原信息
TCHAR intbwstr[256];//八位原信息的int格式
TCHAR pstr[10];    //5个校验位
TCHAR inthaimingstr[256];//海明码的int格式
TCHAR haimingstr[256];//海明码的char形式
/********************************************
 2n函数
*******************************************/
TCHAR power(TCHAR i)
{ TCHAR k,s=1;
   for(k=0;k<i;k++)
    s=s*2;
  return s;
}
/********************************************
  将bwstr中的八位信息转为int格式的
********************************************/
void getstr(HWND hwnd) 
{      
 GetDlgItemText(hwnd,IDC_EDIT1,bwstr,sizeof(bwstr));//获取输入的字符
    TCHAR i,k;
 k=0;
    for(i=0;i<=20;i++)
 {
      if(bwstr[i]!='\0') k++;
 }
    if(k!=8)
    MessageBox(hwnd,TEXT("暂不支持非8位计算"),TEXT("警告"),MB_OK);//当输入非8位时出错处理
     for(i=0;i<=7;i++)
  {
      intbwstr[8-i]=bwstr[i]-48;//转换字符序
  }
}
/*********************************************
 生成海明校验码并显示
*********************************************/
void getp(HWND hwnd)
{
 pstr[1]=(intbwstr[1]+intbwstr[2]+intbwstr[4]+intbwstr[5]+intbwstr[7])%2;   //获取校验位
    pstr[2]=(intbwstr[1]+intbwstr[3]+intbwstr[4]+intbwstr[6]+intbwstr[7])%2;
    pstr[3]=(intbwstr[2]+intbwstr[3]+intbwstr[4]+intbwstr[8])%2;
    pstr[4]=(intbwstr[5]+intbwstr[6]+intbwstr[7]+intbwstr[8])%2;
    pstr[5]=(intbwstr[1]+intbwstr[2]+intbwstr[3]+intbwstr[5]+intbwstr[6]+intbwstr[8])%2;
    TCHAR i,j;
    for(i=2;i<=12;i++)
 {   
  inthaimingstr[i]=0;    //缓冲区全为0
 }
    for(i=1;i<=3;i++)
 {  
  inthaimingstr[power(i)]=1;//特殊位全为1
 }
    j=1;
    for(i=2;i<=12;i++)         //填充信息位
 {   
  if(inthaimingstr[i]==0) inthaimingstr[i]=intbwstr[j++];
 }
    j=2;
    for(i=1;i<=3;i++)          //填充校验位
 { 
  inthaimingstr[power(i)]=pstr[j++];
 }
    inthaimingstr[1]=pstr[1];//填充最低位
    inthaimingstr[13]=pstr[5];//填充最高位
    for(i=1;i<=13;i++)//转换为ASCII码
 {
   haimingstr[i-1]=inthaimingstr[i]+48;
 }
    for(i=0;i<=12;i++)//重排字符序
 {  
   inthaimingstr[12-i]=haimingstr[i];
 }
    inthaimingstr[13]='\0';
     SetDlgItemText(hwnd,IDC_EDIT2,inthaimingstr);//显示
}
/************************************************
校验按钮函数
************************************************/
TCHAR s[10];//存储偶校验位
void getstr_2(HWND hwnd)  //此函数执行后  输入的数字在intbwstr[1,2......]中
{
 GetDlgItemText(hwnd,IDC_EDIT3,bwstr,sizeof(bwstr));//获取输入的字符(人工错一位的)
    TCHAR i;
     for(i=0;i<=12;i++)
  {
      intbwstr[13-i]=bwstr[i]-48;//转换字符序
  }
}
void getp_2(HWND hwnd)
{
   TCHAR i,j,k,n;
   j=1;
   for(i=0;i<=3;i++)   //获取前四位校验位     
 { 
   pstr[j++]=intbwstr[power(i)];
 }
   pstr[5]=intbwstr[13];//获取第五位校验位

   s[1]=(intbwstr[3]+intbwstr[5]+intbwstr[7]+intbwstr[9]+intbwstr[11]+pstr[1])%2;   //获s
   s[2]=(intbwstr[3]+intbwstr[6]+intbwstr[7]+intbwstr[10]+intbwstr[11]+pstr[2])%2;
   s[3]=(intbwstr[5]+intbwstr[6]+intbwstr[7]+intbwstr[12]+pstr[3])%2;
   s[4]=(intbwstr[9]+intbwstr[10]+intbwstr[11]+intbwstr[12]+pstr[4])%2;
   s[5]=(intbwstr[3]+intbwstr[5]+intbwstr[6]+intbwstr[9]+intbwstr[10]+intbwstr[12]+pstr[5])%2;
   n=0;
   for(i=1;i<=5;i++)//计数S错位数
   {
    if(s[i]==1) n++;
   }
   switch (n)
   {
     case 1:
        for(i=1;i<=4;i++)
     {
             if(s[i]==1)
    {
      if(intbwstr[power(i-1)]==1)  intbwstr[power(i-1)]=0;
      else                         intbwstr[power(i-1)]=1;
    
    }
     } 
              if(s[5]==1)
    {
      if(intbwstr[13]==1)  intbwstr[13]=0;
      else                 intbwstr[13]=1;
    
    }

  break;
  
  default:
             k=s[4]*power(3)+s[3]*power(2)+s[2]*power(1)+s[1];
             if(intbwstr[k]==0) intbwstr[k]=1;
             else               intbwstr[k]=0;
   }

   for(i=1;i<=13;i++)//重排字符序
 {  
   inthaimingstr[13-i]=intbwstr[i]+48;
 }
    inthaimingstr[13]='\0';
     SetDlgItemText(hwnd,IDC_EDIT4,inthaimingstr);//显示

}
/****************************************************************************************************************************************
  第二部分:对任信息位生成海明校验码
  **************************************************************************************************************************************/
TCHAR chargetstr[256]; //存放用户输入字符串
TCHAR intgetstr[256];  //存放倒序后的转换为int格式的字符串
TCHAR intsetstr[256];  //存放处理后的int格式字符串
TCHAR charsetstr[256]; //最终要显示的字符串
TCHAR p[256];          //存放校验位
TCHAR how_n;           //用户输入的信息位数
TCHAR how_k;           //所需的校验码数
struct song        //定义song结构体 h为在intgetchar的位置,d[32]为h的二进制形式
{
 int h;
 TCHAR d[32];
};
struct song data[100];//存放每一位数据信息便于推出各校验位值
/*********************************************************
 获取字符串并将chargetstr转为intgetstr[1,2,3..........]
  ********************************************************/
void getcharstr(HWND hwnd)
{
   GetDlgItemText(hwnd,IDC_EDIT5,chargetstr,sizeof(chargetstr));
   TCHAR i;
   how_n=0;

   for(i=0;i<250;i++)//计算用户输入的信息位数how_n
   {
    if(chargetstr[i]=='\0') break;
    how_n++;
   }
  
   for(i=0;i<how_n;i++)//转换为便于处理的int格式字符串intgetstr[1,2,3.....how_n]
   {
     intgetstr[how_n-i]=chargetstr[i]-48;
   }
}
/*********************************************************
计算  how_k: 所需的校验位数
  *******************************************************/
void gethow_k()
{
 int i,n,j;
 n=how_n+1;
    for(i=1;i<150;i++)
 {  j=power(i-1)-i;//j为2的i-1次方减i
    if(j>=n)        // 穷举法  当满足公式时退出循环
    {
       how_k=i;  //此时计算出how_k:所需校验码位
    break;
    }
 }
}
/*********************************************************
填充intsetstr中信息位,顺便填充data数组信息
  *******************************************************/
void getdata()
{
   TCHAR i,j;
   for(i=1;i<=how_n+how_k;i++)//缓冲区全为0
   {
   intsetstr[i]=0;
   }
   for(i=1;i<how_k;i++)//校验位全为1
   {
   intsetstr[power(i-1)]=1;
   }
   intsetstr[how_n+how_k]=1;//最高位为特殊位也为校验位设为1
   j=1;
   for(i=1;i<=how_n+how_k;i++)
   {
     if(intsetstr[i]==0)
  {
   intsetstr[i]=intgetstr[j];//信息位填充
      data[j].h=i;              //填充data的h位:信息位在intsetstr中具体位置
      j++;
  }
   }
}
/************************************************************
计算数组中有效位数
  ***********************************************************/
TCHAR use(TCHAR * s)
{
  TCHAR i,k;
  k=0;
  for(i=0;i<32;i++)
  {
   if(s[i]=='\0') break;
   k++;
  }

 return k;
}


/**************************************************************
将data中 的h值转为二进制并存在d数组中 并且向后移位d[1,2,3....]
  ************************************************************/
void getdata_d()
{
 TCHAR i,j;
 TCHAR buff[32];
 ZeroMemory(buff,sizeof(buff));
 for(i=1;i<=how_n;i++)
 {
    itoa(data[i].h,buff,2);
    for(j=0;j<(use(buff));j++)
    {
     data[i].d[use(buff)-j]=buff[j]-48;
    }
 
 }
}
/****************************************************************
计算各校验位的值  并且写入intsetstr中
  **************************************************************/
void  getpsetp()
{
 TCHAR i,j,s;
 for(i=1;i<how_k;i++)
 {
       s=0;
  for(j=1;j<=how_n;j++)
  {
      if(data[j].d[i]==1)
       s=s+intgetstr[j];
  }
     p[i]=s%2;
 }
   p[how_k]=0;
   for(i=1;i<=how_n;i++)
   {
    p[how_k]=p[how_k]+intgetstr[i];

   }
   for(i=1;i<how_k;i++)
   {
    p[how_k]=p[how_k]+p[i];

   }
  p[how_k]=p[how_k]%2;


   j=1;
   for(i=1;i<how_k;i++)
   {
   intsetstr[power(i-1)]=p[j++];
   }
   intsetstr[how_n+how_k]=p[how_k];
}
/**************************************************************************
   倒序加显示
  ************************************************************************/
void good(HWND hwnd)
{
 TCHAR i;
    for(i=1;i<=how_n+how_k;i++)
 {
      charsetstr[how_n+how_k-i]=intsetstr[i]+48;
 }
    SetDlgItemText(hwnd,IDC_EDIT6,charsetstr);//显示
}
void zero()//清空缓存区
{
ZeroMemory(chargetstr,sizeof(chargetstr));
ZeroMemory(intgetstr,sizeof(chargetstr));
ZeroMemory(charsetstr,sizeof(chargetstr));
ZeroMemory(charsetstr,sizeof(chargetstr));
ZeroMemory(p,sizeof(p));
}
/*******************************************************************************************************************
                                    结束
  *****************************************************************************************************************/

 

 

 

 

 

 

 

 

 

 

 

BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);
        HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);
  HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);
    }

    return FALSE;
}

BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
    return TRUE;
}

void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
    switch(id)
    {
        case IDC_OK:        //生成13位海明校验码
                      getstr(hwnd);
       getp(hwnd);
  
        break;

         case IDC_BUTTON1:  //自动纠错
              getstr_2(hwnd);
        getp_2(hwnd);
         break;


         case IDC_BUTTON2:  //生成任意位海明校验码
              zero();
                       getcharstr(hwnd);
        gethow_k();
        getdata();
        getdata_d();
                       getpsetp();
                       good(hwnd);


         break;

 

 

 

 

 

 


        default:
  break;
    }
}

void Main_OnClose(HWND hwnd)
{
    EndDialog(hwnd, 0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值