今天上课,老师让我们用matlab进行汉明码编码译码的实现,之前上通信原理课程的时候老师顺带提过一句,现在已然是记不太清了,所以上网搜索了一下关于汉明码的原理。
汉明码(Hamming Code),是在电信领域的一种线性调试码,以发明者理查德·卫斯里·汉明的名字命名。。。。。。
简单来说,汉明码就是一个可以校验和纠错的编码。
首先记住一个公式:, n是你要编码的数组长度,k是验证码字的个数
我们现在以k=4,n=7的实例来说明汉明码的编码原理:
a=[1,0,1,0,1,1,1]
因为n+k=11,我们要编码出来的是一个长度为11的数组,其中四位是校验码
根据k值的不同,我们可以吧原始数组分为k组,将原始数组的下标分别转换为二进制
第一组的分别是末位为1的下标:XXX1
第二组的分别是次末位为1的下标:XX1X
第三组的分别是次位为1的下标:X1XX
第四组的分别是首位为1的下标:1XXX
所以第一组P1的下标分别为:3,5,7,9,11
第二组:3,6,7,10,11
第三组:5,6,7
第四组:9,10,11
每一个校验位的数值是组内每一个元素数值的奇偶数
对于译码:
假设接收到长度为11的数组进行译码,先取出校验码,然后用每个组的元素进行奇偶的校验,如果错误,则该组的一个校验状态转为错误,记为1,通过对四个组进行奇偶校验,用每个组的奇偶校验值可以得出一个数组,用该数组即可算出数据错误位置
假设传递时最后一位发生错误,则1,3,4组受到影响,校验数组为[1,0,1,1],通过计算2^3+2^1+2^0=11为错误位置
以下为代码:
clc
a=[1,0,1,0,1,1,1];
a
h1=HamingCode(a,4);
h1
h2=HamingDecode(h1,4);
h2
function h = HamingCode(a,k)
n=length(a(:));
z=1;
j=1;
h=zeros(1,n+k);
for i=1:n+k %将输入数组写入全零矩阵待用,且跳过验证
if i==2^(z-1)
z=z+1;
continue
else
h(i)=a(j);
j=j+1;
end
end
if k==4
h(1)=rem(h(3)+h(5)+h(7)+h(9)+h(11),2);
h(2)=rem(h(3)+h(6)+h(7)+h(10)+h(11),2);
h(4)=rem(h(5)+h(6)+h(7),2);
h(8)=rem(h(9)+h(10)+h(11),2);
else if k==3
h(1)=rem(h(3)+h(5)+h(7),2);
h(2)=rem(h(3)+h(6)+h(7),2);
h(4)=rem(h(5)+h(6)+h(7),2);
else if k==2
h(1)=rem(h(3),2);
h(2)=rem(h(3),2);
end
end
end
function h = HamingDecode(a,k)
%a=[1,0,1,1,0,1,0,1,1,1,0];
n=length(a(:)); %求输入数组长度
h=zeros(1,n-k); %解码和译码的n含义不同
check=zeros(1,k); %四个组的验证数组
che=0;
if k==4
if a(1)~=rem(a(3)+a(5)+a(7)+a(9)+a(11),2); %四个组,如果有任意一个组验证不通过,则相应数组的变量变为1,标志位che变成1,方便后面修改
check(1)=1
che=1
else if a(2)~=rem(a(3)+a(6)+a(7)+a(10)+a(11),2);
check(2)=1
che=1;
else if a(4)~=rem(a(5)+a(6)+a(7),2);
check(4)=1
che=1;
else if a(8)~=rem(a(9)+a(10)+a(11),2);
check(8)=1
che=1;
end
end
end
end
j=1;
z=1;
if che==1 %假如验证生效
s= 2^(3*check(1))+2^(2*check(2))+2^(1*check(3))+2^(check(4)*0)
a(s)=1-a(s)
end
for i=1:n %跳过验证码,将数组写入输出数组
if i==2^(z-1)
z=z+1;
continue
else
h(j)=a(i);
j=j+1;
end
end
end
本人对于汉明码理解借鉴了其他博主文章,传送门:https://blog.csdn.net/Yonggie/article/details/83186280