Darlyn
Darlyn

Reputation: 4940

Manipulations with bits

I have binary file that is represented in hexa e.g

 4d42 b666 000a 0000 0000 0036 0000 0028

The first 4 bytes represent value which i want to extract.

I know i can extract it right

std::ifstream is("img.bmp", std::ifstream::binary);
uint64_t data = 0;
is.read((char*)&data,4)

which would result in 3060157762

However using

  unsigned char * test   = new unsigned char [ 4  ]; 
  is.read((char*)test , 4 );
  uint64_t t = 0;
  for( int i = 0; i < 4;i++){
    t <<= 8; // 2 hexa symbols = 1 byte = 1 char = 8 bits
    t|= test[i];
  }
  cout << t << endl;

this results in 1112368822 which obviously differ.

I wonder how could we achieve same result with second method? What are some bitwise tricks for this? I cannot think of anything besides the method i have shown.

Thanks for help.

Upvotes: 1

Views: 54

Answers (1)

Alexander Lapenkov
Alexander Lapenkov

Reputation: 605

First of all, use 4 byte type to store 4 bytes. You dont need 64 bit type. The thing is that you're reversing your number in the loop. Your second method reads 4 bytes into test like that: test[0] = 0x4, test[1] = 0xd, test[2] = 0x4, test[3] = 0x2. What you do then is filling bytes of t in the reverse order, from right to the left. First, you fill the rightmost byte with 0x4, then moving to the left with 0xd, 0x4 and 0x2 accordingly. So you get t == 0x24d4.


Code that does the thing:

unsigned char * test = new unsigned char [4]; 
is.read((char*)test, 4);
uint32_t t = 0;
for(int i = 3; i >= 0; --i) {
    t <<= 8;
    t |= test[i];
}
cout << t << endl;

Upvotes: 2

Related Questions