C语言字符编码问题:High Nibble计算错误排查
编码字符"A"时高4位结果错误的排查与修复
我尝试对字符“A”(二进制为0100 0001)进行编码,期望输出文件中得到“dq”(d对应高4位编码结果,q对应低4位编码结果)。目前低4位的结果q是正确的,但始终无法得到正确的高4位结果d。
预期输出
Input byte: 0100 0001 (A)
Encoded byte high: 0110 0100 (d)
Encoded byte low: 0111 0001 (q)
实际输出
Input byte: 0100 0001 (A)
Encoded byte high: 1100 0100 (�)
Encoded byte low: 0111 0001 (q)
完整程序代码
#include <stdio.h> #include <stdbool.h> #include <stdint.h> bool encodeByte(uint8_t inputByte, uint8_t* encodedByteHigh, uint8_t* encodedByteLow) { uint8_t p0, p1, p2; uint8_t d0, d1, d2, d3; d0 = (inputByte >> 0) & 0x01; d1 = (inputByte >> 1) & 0x01; d2 = (inputByte >> 2) & 0x01; d3 = (inputByte >> 3) & 0x01; p0 = d0 ^ d1 ^ d2; p1 = d0 ^ d1 ^ d3; p2 = d0 ^ d2 ^ d3; if (p0 == 0) { *encodedByteLow = inputByte & 0x0F; } else { *encodedByteLow = inputByte | 0x10; } if (p1 == 0) { *encodedByteLow = *encodedByteLow & 0x1F; } else { *encodedByteLow = *encodedByteLow | 0x20; } if (p2 == 0) { *encodedByteLow = *encodedByteLow & 0x3F; } else { *encodedByteLow = *encodedByteLow | 0x40; } *encodedByteHigh = inputByte >> 4; p0 = p0 ^ ((inputByte >> 4) & 0x01); p1 = p1 ^ ((inputByte >> 5) & 0x01); p2 = p2 ^ ((inputByte >> 6) & 0x01); if (p0 == 0) { *encodedByteHigh = *encodedByteHigh & 0x7F; } else { *encodedByteHigh = *encodedByteHigh | 0x80; } if (p1 == 0) { *encodedByteHigh = *encodedByteHigh & 0xBF; } else { *encodedByteHigh = *encodedByteHigh | 0x40; } if (p2 == 0) { *encodedByteHigh = *encodedByteHigh & 0xDF; } else { *encodedByteHigh = *encodedByteHigh | 0x20; } return true; } void printBinary(uint8_t byte) { for (int8_t i = 7; i >= 4; --i) { printf("%d", (byte >> i) & 0x01); } printf(" "); for (int8_t i = 3; i >= 0; --i) { printf("%d", (byte >> i) & 0x01); } } int main() { FILE* inputFile = fopen("inputData.txt", "r"); FILE* outputFile = fopen("encodedData.txt", "w"); if (inputFile == NULL || outputFile == NULL) { printf("Failed to open files.\n"); return 1; } uint8_t inputByte; uint8_t encodedByteHigh; uint8_t encodedByteLow; while (fscanf(inputFile, "%c", &inputByte) != EOF) { encodeByte(inputByte, &encodedByteHigh, &encodedByteLow); fprintf(outputFile, "%c%c", encodedByteHigh, encodedByteLow); //print inputbyte, encodedbytehigh, encodedbytelow printf("Input byte: "); printBinary(inputByte); printf("\n"); printf("Encoded byte high: "); printBinary(encodedByteHigh); printf("\n"); printf("Encoded byte low: "); printBinary(encodedByteLow); printf("\n"); } fclose(inputFile); fclose(outputFile); printf("Encoding complete.\n"); return 0; }
问题原因与修复方案
错误根源
- 校验位计算逻辑错误:原代码复用了低4位的校验位
p0/p1/p2,再异或高4位的部分位来计算高4位的校验位,这不符合编码规则——高4位的校验位应该基于自身的4个数据位独立计算。 - 位操作掩码错误:对高4位编码结果操作时,错误修改了最高位(0x80位),导致结果出现异常位。
修复后的encodeByte函数
bool encodeByte(uint8_t inputByte, uint8_t* encodedByteHigh, uint8_t* encodedByteLow) { // 处理低4位(原有逻辑正确,简化写法) uint8_t d0 = (inputByte >> 0) & 0x01; uint8_t d1 = (inputByte >> 1) & 0x01; uint8_t d2 = (inputByte >> 2) & 0x01; uint8_t d3 = (inputByte >> 3) & 0x01; uint8_t p0_low = d0 ^ d1 ^ d2; uint8_t p1_low = d0 ^ d1 ^ d3; uint8_t p2_low = d0 ^ d2 ^ d3; *encodedByteLow = inputByte & 0x0F; if (p0_low) *encodedByteLow |= 0x10; if (p1_low) *encodedByteLow |= 0x20; if (p2_low) *encodedByteLow |= 0x40; // 处理高4位(重新独立计算校验位) uint8_t d4 = (inputByte >> 4) & 0x01; uint8_t d5 = (inputByte >> 5) & 0x01; uint8_t d6 = (inputByte >> 6) & 0x01; uint8_t d7 = (inputByte >> 7) & 0x01; uint8_t p0_high = d4 ^ d5 ^ d6; uint8_t p1_high = d4 ^ d5 ^ d7; uint8_t p2_high = d4 ^ d6 ^ d7; *encodedByteHigh = (inputByte >> 4) & 0x0F; if (p0_high) *encodedByteHigh |= 0x10; if (p1_high) *encodedByteHigh |= 0x20; if (p2_high) *encodedByteHigh |= 0x40; return true; }
修复说明
- 低4位逻辑保留并简化,确保原有正确结果不变。
- 高4位独立提取4个数据位,重新计算对应校验位,并将校验位设置到
0x10、0x20、0x40位(对应第4、5、6位),最终得到0110 0100(十进制100,对应字符'd'),符合预期。
内容的提问来源于stack exchange,提问作者skullyurd
相关产品推荐
相关产品推荐

