hello,大家好哇,我是wk,也是小林 今天带来的是hamming码的python实现
这个是我做通信网络基础实验这门实验课的实验任务
代码没有用什么很复杂的类定义,什么乱七八糟的对象什么的
我使用的是矩阵 算法也比较简单,就是直接,不拐弯磨脚
先上运行结果
话不多说再上代码
tips:注释是我用来测试用的 因为我用的IDLE我暂时不会用idle来debug
import math
import numpy as np
def is_power_of_two(n):
return n > 0 and math.log2(n).is_integer()
a=input("input the information code\n")
imfo_len=len(a)
a=a[::-1]
def cpb(n):
"""计算给定数据位长度n时所需的校验位个数k"""
k = 0
while (2 ** k) < n + k + 1:
k += 1
return k
parity_len=cpb(imfo_len)
a_list=list(a)
index_list = []
bin_str=[]
for i in range(parity_len):
a_list.insert(2**i-1,'0')
#print(a_list)
for i in range(1,imfo_len+parity_len+1):
if(is_power_of_two(i)):
continue
index_list.append(i)
rows=imfo_len
cols=parity_len
b=np.zeros((rows,cols),dtype=int)
for i in range(len(index_list)):
str_1=bin(index_list[i])[2:]
if(len(str_1)<cols):
for bit in range(cols-len(str_1)):
str_1='0'+str_1
bin_str.append(str_1)
for i, binary in enumerate(bin_str):
for j, bit in enumerate(binary):
b[i, j] = int(bit)
for j in range(cols):
r=0
for i in range(rows):
if(b[i,j]!=0):
r^=int(a_list[index_list[i]-1])
a_list[2**(cols-j-1)-1]=str(r)
#print(r)
a=''.join(a_list)
a=a[::-1]
#print(imfo_len,parity_len)
#print(index_list)
#print(b)
print('here is the hamming code:')
print(a)
代码的算法原理非常简单啊(我翻翻老师给的PPT)
这个意思就是 首先确定有几个校验位分别应该写在哪个位置上面
然后就是算这些校验位分别是多少
怎么算呢?
以r2为例
r2对应的是2^2(r1对应的是2^1,r0对应的是2^0)
然后开找,找哪些信息位的下标(就是这个信息位所在的位置是第几个)
比如说这里I1是第三个 下标是3 I3是第六个 下标是6
然后把下标分解了 分解成2的次幂相加的形式 然后r2=所有含有2^2的信息位异或得到的结果
然后再把得到的校验位(就是r0 r1 r2)和信息位按照表格组合的位置起来就行
我的想法就是把位置分解,然后做成一个矩阵
额 图片好糊啊。。。。 但是大致可以分辨 上面是R2 R1 R0 下面是I1 I2 I3 I4
这个矩阵中1表示I中有这个r,算这个r的时候需要用这个I去异或 0 表示没有
我是用数字转二进制数字转字符串(总之有点小复杂)
然后逐列扫描矩阵,得到 r的相关因素
换个图片hhhh
然后进行异或 更新对应的校验位的值
关键代码是这个
for j in range(cols):
r=0
for i in range(rows):
if(b[i,j]!=0):
r^=int(a_list[index_list[i]-1])
a_list[2**(cols-j-1)-1]=str(r)
最后输出就行
给一个kimi解释的版本的代码
import math
import numpy as np # 导入数学库和numpy库,用于数学运算和数组处理
def is_power_of_two(n):
return n > 0 and math.log2(n).is_integer() # 判断一个数是否是2的幂次方
a=input("input the information code\n") # 提示用户输入信息码
imfo_len=len(a) # 获取输入信息码的长度
a=a[::-1] # 将信息码翻转,以便从最低位开始处理
def cpb(n):
"""计算给定数据位长度n时所需的校验位个数k"""
k = 0
while (2 ** k) < n + k + 1: # 循环直到2的k次方小于n+k+1
k += 1
return k # 返回校验位的个数
parity_len=cpb(imfo_len) # 计算并存储所需的校验位个数
a_list=list(a) # 将信息码转换为字符列表
index_list = [] # 初始化一个空列表,用于存储非2的幂次方的索引
bin_str=[] # 初始化一个空列表,用于存储生成的二进制字符串
for i in range(parity_len):
a_list.insert(2**i-1,'0') # 在特定位置插入校验位
for i in range(1,imfo_len+parity_len+1):
if(is_power_of_two(i)):
continue # 如果索引是2的幂次方,则跳过
index_list.append(i) # 将非2的幂次方的索引添加到列表中
rows=imfo_len # 设置矩阵的行数为信息码的长度
cols=parity_len # 设置矩阵的列数为校验位的个数
b=np.zeros((rows,cols),dtype=int) # 创建一个全零的矩阵,用于生成汉明码的生成矩阵
for i in range(len(index_list)):
str_1=bin(index_list[i])[2:] # 将索引转换为二进制字符串
if(len(str_1)<cols):
for bit in range(cols-len(str_1)):
str_1='0'+str_1 # 如果二进制字符串长度小于列数,则在前面补0
bin_str.append(str_1) # 将生成的二进制字符串添加到列表中
for i, binary in enumerate(bin_str):
for j, bit in enumerate(binary):
b[i, j] = int(bit) # 将二进制字符串转换为整数,并填充到矩阵中
for j in range(cols):
r=0
for i in range(rows):
if(b[i,j]!=0):
r^=int(a_list[index_list[i]-1]) # 根据汉明码的生成矩阵,生成校验位
a_list[2**(cols-j-1)-1]=str(r) # 将计算出的校验位插入到正确的位置
a=''.join(a_list) # 将列表转换回字符串
a=a[::-1] # 再次翻转字符串,恢复原始顺序
print('here is the hamming code:')
print(a) # 打印生成的汉明码
有什么错误或者可以改进的地方欢迎大家指出
可以评论可以私信
感谢