从uint8_t类型数组中提取位

时间:2016-12-12 18:16:44

标签: c arrays bit-manipulation

我有一个数据:ef324ad13255e219e8110044997cefaa43ff0954800000000000007存储在名为lfsr[36]的uint8_t类型数组中。

我想从数组中提取特定的,例如有点。 96,位号。 184等。

我该如何执行此操作?

4 个答案:

答案 0 :(得分:6)

如barak manos所述,正确的代码是

(lfsr[bit / 8] >> (bit % 8)) & 1

解释一下:

bit / 8从您的数组中选择一个元素。每个元素包含8位,因此除以8是将位索引转换为元素索引的简便方法。

bit % 8在元素中选择一点。这是索引的最直接选择;它计数从最低有效位到最高有效位(小端)的位。另一种变体是

7 - bit % 8

此变体以相反顺序(big-endian)计数位。出于兼容性原因,有时您必须使用它(例如JPEG格式);如果您可以自由决定选择哪个位顺序,请使用little-endian(因为它更容易)。

语法(... >> ...) & 1从数字中提取一位。有关详细信息,请参阅here

答案 1 :(得分:2)

解决方案将采用以下形式:

( lfsr[byte_idx] >> bit_idx ) & 1

但是,您没有提供足够的信息来帮助我们确定如何获取字节索引和位索引。

  • 您的索引是基于0(A,C,E,G)还是基于1(B,D,F,H)?
  • lfsr[0](A,B,C,D)或lfsr[35](E,F,G,H)中的第一位?
  • 这些位是从最不重要的(C,D,G,H)还是从最重要的(A,B,E,F)编号?

以下图表涵盖了所有这些组合:

                                   A     B     C     D     E     F     G     H
                         +---+                                                
 ( lfsr[ 0] >> 7 ) & 1   |   |     0     1     7     8   280   281   287   288
 ( lfsr[ 0] >> 6 ) & 1   |   |     1     2     6     7   281   282   286   287
 ( lfsr[ 0] >> 5 ) & 1   |   |     2     3     5     6   282   283   285   286
 ( lfsr[ 0] >> 4 ) & 1   |   |     3     4     4     5   283   284   284   285
 ( lfsr[ 0] >> 3 ) & 1   |   |     4     5     3     4   284   285   283   284
 ( lfsr[ 0] >> 2 ) & 1   |   |     5     6     2     3   285   286   282   283
 ( lfsr[ 0] >> 1 ) & 1   |   |     6     7     1     2   286   287   281   282
 ( lfsr[ 0] >> 0 ) & 1   |   |     7     8     0     1   287   288   280   281
                         +---+                                                
 ( lfsr[ 1] >> 7 ) & 1   |   |     8     9    15    16   272   273   279   280
 ( lfsr[ 1] >> 6 ) & 1   |   |     9    10    14    15   273   274   278   279
 ( lfsr[ 1] >> 5 ) & 1   |   |    10    11    13    14   274   275   277   278
 ( lfsr[ 1] >> 4 ) & 1   |   |    11    12    12    13   275   276   276   277
 ( lfsr[ 1] >> 3 ) & 1   |   |    12    13    11    12   276   277   275   276
 ( lfsr[ 1] >> 2 ) & 1   |   |    13    14    10    11   277   278   274   275
 ( lfsr[ 1] >> 1 ) & 1   |   |    14    15     9    10   278   279   273   274
 ( lfsr[ 1] >> 0 ) & 1   |   |    15    16     8     9   279   280   272   273
                         +---+                                                
                         | . |                                                
                           .                                                  
                         | . |                                                
                         +---+                                                
 ( lfsr[34] >> 7 ) & 1   |   |   272   273   279   280     8     9    15    16
 ( lfsr[34] >> 6 ) & 1   |   |   273   274   278   279     9    10    14    15
 ( lfsr[34] >> 5 ) & 1   |   |   274   275   277   278    10    11    13    14
 ( lfsr[34] >> 4 ) & 1   |   |   275   276   276   277    11    12    12    13
 ( lfsr[34] >> 3 ) & 1   |   |   276   277   275   276    12    13    11    12
 ( lfsr[34] >> 2 ) & 1   |   |   277   278   274   275    13    14    10    11
 ( lfsr[34] >> 1 ) & 1   |   |   278   279   273   274    14    15     9    10
 ( lfsr[34] >> 0 ) & 1   |   |   279   280   272   273    15    16     8     9
                         +---+                                                
 ( lfsr[35] >> 7 ) & 1   |   |   280   281   287   288     0     1     7     8
 ( lfsr[35] >> 6 ) & 1   |   |   281   282   286   287     1     2     6     7
 ( lfsr[35] >> 5 ) & 1   |   |   282   283   285   286     2     3     5     6
 ( lfsr[35] >> 4 ) & 1   |   |   283   284   284   285     3     4     4     5
 ( lfsr[35] >> 3 ) & 1   |   |   284   285   283   284     4     5     3     4
 ( lfsr[35] >> 2 ) & 1   |   |   285   286   282   283     5     6     2     3
 ( lfsr[35] >> 1 ) & 1   |   |   286   287   281   282     6     7     1     2
 ( lfsr[35] >> 0 ) & 1   |   |   287   288   280   281     7     8     0     1
                         +---+

以下是如何获取每种索引方法的位:

A: int bit96 = ( lfsr[                   96    / 8       ] >> ( 7 - (  96    % 8 ) ) ) & 1;
B: int bit96 = ( lfsr[                  (96-1) / 8       ] >> ( 7 - ( (96-1) % 8 ) ) ) & 1;
C: int bit96 = ( lfsr[                   96    / 8       ] >> (        96    % 8   ) ) & 1;
D: int bit96 = ( lfsr[                  (96-1) / 8       ] >> (       (96-1) % 8   ) ) & 1;
E: int bit96 = ( lfsr[ sizeof(lfsr) - (  96    / 8 ) - 1 ] >> ( 7 - (  96    % 8 ) ) ) & 1;
F: int bit96 = ( lfsr[ sizeof(lfsr) - ( (96-1) / 8 ) - 1 ] >> ( 7 - ( (96-1) % 8 ) ) ) & 1;
G: int bit96 = ( lfsr[ sizeof(lfsr) - (  96    / 8 ) - 1 ] >> (        96    % 8   ) ) & 1;
H: int bit96 = ( lfsr[ sizeof(lfsr) - ( (96-1) / 8 ) - 1 ] >> (       (96-1) % 8   ) ) & 1;

G最有可能。 A和B是下一个最有可能的。 E极不可能,F仅包括完整性。

答案 2 :(得分:0)

您可以尝试使用遮罩和按位AND。例如,您可以通过执行类似0x1&的操作来获取LSB。 (从中提取位的数字)。抓住第二个将是0x2,第三个是0x4等等。

答案 3 :(得分:-1)

您可以使用相同的数组

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

#define MOST_LEFT_BIT_UINT8 (UINT8_MAX / 2 + 1)

int main(void) {
  uint8_t lfsr[56] = "ef324ad13255e219e8110044997cefaa43ff0954800000000000007";

  for (size_t i = 0; i < sizeof lfsr - 1; i++) {
    for (size_t j = 0; j < 8; j++) {
      if (lfsr[i] & (MOST_LEFT_BIT_UINT8 >> j))
        printf("1");
      else
        printf("0");
    }
    printf(" ");
  }
  printf("\n");
}