好友
阅读权限25
听众
最后登录1970-1-1
|
本帖最后由 ZhangYixiSuccee 于 2026-3-6 09:59 编辑
ECC:(Error Checking and Correction,错误检查和纠错算法),这里介绍的是汉明码,- 信息位N和校验位K满足一定关系:2^K - K >= N+1,
所以可得到如下表:注意这里是BIT个数,而不是Byte,换算成Byte需要/8,
| 信息码位数N | 1 | 2-4 | 5-11 | 12-26 | 27-57 | 58-120 | 121-247 | 248-502 | | 校验位数K | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
现在介绍一下纠错原理:- 校验后的位数为:M = N + K
- 接下来确定一下校验位的位置:位于2的幂次方位置处,比如1,2,4,8,16,32等位置处。
- 校验码值的计算:位置的数值的第i个bit为1的位置出的数值进行计算,计算方法可以为奇偶校验 或者异或运算
比如信息码1 0 1 0 1 -> 0x15,假定信息码为5位,那么校验位为4位,计算方式为异或- 原始信息码: 1 0 1 0 1,是5位
- 补充校验位后信息码:x0 x1 1 x2 0 1 0 x3 1,补充后为9,位
- x0 = (1 异或 0 异或 0 异或 1) = 0,计算的位置有 1,3,5,7,9,这些第0位都是1
- x1= (1异或 1 异或 0 )= 0 ,计算的位置有2,3,6,7, 第1位都是1
- x2=(0 异或 1 异或 0 )= 1,计算的位置有4,5,6,7, 第2位都是1
- x3=(1)=1,计算的位置有8,9, 第3位都是1
所以组成的校验位为 x0 ,x1,x2,x3,由于x3 处于低位,x0处于高位,所以最终校验值为1100,为0xC如何实现检错与纠错呢?信息码在传输过程0x15 -》0x17,ECC 校验值认为0xC,- x0 = (1 异或 0 异或 1 异或 1) = 1,计算的位置有 1,3,5,7,9,这些第0位都是1
- x1= (1异或 1 异或 1 )= 0 ,计算的位置有2,3,6,7, 第1位都是1
- x2=(0 异或 1 异或 1 )= 0,计算的位置有4,5,6,7, 第2位都是1
- x3=(1)=1,计算的位置有8,9, 第3位都是1
- ECC 新的Value为:1001 -》0x9,与0xC不同,
- X0,X1,X2均与原来计算不同,则说明其包括的一个值发生翻转,而其公共的bit位7,
- 所以原来的信息码为1 0 1 0 1,即0x15
算法如下(Python实现)[Python] 纯文本查看 复制代码 # 计算原始信息码需要的校验位数
def get_parity_num_from_data(data_bit_num):
cal_parity_num = 0
while(1):
if ((1 << cal_parity_num) - 1 - cal_parity_num) >= data_bit_num:
break
cal_parity_num = cal_parity_num + 1
return cal_parity_num
# 构建补充校验位后信息码
def build_ecc_data(data, data_bit_num, parity_bit_num):
index = 0
build_data = {}
data_index = 0
data = data[::-1]
bit_index = 0
​
if data_bit_num%8 == 0:
data_limit = data_bit_num//8
else:
data_limit = data_bit_num // 8 + 1
for i in range(data_bit_num + parity_bit_num):
if i== ((1 << index) - 1):
index = index + 1
build_data[i] = 0
else:
if data_index < data_limit:
build_data[i] = (data[data_index] & (1 << bit_index)) >> bit_index
bit_index = bit_index + 1
if bit_index >= 8:
data_index = data_index + 1
bit_index = 0
else:
build_data[i] = 0
return (build_data)
# 计算ecc value
def gen_ecc_parity(data, data bit_num, parity_bit_num) :
print(f" len:{len(data)} data:{data}")
print(f" hex data:{data.hex(}")
cal_parity_num = get_parity_num_from_data(data_bit_num)
print(f"cal_parity_num:{cal_parity_num}")
build_data = build_ecc_data(data, data_bit_num, parity_bit_num)
# for key,value in build_data.items():
parity_bit = {}
for parity in range(cal_parity_num):
parity_bit[parity] = 0
index = 1
for key, data in build_data.items():
if index & (1<<(parity)):
parity_bit[parity] = parity_bit[parity] ^ data
index = index + 1
print(f"parity bit :{parity_bit}")
parity_value = 0
for key, value in parity_bit.items():
parity_value |= value << key
print(f"parity_value:iparity_value:x}") 运行结果如下:
ECC 校验相对简单:[Python] 纯文本查看 复制代码 def ecc_parity_verify(data, data_bit_num, parity_value, parity bit_num):
(cal_parity_Value, parity_bit, build_data) = gen_ecc_parity(data, data_bit_num, parity_bit_num)
if parity_value == cal_parity_value:
print(f"ecc parity verify success, parity value:{cal_parity_value:x}")
else:
print(f"ecc parity verify failed, parity Value: fparity_Value:x}, cal parity value: {cal_parity_value:x}")
raise Exception("ecc parity verify failed") ECC 纠错比较难:需要确认是否可以纠正回来,如果可以纠正回来,然后确定是哪个bit位翻转导致- 先按新的信息码计算出新ECC值
- 新的ECC值和之前的ECC对比,将不同的bit的位置打印出来
- 根据不同的bit位置找出出错的bit位置
- 在将出错的bit位置 与原信息码的bit位置匹配
具体纠错算法,可以让AI编写。 |
|