C语言实现海明码

海明码编码的原理这里不介绍了,网上有很多,我也是看了很多,这里简单实现了一个编码4字节的海明码实现。

void encode(unsigned char data[4], unsigned char code[5]) {
    unsigned int i, j, bit;
    unsigned char b, c;
    unsigned char p[39] = {0};
    memset(code, 0, sizeof(code));
    for (i = 1; i <= 32; i++) {
        j = (i-1) / 8;
        bit = (i-1) % 8;
        b = (data[j] & (1 << bit));
        switch (i) {
        case 1:
            c = (b << 2) % 0xff;
            code[0] |= c;
            break;
        case 2: case 3: case 4:
            c = (b << 3) % 0xff;
            code[0] |= c;
            break;
        case 5: case 6: case 7: case 8: case 9: case 10: case 11:
            c = (b << 4) % 0xff;
            code[1] |= c;
            break;
        case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19:
            c = (b << 5) % 0xff;
            code[2] |= c;
            break;
        case 20: case 21: case 22: case 23: case 24: case 25: case 26:
            c = (b << 5) % 0xff;
            code[3] |= c;
            break;
        case 27: case 28: case 29: case 30: case 31: case 32:
            c = (b << 6) % 0xff;
            code[4] |= c;
            break;
        }
    }

    for (i = 1; i <= 38; i++) {
        if (i != 0x01 && i != 0x02 && i != 0x04 && i != 0x08 && i != 0x10 && i != 0x20) {
            bit = (i-1) % 8;
            switch (i) {
            case 3: case 5: case 6: case 7:
                p[i] = (code[0] & (1 << bit)) >> bit;
                break;
            case 9: case 10: case 11: case 12: case 13: case 14: case 15:
                p[i] = (code[1] & (1 << bit)) >> bit;
                break;
            case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24:
                p[i] = (code[2] & (1 << bit)) >> bit;
                break;
            case 25: case 26: case 27: case 28: case 29: case 30: case 31:
                p[i] = (code[3] & (1 << bit)) >> bit;
                break;
            case 33: case 34: case 35: case 36: case 37: case 38:
                p[i] = (code[4] & (1 << bit)) >> bit;
                break;
            }
        }
    }

    p[1] = p[3] ^ p[5] ^ p[7] ^ p[9] ^ p[11] ^ p[13] ^ p[15] ^ p[17] ^ p[19] ^ p[21] ^ p[23] ^ p[25] ^ p[27] ^ p[29] ^ p[31] ^ p[33] ^ p[35] ^ p[37];
    p[2] = p[3] ^ p[6] ^ p[7] ^ p[10] ^ p[11] ^ p[14] ^ p[15] ^ p[18] ^ p[19] ^ p[22] ^ p[23] ^ p[26] ^ p[27] ^ p[30] ^ p[31] ^ p[34] ^ p[35] ^ p[38];
    p[4] = p[5] ^ p[6] ^ p[7] ^ p[12] ^ p[13] ^ p[14] ^ p[15] ^ p[20] ^ p[21] ^ p[22] ^ p[23] ^ p[28] ^ p[29] ^ p[30] ^ p[31] ^ p[36] ^ p[37] ^ p[38];
    p[8] = p[9] ^ p[10] ^ p[11] ^ p[12] ^ p[13] ^ p[14] ^ p[15] ^ p[24] ^ p[25] ^ p[26] ^ p[27] ^ p[28] ^ p[29] ^ p[30] ^ p[31];
    p[16] = p[17] ^ p[18] ^ p[19] ^ p[20] ^ p[21] ^ p[22] ^ p[23] ^ p[24] ^ p[25] ^ p[26] ^ p[27] ^ p[28] ^ p[29] ^ p[30] ^ p[31];
    p[32] = p[33] ^ p[34] ^ p[35] ^ p[36] ^ p[37] ^ p[38];

    code[0] |= p[1];
    code[0] |= (p[2] << 1);
    code[0] |= (p[4] << 3);
    code[0] |= (p[8] << 7);

    code[1] |= (p[16] << 7);
    code[3] |= (p[32] << 7);
}

void code_to_bitarray(unsigned char code[5], unsigned char p[39]) {
    unsigned int i, j, bit;
    for (i = 1; i <= 38; i++) {
        j = i - 1;
        bit = j % 8;
        p[i] = (code[j / 8] & (1 << bit)) >> bit;
    }
}

void bitarray_to_wng(unsigned char p[39], unsigned char wng[6]) {
    wng[0] = p[1] ^ p[3] ^ p[5] ^ p[7] ^ p[9] ^ p[11] ^ p[13] ^ p[15] ^ p[17] ^ p[19] ^ p[21] ^ p[23] ^ p[25] ^ p[27] ^ p[29] ^ p[31] ^ p[33] ^ p[35] ^ p[37];
    wng[1] = p[2] ^ p[3] ^ p[6] ^ p[7] ^ p[10] ^ p[11] ^ p[14] ^ p[15] ^ p[18] ^ p[19] ^ p[22] ^ p[23] ^ p[26] ^ p[27] ^ p[30] ^ p[31] ^ p[34] ^ p[35] ^ p[38];
    wng[2] = p[4] ^ p[5] ^ p[6] ^ p[7] ^ p[12] ^ p[13] ^ p[14] ^ p[15] ^ p[20] ^ p[21] ^ p[22] ^ p[23] ^ p[28] ^ p[29] ^ p[30] ^ p[31] ^ p[36] ^ p[37] ^ p[38];
    wng[3] = p[8] ^ p[9] ^ p[10] ^ p[11] ^ p[12] ^ p[13] ^ p[14] ^ p[15] ^ p[24] ^ p[25] ^ p[26] ^ p[27] ^ p[28] ^ p[29] ^ p[30] ^ p[31];
    wng[4] = p[16] ^ p[17] ^ p[18] ^ p[19] ^ p[20] ^ p[21] ^ p[22] ^ p[23] ^ p[24] ^ p[25] ^ p[26] ^ p[27] ^ p[28] ^ p[29] ^ p[30] ^ p[31];
    wng[5] = p[32] ^ p[33] ^ p[34] ^ p[35] ^ p[36] ^ p[37] ^ p[38];
}

unsigned char locate_bit(unsigned char wng[6]) {
    unsigned char loc = 0;
    char i = 0;
    for (i = 5; i >= 0; i--) {
        loc |= (wng[i] << i);
    }
    return loc;
}

void bitarray_to_code(unsigned char p[39], unsigned char code[5]) {
    unsigned int i, j;
    unsigned char bit;
    memset(code, 0, sizeof(code));
    for(i = 1; i <= 38; i++) {
        j = i - 1;
        bit = j % 8;
        code[j / 8] |= (p[i] << bit);
    }
}

void bitarray_to_data(unsigned char p[39], unsigned char data[4]) {
    memset(data, 0, sizeof(data));
    unsigned char d[32];
    unsigned char bit = 0;
    unsigned int i, j;
    j = 0;
    for (i = 1; i <= 38; i++) {
        if (i != 1 && i != 2 && i != 4 && i != 8 && i != 16 && i != 32) {
            d[j++] = p[i];
        }
    }
    for (i = 0; i < 32; i++) {
        bit = i % 8;
        data[i / 8] |= (d[i] << bit);
    }
}

bool decode(unsigned char code[5], unsigned char data[4]) {

    unsigned char bit;
    unsigned char p[39] = {0};
    unsigned char wng[6] = {0};
    unsigned char loc = 0;
    code_to_bitarray(code, p);
    bitarray_to_wng(p, wng);
    loc = locate_bit(wng);
    if (0 == loc) {
        bitarray_to_data(p, data);
        return true;
    } else {
        p[loc] = 1 - p[loc];
        bitarray_to_code(p, code);
        bitarray_to_data(p, data);
        return false;
    }
}

void filename_to_code(char filename[32], char filename_code[40]) {
    int i = 0;
    for(i = 0; i < 8; i++) {
        encode((unsigned char*)(filename + i * 4), (unsigned char*)(filename_code + i * 5));
    }
}

void code_to_filename(char filename_code[40], char filename[32]) {
    int i = 0;
    for (i = 0; i < 8; i++) {
        decode((unsigned char*)(filename_code + i * 5), (unsigned char*)(filename + i * 4));
    }
}

我用一个main程序测试

int main(int argc, char* argv[]) {

    char filename[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ01234";
    char filename_code[40];
    char filename_dst[32];
    filename_to_code(filename, filename_code);
    code_to_filename(filename_code, filename_dst);

    cout << filename <<endl;
    cout << filename_dst << endl;
    return 0;
}

输出结果经过编码解码之后的内容一致。

ABCDEFGHIJKLMNOPQRSTUVWXYZ01234
ABCDEFGHIJKLMNOPQRSTUVWXYZ01234
  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是用C语言实现海明码的代码: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> int main() { int k, n, i, j, p, q, r, s, t, u, v, w, x, y, z; int *data, *code, *temp; printf("请输入信息码的位数k:"); scanf("%d", &k); printf("请输入校验位的位数n:"); scanf("%d", &n); data = (int *)malloc(sizeof(int) * k); code = (int *)malloc(sizeof(int) * (k + n)); temp = (int *)malloc(sizeof(int) * (k + n)); printf("请输入%d位信息码:", k); for (i = 0; i < k; i++) { scanf("%d", &data[i]); } p = 0; q = 0; while (p < k) { if (pow(2, q) - 1 == p + q) { q++; } else { code[p + q] = data[p]; p++; } } for (i = 0; i < n; i++) { r = pow(2, i); s = 0; t = r; while (t <= k + n) { for (j = t; j < t + r && j <= k + n; j++) { if (j != r && j != t - 1) { s = s ^ code[j - 1]; } } t = t + 2 * r; } code[r - 1] = s; } printf("海明码为:"); for (i = 0; i < k + n; i++) { printf("%d", code[i]); } printf("\n"); printf("请输入接收到的%d位码:", k + n); for (i = 0; i < k + n; i++) { scanf("%d", &temp[i]); } u = 0; for (i = 0; i < n; i++) { v = pow(2, i); w = 0; x = v; while (x <= k + n) { for (j = x; j < x + v && j <= k + n; j++) { if (j != v && j != x - 1) { w = w ^ temp[j - 1]; } } x = x + 2 * v; } if (w != temp[v - 1]) { u = u + v; } } if (u == 0) { printf("接收到的码没有错误。\n"); } else { printf("接收到的码第%d位出现了错误。\n", u); if (temp[u - 1] == 0) { temp[u - 1] = 1; } else { temp[u - 1] = 0; } printf("正确的码为:"); for (i = 0; i < k + n; i++) { printf("%d", temp[i]); } printf("\n"); } free(data); free(code); free(temp); return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值