汉明码(Hamming Code)错误检测与纠正码原理和 python实现如ECC内存)、通信系统等领域

汉明码(Hamming Code)是由理查德·汉明(Richard Hamming)于1950年提出的错误检测与纠正码,广泛应用于计算机内存(如ECC内存)、通信系统等领域。其核心目标是通过冗余位实现单比特错误纠正双比特错误检测


核心原理

  1. 冗余位(校验位)

    • 在原始数据中插入r个校验位,满足不等式:
      2ʳ ≥ m + r + 1m为数据位长度)。
    • 例如:7位数据(m=7)需要4个校验位(r=4),形成11位汉明码(7+4=11)。
  2. 校验位位置

    • 校验位位于2的幂次方位(即第1、2、4、8…位),其余位为数据位。
  3. 编码过程

    • 每个校验位覆盖特定位置的比特,其值为偶校验(或奇校验)结果。
    • 校验位计算规则
      i个校验位覆盖所有二进制表示中第i位为1的位置。
      例如:
      • P1(第1位)覆盖所有位置号二进制第1位为1的位(1,3,5,7,9…)。
      • P2(第2位)覆盖位置号二进制第2位为1的位(2,3,6,7,10…)。
  4. 错误检测与纠正

    • 接收端重新计算校验位,生成校验子(Syndrome)
    • 校验子为0表示无错误;非0时,其值直接指出错误位置(二进制转十进制)。

示例:7位数据编码为汉明码

原始数据1011001(7位,D7-D1)
校验位:需4位(P1,P2,P4,P8),满足2⁴≥7+4+1→16≥12。

步骤

  1. 排列数据与校验位(_为校验位):
    P1 P2 D3 P4 D5 D6 D7 P8
    填入数据:P1 P2 1 P4 0 0 1 P8
  2. 计算校验位(偶校验):
    • P1(覆盖1,3,5,7,9…):P1 ⊕ 1 ⊕ 0 ⊕ 1 = 0 → P1=0
    • P2(覆盖2,3,6,7,10…):P2 ⊕ 1 ⊕ 0 ⊕ 1 = 0 → P2=0
    • P4(覆盖4,5,6,7,12…):P4 ⊕ 0 ⊕ 0 ⊕ 1 = 0 → P4=1
    • P8(覆盖8,9,10,11…):P8 ⊕ 1 = 0 → P8=1
  3. 最终汉明码0 0 1 1 0 0 1 1 1(共11位)。

错误纠正示例

假设第5位(D5)出错:0 0 1 1 1 0 1 1 1(原应为0,现为1)。
接收端校验

  1. 重新计算校验子:
    • S1(P1覆盖位:1,3,5,7,9…):0 ⊕ 1 ⊕ 1 ⊕ 1 ⊕ 1 = 0 → 0
    • S2(P2覆盖位:2,3,6,7,10…):0 ⊕ 1 ⊕ 0 ⊕ 1 ⊕ 1 = 1 → 1
    • S4(P4覆盖位:4,5,6,7,12…):1 ⊕ 1 ⊕ 0 ⊕ 1 = 1 → 1
    • S8(P8覆盖位:8,9,10,11…):1 ⊕ 1 = 0 → 0
  2. 校验子:S8S4S2S1 = 0110(二进制)= 6 → 第6位(D5)出错,翻转即可纠正。

关键特性

  • 单比特错误纠正:可定位并修复任意1位错误。
  • 双比特错误检测:通过扩展汉明码(如SEC-DED)可检测2位错误,但无法纠正。
  • 效率:冗余位占比随数据位增加而降低(如7位数据需4位校验,1024位数据仅需11位校验)。

应用场景

  • ECC内存(如服务器、航天器)。
  • 网络通信(如卫星传输)。
  • 存储系统(如RAID磁盘阵列)。

如需更深入的细节(如扩展汉明码、奇偶校验选择),可进一步探讨!

import numpy as np


class HammingCode:
    def __init__(self, r=3):
        self.r = r
        self.n = 2 ** r - 1
        self.k = self.n - r

        # 生成矩阵 (系统码形式:前k位为信息位)
        self.gen_matrix = np.array([
            [1, 0, 0, 0, 1, 1, 0],
            [0, 1, 0, 0, 1, 0, 1],
            [0, 0, 1, 0, 0, 1, 1],
            [0, 0, 0, 1, 1, 1, 1]
        ], dtype=int)

        # 校验矩阵 (与生成矩阵配对)
        self.parity_matrix = np.array([
            [1, 1, 0, 1, 1, 0, 0],
            [1, 0, 1, 1, 0, 1, 0],
            [0, 1, 1, 1, 0, 0, 1]
        ], dtype=int)

        # 错误位置映射表 (伴随式元组 → 错误位置索引)
        self.error_table = {
            (0, 0, 0): -1,  # 无错误
            (0, 0, 1): 6,  # p3错误
            (0, 1, 0): 5,  # p2错误
            (0, 1, 1): 2,  # d3错误
            (1, 0, 0): 4,  # p1错误
            (1, 0, 1): 1,  # d2错误
            (1, 1, 0): 0,  # d1错误
            (1, 1, 1): 3  # d4错误
        }

    def encode(self, bits):
        """(7,4)汉明码编码"""
        # 补零使长度为4的倍数
        padding_len = (4 - len(bits) % 4) % 4
        padded_bits = np.concatenate((bits, np.zeros(padding_len, dtype=int)))

        # 输出长度 = 输入长度 * 7/4
        encoded = np.zeros(len(padded_bits) * 7 // 4, dtype=int)

        # 分组处理每个4位信息组
        for i in range(0, len(padded_bits), 4):
            message = padded_bits[i:i + 4]
            codeword = (np.dot(message, self.gen_matrix) % 2)
            start_idx = i * 7 // 4
            encoded[start_idx:start_idx + 7] = codeword

        # 存储补零长度用于解码
        self.last_padding = padding_len
        return encoded

    def decode(self, encoded_bits):
        """(7,4)汉明码解码(自动纠单比特错误)"""
        decoded_list = []

        # 处理每个7位码字组
        for i in range(0, len(encoded_bits), 7):
            codeword = encoded_bits[i:i + 7]

            # 计算伴随式(校验子)
            syndrom = np.dot(self.parity_matrix, codeword) % 2
            syndrom_tuple = tuple(syndrom)

            # 检测错误位置
            error_index = self.error_table.get(syndrom_tuple, -1)

            # 自动纠正单比特错误
            if error_index >= 0 and error_index < len(codeword):
                codeword[error_index] = 1 - codeword[error_index]

            # 提取信息位(前4位)
            decoded_list.extend(codeword[:4])

        # 去除编码时添加的填充位
        decoded = np.array(decoded_list[:-self.last_padding]) if self.last_padding > 0 else np.array(decoded_list)
        return decoded


# 测试验证
if __name__ == "__main__":
    encoder = HammingCode()

    # 测试1: 单码字无错误
    data1 = np.array([1, 0, 1, 0])
    encoded1 = encoder.encode(data1)
    decoded1 = encoder.decode(encoded1)
    assert np.array_equal(data1, decoded1), "测试1失败"

    # 测试2: 单码字错误纠正
    data2 = np.array([1, 0, 0, 0])
    encoded2 = encoder.encode(data2)
    # 引入错误 (d3位置)
    corrupted2 = encoded2.copy()
    corrupted2[2] = 1 - corrupted2[2]  # 翻转d3位
    decoded2 = encoder.decode(corrupted2)
    assert np.array_equal(data2, decoded2), "测试2失败"

    # 测试3: 多码字连续解码
    data3 = np.array([1, 0, 1, 0, 1, 1, 0, 0])
    encoded3 = encoder.encode(data3)
    decoded3 = encoder.decode(encoded3)
    assert np.array_equal(data3, decoded3), "测试3失败"

    # 测试4: 多码字错误纠正
    data4 = np.array([1, 1, 0, 0, 1, 0, 1, 0])
    encoded4 = encoder.encode(data4)
    corrupted4 = encoded4.copy()
    # 第一个码字d1错误
    corrupted4[0] = 1 - corrupted4[0]
    # 第二个码字d4错误
    corrupted4[3 + 7] = 1 - corrupted4[3 + 7]
    decoded4 = encoder.decode(corrupted4)
    assert np.array_equal(data4, decoded4), "测试4失败"

    # 测试5: 边界情况 - 单码字p位错误
    data5 = np.array([0, 1, 0, 1])
    encoded5 = encoder.encode(data5)
    corrupted5 = encoded5.copy()
    # 引入p1错误
    corrupted5[4] = 1 - corrupted5[4]
    decoded5 = encoder.decode(corrupted5)
    assert np.array_equal(data5, decoded5), "测试5失败"

    print("所有测试通过!")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值