I have the data: ef324ad13255e219e8110044997cefaa43ff0954800000000000007
stored in an uint8_t type array called lfsr[36]
.
I want to extract specific bits from the array, e.g. bit no. 96, bit no. 184 etc.
How can I perform this operation?
I have the data: ef324ad13255e219e8110044997cefaa43ff0954800000000000007
stored in an uint8_t type array called lfsr[36]
.
I want to extract specific bits from the array, e.g. bit no. 96, bit no. 184 etc.
How can I perform this operation?
As noted by barak manos, the proper code is
(lfsr[bit / 8] >> (bit % 8)) & 1
To explain it:
bit / 8
chooses an element from your array. Each element contains 8 bits, so dividing by 8 is an easy way to convert a bit index to an element index.
bit % 8
chooses a bit inside the element. This is most straightforward choice of indexing; it counts bits from the least significant bit to most significant bit (little-endian). Another variant is
7 - bit % 8
This variant counts the bits in reverse order (big-endian). Sometimes you have to use it (e.g. in JPEG) for compatibility reasons; if you are free to decide which bit order to choose, use little-endian (because it's easier).
The syntax (... >> ...) & 1
extracts one bit from a number. See here for details.
The solution will take the following form:
( lfsr[byte_idx] >> bit_idx ) & 1
You didn't provide enough information to help us determine how to obtain the byte index and the bit index, though.
lfsr[0]
(A,B,C,D) or in lfsr[35]
(E,F,G,H)?All combinations of those are covered by the following chart:
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
+---+
Here's how to obtain the bit for each of the indexing methods:
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 is most likely. A and B are the next most likely. E is extremely unlikely and F was only included for completeness.
You could try using a mask and bitwise AND's. For example, you could grab the LSB by doing something like 0x1 & (number to extract bit from). Grabbing the second would be 0x2, the third 0x4, etc.
You can use the same array
#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");
}