3. EDID校验和验证

EDID校验和验证 学习卡片

任务说明

EDID(Extended Display Identification Data)结构中的最后一个字节(第127字节,从0开始计数)为校验和字节。该校验和的定义为:将前127个字节的值累加,再加上校验和字节本身,所得总和的低8位必须等于0。本案例实现一个EDID校验和计算与验证工具,能够对给定的128字节EDID数据计算正确校验和,并验证已有校验和是否正确,同时处理校验失败的情况。

EDID校验和结构

EDID 128字节结构 字节 0 ~ 126(参与累加) 127 校验和 校验条件: (sum(byte[0..126]) + byte[127]) & 0xFF == 0

代码实现


#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define EDID_SIZE 128

/* 计算并返回正确的校验和字节 */
uint8_t edid_calc_checksum(const uint8_t *edid) {
    uint8_t sum = 0;
    for (int i = 0; i < EDID_SIZE - 1; i++) {
        sum += edid[i];
    }
    return (uint8_t)(0x100 - sum);  /* 使总和低8位为0 */
}

/* 验证EDID校验和,返回1表示正确,0表示错误 */
int edid_verify_checksum(const uint8_t *edid) {
    uint8_t sum = 0;
    for (int i = 0; i < EDID_SIZE; i++) {
        sum += edid[i];
    }
    return (sum == 0) ? 1 : 0;
}

/* 修复校验和:将第127字节设为正确值 */
void edid_fix_checksum(uint8_t *edid) {
    edid[127] = edid_calc_checksum(edid);
}

/* 打印EDID前8字节与校验和状态 */
void print_edid_info(const uint8_t *edid, const char *tag) {
    printf("[%s] Header: ", tag);
    for (int i = 0; i < 8; i++) {
        printf("%02X ", edid[i]);
    }
    printf("| Checksum byte: 0x%02X | Verify: %s\n",
           edid[127],
           edid_verify_checksum(edid) ? "PASS" : "FAIL");
}

int main() {
    /* 样例EDID数据(128字节,此处仅列出前8字节与最后1字节,其余填充0x00) */
    uint8_t edid[EDID_SIZE];
    memset(edid, 0x00, EDID_SIZE);

    /* 有效EDID头:00 FF FF FF FF FF FF 00 */
    uint8_t header[8] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
    memcpy(edid, header, 8);

    /* 场景1:校验和错误(初始为0x00,几乎必然错误) */
    printf("=== 场景1:校验失败 ===\n");
    print_edid_info(edid, "原始数据");

    /* 场景2:修复校验和 */
    edid_fix_checksum(edid);
    printf("=== 场景2:修复后 ===\n");
    print_edid_info(edid, "修复数据");

    /* 场景3:人为破坏校验和,验证失败处理 */
    edid[127] = 0x00;
    printf("=== 场景3:人为破坏 ===\n");
    print_edid_info(edid, "破坏数据");

    /* 场景4:重新修复,验证恢复 */
    edid_fix_checksum(edid);
    printf("=== 场景4:再次修复 ===\n");
    print_edid_info(edid, "恢复数据");

    return 0;
}

编译与运行


gcc -o edid_checksum edid_checksum.c
./edid_checksum

验证方法与判定标准

程序运行后应依次输出四个场景的EDID头部信息与校验状态。判定标准如下:

  • 场景1:原始数据(校验和字节为0x00)应显示Verify: FAIL,证明校验和验证逻辑能正确识别错误。
  • 场景2:调用edid_fix_checksum()后,校验和字节被更新,显示Verify: PASS,证明计算函数正确。
  • 场景3:人为将校验和字节改为0x00后,再次显示FAIL,证明验证函数对篡改敏感。
  • 场景4:再次修复后恢复PASS,证明修复功能可重复使用。

若四个场景输出与上述描述一致,则本案例实现通过验证。注意:本程序使用全零填充的EDID数据作为样例,仅用于演示校验和算法,不代表真实显示器的有效EDID内容。