You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现海绵结构时触发Segmentation fault的问题排查

问题分析与解决方案

核心问题原因

  1. 数组越界访问触发内存污染:status_permutieren函数的循环从i=0开始,此时status[i - 16 + j]等价于status[-16 + j],属于非法越界访问,会破坏内存中其他区域的数据,导致后续subbytes函数中list[i]的值超出tab数组的合法索引范围(0-255),最终触发Segmentation fault。
  2. 未确保下标合法性:tab数组仅有256个元素,但list[i]是int类型,若其值为负数或大于255,直接作为下标访问tab会导致越界错误。

修复步骤

1. 修正status_permutieren的循环起始值

将循环起始i从0改为16,避免访问status数组以外的内存:

void status_permutieren() {
    int temp[16];
    // 从i=16开始,确保i-16为合法下标(0 <= i-16 < 208)
    for (int i = 16; i < 208; i += 16) {
        for (int j = 0; j < 16; j++) {
            status[i + j] ^= status[i - 16 + j];
            temp[j] = status[i + j];
        }
        prp(temp, &status[i]);
    }
}

2. 强制保证tab下标在合法范围

在subbytes函数中,将list[i]强制转换为unsigned char,确保其值落在0-255之间:

void subbytes(int *list, int *result) {
    for (int i = 0; i < 16; i++) {
        // 强制转换为无符号字节,避免负数或超范围值作为下标
        result[i] = tab[(unsigned char)list[i]];
    }
}

3. 可选:添加断言调试(快速定位非法下标)

可以加入断言,在调试阶段快速发现非法下标问题:

#include <assert.h> // 需要包含此头文件

void subbytes(int *list, int *result) {
    for (int i = 0; i < 16; i++) {
        unsigned char idx = (unsigned char)list[i];
        assert(idx < sizeof(tab)/sizeof(tab[0])); // 断言下标合法
        result[i] = tab[idx];
    }
}

修正后的完整代码(关键部分已修改)

#include <stdio.h>
#include <assert.h> // 可选,用于调试断言

int tab[] = {129, 160, 71, 24, 142, 254, 178, 152, 182, 53, 190, 133, 149, 187, 56, 14, 198, 62, 192, 118, 121, 4, 125, 146, 90, 207, 66, 31, 19, 7, 132, 114, 68, 202, 208, 80, 37, 40, 134, 58, 111, 42, 250, 105, 180, 41, 156, 155, 166, 211, 170, 215, 165, 69, 88, 23, 6, 141, 226, 186, 35, 28, 54, 193, 89, 92, 230, 120, 44, 59, 64, 237, 151, 91, 116, 171, 87, 115, 26, 137, 67, 78, 194, 5, 29, 167, 189, 17, 253, 124, 238, 65, 184, 30, 185, 220, 84, 172, 123, 174, 18, 117, 153, 150, 128, 74, 162, 98, 212, 231, 159, 242, 206, 93, 188, 46, 76, 243, 147, 240, 219, 179, 139, 246, 255, 130, 195, 99, 161, 183, 245, 22, 140, 45, 173, 163, 148, 33, 20, 47, 216, 131, 12, 72, 223, 32, 145, 94, 249, 96, 205, 10, 157, 57, 95, 136, 138, 218, 229, 0, 122, 107, 126, 113, 109, 127, 158, 168, 210, 236, 204, 112, 191, 252, 104, 48, 73, 79, 197, 52, 108, 176, 38, 102, 100, 164, 247, 61, 2, 241, 43, 224, 119, 75, 63, 25, 143, 225, 97, 217, 106, 203, 110, 49, 200, 1, 39, 233, 3, 214, 81, 209, 60, 244, 34, 154, 239, 9, 101, 232, 235, 85, 83, 50, 86, 169, 51, 222, 251, 175, 144, 135, 16, 70, 248, 15, 82, 234, 27, 228, 8, 55, 21, 221, 36, 196, 177, 77, 227, 199, 213, 13, 201, 11, 103, 181};

int status[208];

void mixRows_gerade_runde_(int *liste, int *result) {
    result[0] = (liste[0] ^ 0xd3);
    result[1] = (liste[1] ^ liste[0] ^ 0xd3);
    result[2] = (liste[2] ^ liste[1] ^ liste[0] ^ 0xd3);
    result[3] = (liste[3] ^ liste[2] ^ liste[1] ^ liste[0] ^ 0xd3);
    result[4] = (liste[4] ^ 0xd4);
    result[5] = (liste[5] ^ liste[4] ^ 0xd4);
    result[6] = (liste[6] ^ liste[5] ^ liste[4] ^ 0xd4);
    result[7] = (liste[7] ^ liste[6] ^ liste[5] ^ liste[4] ^ 0xd4);
    result[8] = (liste[8] ^ 0xd5);
    result[9] = (liste[9] ^ liste[8] ^ 0xd5);
    result[10] = (liste[10] ^ liste[9] ^ liste[8] ^ 0xd5);
    result[11] = (liste[11] ^ liste[10] ^ liste[9] ^ liste[8] ^ 0xd5);
    result[12] = (liste[12] ^ 0xd6);
    result[13] = (liste[12] ^ liste[13] ^ 0xd6);
    result[14] = (liste[12] ^ liste[13] ^ liste[14] ^ 0xd6);
    result[15] = (liste[12] ^ liste[13] ^ liste[14] ^ liste[15] ^ 0xd6);
}

void mixRows_ungerade_runde_(int *liste, int *result) {
    result[0] = (liste[3] ^ liste[2] ^ liste[1] ^ liste[0] ^ 0xd3);
    result[1] = (liste[3] ^ liste[2] ^ liste[1] ^ 0xd3);
    result[2] = (liste[3] ^ liste[2] ^ 0xd3);
    result[3] = (liste[3] ^ 0xd3);
    result[4] = (liste[7] ^ liste[6] ^ liste[5] ^ liste[4] ^ 0xd4);
    result[5] = (liste[5] ^ liste[7] ^ liste[6] ^ 0xd4);
    result[6] = (liste[7] ^ liste[6] ^ 0xd4);
    result[7] = (liste[7] ^ 0xd4);
    result[8] = (liste[8] ^ liste[9] ^ liste[10] ^ liste[11] ^ 0xd5);
    result[9] = (liste[9] ^ liste[11] ^ liste[10] ^ 0xd5);
    result[10] = (liste[10] ^ liste[11] ^ 0xd5);
    result[11] = (liste[11] ^ 0xd5);
    result[12] = (liste[12] ^ liste[13] ^ liste[14] ^ liste[15] ^ 0xd6);
    result[13] = (liste[13] ^ liste[14] ^ liste[15] ^ 0xd6);
    result[14] = (liste[14] ^ liste[15] ^ 0xd6);
    result[15] = (liste[15] ^ 0xd6);
}

void liste_zu_status(int *list) {
    for (int i = 0; i < 16; i++) {
        status[i] ^= list[i];
    }
}

void subbytes(int *list, int *result) {
    for (int i = 0; i < 16; i++) {
        unsigned char idx = (unsigned char)list[i];
        assert(idx < sizeof(tab)/sizeof(tab[0]));
        result[i] = tab[idx];
    }
}

void shift_colums(int *list, int *result) {
    result[0] = list[0];
    result[1] = list[13];
    result[2] = list[10];
    result[3] = list[7];
    result[4] = list[4];
    result[5] = list[1];
    result[6] = list[14];
    result[7] = list[11];
    result[8] = list[8];
    result[9] = list[5];
    result[10] = list[2];
    result[11] = list[15];
    result[12] = list[12];
    result[13] = list[9];
    result[14] = list[6];
    result[15] = list[3];
}

void prp(int *block, int *result) {
    int temp[16];
    subbytes(block, temp);
    mixRows_gerade_runde_(temp, result);
    shift_colums(result, temp);
    subbytes(temp, result);
    mixRows_gerade_runde_(result, temp);
    shift_colums(temp, result);
    subbytes(result, temp);
    mixRows_ungerade_runde_(temp, result);
    shift_colums(result, temp);
    subbytes(temp, result);
    mixRows_ungerade_runde_(result, temp);
    shift_colums(temp, result);
    subbytes(temp, result);
    mixRows_ungerade_runde_(result, temp);
    shift_colums(temp, result);
    subbytes(temp, result);
}

void status_permutieren() {
    int temp[16];
    for (int i = 16; i < 208; i += 16) {
        for (int j = 0; j < 16; j++) {
            status[i + j] ^= status[i - 16 + j];
            temp[j] = status[i + j];
        }
        prp(temp, &status[i]);
    }
}

void block_absorbieren(int *block) {
    for (int i = 0; i < 16; i++) {
        status[i] ^= block[i];
    }
    status_permutieren();
}

void status_zuruecksetzen() {
    for (int i = 0; i < 208; i++) {
        status[i] = 0;
    }
}

void daten_absorbieren(int *daten, int len) {
    int temp[16];
    for (int i = 0; i < len; i += 16) {
        for (int j = 0; j < 16; j++) {
            temp[j] = (i + j < len)? daten[i + j] : 0;
        }
        block_absorbieren(temp);
    }
}

void daten_generieren(int menge, int *ergebnis) {
    for (int i = 0; i < menge; i++) {
        ergebnis[i] = status[207] ^ status[206] ^ ~status[202] & status[197] | status[196] ^ status[189];
        status_permutieren();
    }
}

int main() {
    printf("starting\n");
    // Initialize status array with zeros
    for (int i = 0; i < 208; i++) {
        status[i] = 0;
    }

    // Example usage
    int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
    int generated_data[10];

    // Absorb data
    daten_absorbieren(data, sizeof(data) / sizeof(data[0]));

    // Generate data
    daten_generieren(10, generated_data);

    // Print generated data
    printf("Generated data:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", generated_data[i]);
    }
    printf("\n");

    return 0;
}

内容的提问来源于stack exchange,提问作者Ruben Wulf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 22:10:54