通过按位运算将位数组转换为C中的十六进制数组

Converting array of bits to array of hex in C through bitwise operations

我正在尝试将一个位数组转换为一个字节数组,但我的操作似乎正在以与我希望的方向相反的方向读取我的位。例如,假设二进制位数组是 10110111 11000000 00000110。我希望字节数组为 {B7, C0, 06}。相反,我下面的代码产生 {ED, 03, 60} 的输出,即它在相反方向上每 8 位读取一次。谁能给我一些关于我哪里出错的建议?

void find_hex_arr(uint8_t* bit_arr, int bit_len) {
  uint8_t* hex_arr = malloc(bit_len/8);
  int index = 0;
  unsigned int i = 0;
  unsigned int j = 0;
  for (i = 0; i < bit_len; i = j) {
    for (j = i; j < i + 8; ++j) {
      hex_arr[index] |= bit_arr[j] << (j - i);
    }
    index++;
  }
}

你应该改变这个:

for (i = 0; i < bit_len; i = j) {
    for (j = i; j < i + 8; ++j) {
      hex_arr[index] |= bit_arr[j] << (j - i);

进入这个:

for (i = 0; i < bit_len; i += 8) {
    for (j = 0; j < 8; ++j) {
      hex_arr[index] |= bit_arr[i+j] << (7 - j);

因为你的班次以相反的方向重新排序位。

您要移动的值就是问题所在。

第一次进入内部循环时,i 为 0,j 为 0。这使得 j-i 为 0,所以有问题的值被或运算到最右边位而不是最左边。然后当 j 是 1 你的移位 1 所以该位进入第二个右位而不是第二个左位。

所以当它应该从 7 到 0 时,你的班次从 0 到 7。你可以通过从 7 中减去班次量来解决这个问题。

hex_arr[index] |= bit_arr[j] << (7 - (j - i));

严格来说,您不需要两个循环,因为两个数组以锁步方式移动,最高可达 8 倍。

您的输入数组如下:

uint8_t bit_arr[] = {
    1, 0, 1, 1, 0, 1, 1, 1,
    1, 1, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 1, 1, 0};

期望的输出是

uint8_t expected[] = {0xB7, 0xC0, 0x06}

请注意,在此表示中最高有效位排在第一位。数组中的位 0-8 是输出字节 0 中从最高位到最低位的位,依此类推。

这与基本循环和位移的工作原理非常相配。您可以将位一位一位地推入输出数组的最低有效位:

uint8_t *hex_arr = malloc(bit_len / 8);
memset(hex_arr, 0, bit_len / 8);
for(int i = 0; i < bit_len; i++) {
    hex_arr[i / 8] <<= 1;
    hex_arr[i / 8] += bit_arr[i];
}

这个故事的寓意是,您必须小心定义表示和数据的方式。确保您从概念上了解您希望事物的发展方向,并且您不会遇到图形或内部表示的问题。