通过按位运算将位数组转换为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];
}
这个故事的寓意是,您必须小心定义表示和数据的方式。确保您从概念上了解您希望事物的发展方向,并且您不会遇到图形或内部表示的问题。
我正在尝试将一个位数组转换为一个字节数组,但我的操作似乎正在以与我希望的方向相反的方向读取我的位。例如,假设二进制位数组是 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];
}
这个故事的寓意是,您必须小心定义表示和数据的方式。确保您从概念上了解您希望事物的发展方向,并且您不会遇到图形或内部表示的问题。