基本要求
选择一种校验方法用高级语言编写代码来实现对存储器读写校验的仿真。
基本思想
以汉明码为容错编码来实现存储器读写校验的仿真实验。
1、 输入要传送的二进制数,按照配偶原则来配置汉明码。
2、 输入接收到的汉明码,更根据汉明码的纠错过程(假设仅仅只有一个数个数为发生错误,因为汉明码是具有一位纠错能力的编码)对接收到的汉明码进行校验。
对新增添的检测位数k的确定
设欲检测的二进制代码为n位,为使其具有纠错能力,需增添k位检测位,组成n+k位的代码(即汉明码)。更具公式
2^k >= n + k + 1
可以计算出k的值。
代码实现 while(1 ( 对新增添的检测位的位置确定
设n+k位代码自左至右依次编为第1,2,3,……,n+k位,而将k位检测位记作Ci(i=1,2,4,8,……),分别安插在n+k位代码编号的第1,2,4,8,……,2^(k-1)位上。这些检测位的位置设置是为了保证它们能分别承担n+k位的信息中不同数位所组成的“小组”的奇偶检测任务。由汉明码检测位位置的特点,可以根据 循环{
1 i ++; (i初始为0) }
来确定检测位的位置。
对新增添的检测位所负责检测小组的位的确定
根据对汉明码的了解,检测位和它所负责检测的小组的具体分配如下:
C1检测的小组包含1,2,4,7,9,11,……位
C2检测的小组包含2,3,6,7,10,11,14,15,……位
C4检测的小组包含4,5,6,7,12,13,14,15,……位
根据小组划分的特点,通过以下代码来实现找到检测的小组的各个位:
1. //找到汉明码检测小组中的各个位
2. int pos(int i){ //找到汉明码检测小组中的各个位
3. int c=0;
4. int pos=2,n=4;
5. while(ci){
6. pos++;
7. if(pos==n)n*=2,c--;
8. c++;
9. }
10. return pos;
11. }
对新增添的检测位的值的确定
找到每个检测位所负责的小组的各个位,把每个检测位所负责检测的小组位上的二进制数加起来,对其和进行摸2计算。按配偶原则配置,当检测小组的1为奇数个时,其和摸2的结果为1,则检测位的值为1;当检测小组的1为偶数个时,其和摸2的结果为0,则检测位的值位0。
代码实现
#include
//输入二进制数
void in_bin(int bin[]){
char binary[100];
int i=0;
printf("请输入要传送的二进制数:");
scanf("%s",binary);
while(binary[i]){
bin[i+1]=binary[i]-48;
i++;
}
bin[0]=i;//bin[0]记录输入的二进制数的个数
}
//输出二进制数
void out_bin(int bin[]){
printf("输入要传送的二进制数:");
for(int i=1;ibin[0];i++){
printf("%d",bin[i]);
}
printf("n");
}
//输出汉明码位上的数
void out_p(int p[]){
printf("汉明码位上的数为:");
for(int i=1;ip[0];i++){
printf("%d",p[i]);
}
printf("n");
}
//输出汉明码
void out_haiming(int bin[],int p[],int place=0){
printf("汉明码为:");
int i,n=1;
int pp=1,pb=1;
for(i=1;ibin[0]+p[0];i++)
if(i==n){
printf("%d",p[pp++]);
n=n*2;
}
else{
printf("%d",bin[pb++]);
}
printf("n");
}
//找到汉明码检测小组中的各个位
int pos(int i){//找到汉明码检测小组中的各个位
int c=0;
int pos=2,n=4;
while(ci){
pos++;
if(pos==n)n*=2,c--;
c++;
}
return pos;
}
//计算汉明码检测位上的值
void in_p(int p[],int bin[]){
int i,j;
p[0]=1;
while(1p[0]p[0]+bin[0]+1)p[0]++;//此语句求新增添的检测位的个数:公式->2^k>=n+k+1
//
// p[0]记录汉明码的个数;
// printf("汉明码个数:%dn",p[0]);//输出汉明码的个数
for(i=1;i100;i++)p[i]=0;//初始化
for(i=1;ip[0];i++){
for(j=1;jbin[0];j++){
// printf("%d ",pos(j)&(1
if(pos(j)&(1(i-1))){
// printf("%d",j);
// printf("%d",pos(j));
// printf("%d",1
p[i]=(p[i]+bin[j])%2;
//printf("%d",pos(j));
//printf("%d",j);
}
//printf("n%d",i);
}
}
}
//输入接收到的汉明码
void in_reacice(int r[]){
char recive[100];
int i=0;
scanf("%s",recive);
while(recive[i]){
r[i+1]=recive[i]-48;
i++;
}
r[0]=i;//r[0]记录输入的二进制数的个数
}
//校验接收到的汉明码是否出错
void check_reacive(int p[],int r[],int q[]){
int i,j,k;
int flag[100];
int bins[100];
for(i=0;i100;i++)q[i]=0;//初始化
k = 1;
for(i=0;ip[0];i++){
flag[k] = 1i;//记录汉明码检测位的位置
q[k] = r[flag[k]];//记录汉明码检测位所在的值
k ++;
flag[0] ++;
q[0] ++;
}
int c = 0;
k = 1;
bins[0] = 0;
for(i = 1;i r[0];i ++){
c = 0;
for(j = 1;j flag[0];j ++){
if(i == flag[j]) c = 1;
}
if(c == 0){
bins[k] = r[i];//把汉明码的检测位与实际传入的二进制数进行分离
k ++;
bins[0] ++;
}
}
//纠错
for(i=1;iq[0];i++){
for(j=1;jbins[0];j++){
if(pos(j)&(1(i-1))){
q[i]=(q[i]+bins[j])%2;
}
}
}
int y = q[0] - 1;
int s = 0;
for(i = q[0];i > 0;i --){
s += (1y) * q[i]; //计算最后出现错误的位置
y --;
}
if(s == 0){
printf("n传送和接收过程中,信息未出现错误!n");
}else{
printf("n错误!!!汉明码的第%d位出现错误!",s);
if(r[s] == 1){
r[s] = 0;
}else{
r[s] = 1;
}
printf("nn纠错后的汉明码为:");
for(i = 1;i r[0];i ++){
printf("%d",r[i]);
}
printf("n");
}
}
int main(){
int bin[100];
int p[100];
int r[100];
int q[100];
in_bin(bin);
in_p(p,bin);
out_bin(bin);
out_p(p);
out_haiming(bin,p);
printf("-----------------------------n");
printf("请输入接收到的汉明码:");
in_reacice(r);
check_reacive(p,r,q);
return 0;
}
测试样例数据显示:
测试1.(校验四位二进制数)
测试2.(校验六位二进制数)
测试3.(校验七位二进制数)
测试4.(校验十五位二进制数)
个人认为最难解决的是对检测位的值的确定,检测位的个数可以通过对