数字传输 | 任意位数的汉明码hamming code编码+产生误差+纠错(原理+python代码实现)

由于网上搜到关于汉明码矩阵计算的资料比较少,基本上都是(7,4)居多,有些还是用class定义的,感觉很不友好。现在就来补充一点资料吧。

1. 汉明码基础知识

关于汉明码手算基本过程,大家可以参考汉明码手算,对汉明码编码有一个大概了解

1.1 关于判断一个数2的N次幂

一个数如果是2的N次幂,那它的二进制必定只有一个1其余为0,要想判断一个数是否是2的N次幂,只需把这个数减1,然后按位与,判断结果是否为0。

用8来举例子
在这里插入图片描述
代码实现如下

if num & num-1 ==0:  #Ture则为2的N次幂

1.2 list的index

本代码会涉及到很多list和汉明码位数的使用,list的index是从0开始,而汉明码第一位我们认为是1,所以两者相差了1,打代码要小心。

1.3 校验位,数据位,编码长度的关系

在这里插入图片描述
根据excel,我们可以看出他们之间的关系的规律,并得出如下式子

校验位 parity bit 这里简写成P
在这里插入图片描述

1.4 汉明码编码(7,4)例题

在这里插入图片描述

2.hammingcode(X,Y)实现

2.1计算位数

上面1.3讲过了,三个位数之间是有关系的,我们可以用代码来找,这里为了方便我的data用了4位方便学习,后续可自行改成任意长度

print("welcome to use the code made by Benni-Kang")
data='1101'
len_data=len(data)
Par_bits=0
while(len_data+1>2**Par_bits - Par_bits):
    Par_bits+=1
print('Number of Parity Bits=',Par_bits)

2.2 创建G矩阵

2.2.1 创建H矩阵

在这里插入图片描述
这是把每一位的2进制写在下面表格,而且是倒着写 如1的二进制001,在这里就是从下往上写。把这个表格拿出来变成矩阵就是H
在这里插入图片描述

import numpy as np
import pandas as pd

column = [] 
j=-1
for i in range(1,total_bits+1): #1 /7
    num =bin(i)
    while num[j] != "b":
        column+=num[j]
        j-=1
    j=-1
    column = list(map(int,column))  
    if i==1:
        col= pd.DataFrame(column,columns=['1'])
    else:
        column =pd.DataFrame(column,columns=[str(i)])
        H_dataframe=pd.concat([col,column],axis=1)
        col=H_dataframe
    column=[]
    
H_dataframe.fillna(0,inplace=True)# 空缺补0
H_dataframe.index=H_dataframe.index+1 #从1开始索引
H_matrix = np.array(H_dataframe)

这里的datafame可以看成是一个表格,像excel,并不是矩阵,不过可以转换成矩阵来计算
在这里插入图片描述

2.2.2创建单位矩阵

unit_matrix=np.eye(len_data)#创建单位矩阵

在这里插入图片描述

2.2.3创建G矩阵

把H的(1,2,4)列去掉,然后在新的矩阵的1,2,4行按顺序插入单位矩阵,就变成了G矩阵

for i in range(1,total_bits+1):
    if i & i-1 == 0:
        print(i)
        H_dataframe.drop(str(i), axis=1,inplace=True)
g_matrix=H_dataframe

在这里插入图片描述
g_matrix是去除掉的,现在下面来插入

j=0
for i in range(1,total_bits+1):
    if i & i-1 == 0:
#         print("1111",i)
        G_matrix=np.insert(unit_matrix, i-1, g_matrix.iloc[j], axis=0)
        unit_matrix=G_matrix
#         print(j)
#         print(g_matrix.iloc[j])
        j+=1

在这里插入图片描述

2.3把data变成list类型

这个没有什么好讲的…

data_list=[]
for char in data:
    data_list.append(char)
data_list = list(map(int,data_list))  

在这里插入图片描述

2.4矩阵乘

关于这个矩阵乘的线代计算,可以参考我的numpy学习笔记中2.3.2有提及具体的内容

首先当然是转换成矩阵,一维矩阵转置在这里是没有意义的,所以列向量行向量都一样,然后我们把G和data两个矩阵相乘,然后在转换成list类型

data_matrix =np.array(data_list)    #转换为array
r_matrix=np.dot(G_matrix,data_matrix)
r_list=r_matrix.tolist()

在这里插入图片描述

2.5求膜2

这里的意思就是计算出一个数的二进制的最小位

encode=[]
for num in r_list:
    mod2 = num % 2
    encode.append(int(mod2))
print("The encoded message is ",encode)

2.6产生误差

产生随机数,并翻转

import random
def flip_bit(message, location):
    # This will flip the bit at position e-1 (0->1 and 1->0)
    message[location] = 1 - message[location]
	print("welcome to use the code made by Benni-Kang")
	
    return message
def flip_random_bit(message):
    e = random.randint(1, len(message))
    print("Flipping bit (=introducing error) at location: " + str(e))
    # This will flip the bit at position e-1 (0->1 and 1->0)
    message = flip_bit(message, e-1)

    return message

2.7 纠错

纠错就是,拿H矩阵和encoded的矩阵相乘之后如果没错,结果为0,如果有错,结果为错误的位数,而且这里的二进制要倒着写,最高位是H0,最低位反而是Hn(n为校验位个数)
在这里插入图片描述

reveiver_message_matrix =np.array(reveiver_message)
Pc=np.dot(H_matrix,reveiver_message_matrix)
Pc_list=Pc.tolist()
print(Pc_list)

receive_bits=[]
for num in Pc_list:
    mod2 = num % 2
    receive_bits.append(int(mod2))

bi_to_di=''
for i in range(1,len(receive_bits)+1):
    bi_to_di+= str(receive_bits[-i])

error_position= int(bi_to_di,2)
if error_position!=0:
    message=flip_bit(reveiver_message, error_position-1)
print(message)

3.其他有意思的方法

这里用到的方法都是array类型,也有用list做出来同样效果的,比如直接用去掉124位的H和data直接乘,就变成校验位,然后再把校验位插入数据的list就变成了encode message。我这里举些代码例子,只是为了演示想法,不是本体具体解法。

在这里插入图片描述
由于删除1,2,4位会导致list的删改,所以我们要用到reserve()函数,从高位开始删除,这样就不会造成错误,可以自行删除看会发生什么

删除list中的1,2,4位代码举例如下:
在这里插入图片描述

插入的代码如下
在这里插入图片描述

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
下面是一个用python编写的任意位数明码编码的源代码: ```python def hamming_encode(data): n = len(data) # 源数据长度 k = 0 # 编码数据长度 # 计算编码数据长度 while 2 ** k < n + k + 1: k += 1 # 设置校验位的位置 parity_bits = [] for i in range(k): parity_bits.append(2 ** i) # 编码数据 encoded_data = [None] * (k + n) j = 0 for i in range(1, k + n + 1): if i in parity_bits: # 如果是校验位 encoded_data[i - 1] = None # 先将校验位位置留空 else: encoded_data[i - 1] = int(data[j]) # 将源数据填入编码数据 j += 1 # 计算校验位的值 for p in parity_bits: # 初始化校验位的值为0 encoded_data[p - 1] = 0 # 计算校验位的值 for i in range(p - 1, k + n): if encoded_data[i] != None and (i+1) % (2 * p) >= p: encoded_data[p - 1] ^= encoded_data[i] return ''.join(str(x) for x in encoded_data) # 测试 data = input("请输入源数据:") encoded_data = hamming_encode(data) print("明码编码后的数据为:", encoded_data) ``` 这段代码通过输入源数据,然后根据明码编码规则生成明码编码后的数据。编码的过程如下: 1. 首先确定编码数据的长度k,满足条件2\**k > n + k + 1,其中n为源数据的长度。 2. 然后确定校验位的位置,根据2的幂次方计算出校验位的位置,这些位置的数值都是2的幂次方。 3. 接下来开始编码数据,遍历源数据和校验位的位置,将源数据按顺序填入编码数据中。略过校验位的位置,初始值为None。 4. 初始化校验位的值为0,然后计算校验位的值。 5. 最后将编码数据转换为字符串形式并返回。 通过以上代码,你可以输入任意位数的源数据,程序会自动生成相应的明码编码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值