How to take to nibbles from a byte of data that are chars into two bytes stored in another variable in order to unmask - c

I have two uint_16ts that I've gotten from the nibbles of my data as seen in the code below. I need to put that into mask set so that each of the nibbles are now in its own byte. The code I got is below I can't for the life of me figure it out. I need to do this cause this will create the mask I will use to unmask mildly encrypted data.
uint16_t length = *(offset+start) - 3;
uint16_t mask = length;
if(Fmt == ENCRYPTED) {
char frstDig = (length & 0x000F)
char scndDig = (length & 0x00F0) >> 4;
mask =

Shift one of the digits by 8 bits, and OR them together.
mask = (scndDig << 8) | frstDig;

Related

C not calculating bitwise operations properly

I have a list of 16-bit (unsigned shorts) blocks which I receive from another part of program which I want to write to a binary file. I am trying to split these into 8-bit characters so I devised this method:
int blocks = 1;
unsigned short stuffToWrite[blocks];
stuffToWrite[0] = 0b0100101011110111;
int charsPerBlock = sizeof(unsigned short) / sizeof(char);
char charsToWrite[blocks * charsPerBlock];
for (int i = 0; i < blocks; i++) {
for (int j = 0; j < charsPerBlock; j++) {
charsToWrite[i*charsPerBlock+j] = (stuffToWrite[i] & ((((int) pow(2, sizeof(char)*8)-1) << ((charsPerBlock-1)*sizeof(char)*8)) >> (j*sizeof(char)*8))) >> ((charsPerBlock-j-1)*sizeof(char)*8);
// Testing line //
printf("%u = (%u & %u) >> %lu\n", charsToWrite[i*charsPerBlock+j], stuffToWrite[i], (((int) pow(2, sizeof(char)*8)-1) << ((charsPerBlock-1)*sizeof(char)*8)) >> j*sizeof(char)*8, (charsPerBlock-j-1)*sizeof(char)*8);
}
This looks quite complicated but it's not really. I am just creating a 8 bit mask ((int) pow(2, sizeof(char)*8)-1)), shifting it to the first bits (<< ((charsPerBlock-1)*sizeof(char)*8))) then shifting it back into the right position (>> (j*sizeof(char)*8)))). I then AND this with the original block and shift it back to the lowest bits to become a character (>> ((charsPerBlock-j-1)*sizeof(char)*8)).
This works fine for the first block, giving me 74 or 01001010. However, the second block gives me a very large incorrect number. I am not sure what was going wrong here as I am pretty sure my method works well so I wrote up a test line to break up the steps which yielded the following:
74 = (19191 & 65280) >> 8
4294967287 = (19191 & 255) >> 0
Which is obviously wrong.
I would appreciate any help identifying the error and how to fix it (also if there is a better way to do this).
This looks quite complicated but it's not really.
It is. If you are just looking to serialize data into bytes, then all you need is this:
int blocks = 1;
uint16_t stuffToWrite[blocks] = { 0b0100101011110111 };
char charsToWrite[blocks * sizeof(uint16_t)] =
{
(stuffToWrite[0] >> 8) & 0xFFu,
(stuffToWrite[0] ) & 0xFFu,
};
This works regardless of endianess of the incoming data, but it assumes that the output data has the most significant byte first.
Similarly for a 32 bit number you'd go >> 24, >> 16, >> 8 and >> 0.
Also please note that when doing bitwise arithmetic, never use the following types: signed types, char, floating point.

How does this bitwise hamming(31,26) encoder work in C? (Bitmasking)

I understand what the individual operations are (such as the bitwise ANDs an ORs), but I don't understand why they have been used where they have been.
Also, my understanding is that the first set of masks are used to compute parity bits. But I don't understand why the 2nd set of masks have been chosen or what their purpose is. Can anyone help me get my head around this please?
rawData is the input word that is to be encoded by the hamming.c function.
Doing the encoding of a [31,26] Hamming code, the function hammingEncode() encodes a message rawData consisting of 26 message bits by inserting 5 parity bits on positions 0, 1, 3, 7 and 15 (counting bits starting from 0).
The purpose of the part you are asking about:
unsigned int mask1 = 0b11111111111111100000000000;
unsigned int mask2 = 0b00000000000000011111110000;
unsigned int mask3 = 0b00000000000000000000001110;
unsigned int mask4 = 0b00000000000000000000000001;
encodedData |= (rawData & mask1) << 5;
encodedData |= (rawData & mask2) << 4;
encodedData |= (rawData & mask3) << 3;
encodedData |= (rawData & mask4) << 2;
is to move the 26 message bits into the correct positions: 16-30, 8-14, 4-6 and 2 using mask1, mask2, mask3 and mask4 respectively.
After that, the parity bits are calculated and inserted on their correct positions.

Turn byte into array of bits? C

I want to read binary file byte at the time and then store bits of that byte into integer array. And similarly I want to write integer array of 1s and 0s (8 of them ) into binary file as bytes?
If you have an array of bytes:
unsigned char bytes[10];
And want to change it into an array of bits:
unsigned char bits[80];
And assuming you have 8 bits per byte, try this:
int i;
for (i=0; i<sizeof(bytes)*8; i++) {
bits[i] = ((1 << (i % 8)) & (bytes[i/8])) >> (i % 8);
}
In this loop, i loops through the total number of bits. The byte that a given bit lives at is i/8, which as integer division rounds down. The position of the bit within a byte is i%8.
First we create a mask for the desired bit:
1 << (i % 8)
Then the desired byte:
bytes[i/8]
Then we perform a logical AND to clear all bits except the one we want.
(1 << (i % 8)) & (bytes[i/8])
Then we shift the result right by the bit position to put the desired bit at the least significant bit. This gives us a value of 1 or 0.
Note also that the arrays in question are unsigned. That is required for the bit shifting to work properly.
To switch back:
int i;
memset(bytes, 0, sizeof(bytes));
for (i=0; i<sizeof(bytes)*8; i++) {
bytes[i/8] |= bits[i] << (i % 8);
}
We start by clearing out the byte array, since we'll be setting each byte one bit at a time.
Then we take the bit in question:
bits[i]
Shift it into its position:
bits[i] << (i % 8)
Then use a logical OR to set the appropriate byte;
A simple C program to do the job on a byte array 'input' of size 'sz' would be:
int i=0,j=0;
unsigned char mask = 0x01u;
for (i=0;i<sz;i++)
for (j=0;j<8;j++)
output[8*i+j]=((unsigned char)input[i] >> j) & (unsigned char)(mask);

Bit Shifting - Finding nth byte in a number [duplicate]

I know you can get the first byte by using
int x = number & ((1<<8)-1);
or
int x = number & 0xFF;
But I don't know how to get the nth byte of an integer.
For example, 1234 is 00000000 00000000 00000100 11010010 as 32bit integer
How can I get all of those bytes? first one would be 210, second would be 4 and the last two would be 0.
int x = (number >> (8*n)) & 0xff;
where n is 0 for the first byte, 1 for the second byte, etc.
For the (n+1)th byte in whatever order they appear in memory (which is also least- to most- significant on little-endian machines like x86):
int x = ((unsigned char *)(&number))[n];
For the (n+1)th byte from least to most significant on big-endian machines:
int x = ((unsigned char *)(&number))[sizeof(int) - 1 - n];
For the (n+1)th byte from least to most significant (any endian):
int x = ((unsigned int)number >> (n << 3)) & 0xff;
Of course, these all assume that n < sizeof(int), and that number is an int.
int nth = (number >> (n * 8)) & 0xFF;
Carry it into the lowest byte and take it in the "familiar" manner.
If you are wanting a byte, wouldn't the better solution be:
byte x = (byte)(number >> (8 * n));
This way, you are returning and dealing with a byte instead of an int, so we are using less memory, and we don't have to do the binary and operation & 0xff just to mask the result down to a byte. I also saw that the person asking the question used an int in their example, but that doesn't make it right.
I know this question was asked a long time ago, but I just ran into this problem, and I think that this is a better solution regardless.
//was trying to do inplace, would have been better if I had swapped higher and lower bytes somehow
uint32_t reverseBytes(uint32_t value) {
uint32_t temp;
size_t size=sizeof(uint32_t);
for(int i=0; i<size/2; i++){
//get byte i
temp = (value >> (8*i)) & 0xff;
//put higher in lower byte
value = ((value & (~(0xff << (8*i)))) | (value & ((0xff << (8*(size-i-1)))))>>(8*(size-2*i-1))) ;
//move lower byte which was stored in temp to higher byte
value=((value & (~(0xff << (8*(size-i-1)))))|(temp << (8*(size-i-1))));
}
return value;
}

How to extract 2 bytes from a word, and how to make a word from 2 bytes (in C)?

I am trying to extract two bytes from a 16-bit word, and to make a 16-bit word from two bytes. This is what I have tried (byte = unsigned char, word = unsigned short):
Split grpix word into 2 bytes:
word grpix; // Assume that the value has been initialized
byte grpixl = grpix & 0x00FF;
byte grpixh = grpix & 0xFF00;
Make grpix word from 2 bytes
byte grpixh; // Assume that the value has been initialized
byte grpixl; // Assume that the value has been initialized
word grpix = grpixh;
grpix <<= 8;
grpix += grpixl;
For some reason, my code doesn't work as expected, and now I'm not sure if the "splitting" of the word is wrong, if the "making" of the word is wrong, or both... Could you give me some advice?
You're not shifting when you split the word. So if grpix is 0x1234, then grpixl gets the expected 0x34 but grpixh ends up as 0x1200. You should say
byte grpixh = grpix >> 8;
Of course, you're also ignoring any endianness concerns that may be present. You should probably convert your word to a known endian (with something like htons()) before attempting to split (and do the reverse conversion when joining).
Get to know: http://graphics.stanford.edu/~seander/bithacks.html for doing all manner of operations.
right_byte = short_val & 0xFF;
left_byte = ( short_val >> 8 ) & 0xFF
short_val = ( ( left_byte & 0xFF ) << 8 ) | ( right_byte & 0xFF );
I always do a &0xFF mask to assure I have no sign problems.
The simple code that I use to solve this, is:
word=(msb<<8)+lsb;
The following routines have proved very reliable for me:-
unsigned short get16int(a) char *a;{
unsigned short hi,lo;
hi = *a++ << 8;
lo = *a & 0x00ff; /* Needed to cater for sign extending when msb bit is set */
return (hi | lo);
}
put16int(a,i) char *a; int i;{
*a++ = i >> 8;
*a = i;
}
When you mask out the high byte, you need to also shift down by 8 bits, otherwise you just end up with a 16bit number with the bottom eight bits cleared.
byte grpixh = (grpix & 0xFF00) >> 8
Also your composition can be more efficient by using or-equals instead of plus-equals:
grpix |= grpixh << 8
word grpix = grpixl+256*grpixh;

Resources