2017-03-31 59 views
0

我有一个是在六e.g表示手法与比特

4d42 b666 000a 0000 0000 0036 0000 0028 

前4个字节表示,其我想提取值二进制文件。

我知道我可以用鼠标右键

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

这将导致3060157762

但是使用

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; 

这导致1112368822这显然不同的解压缩。

我不知道我们怎么能用第二种方法实现相同的结果?什么是这样的一些按位技巧?除了我所展示的方法之外,我想不出任何东西。

感谢您的帮助。

+0

提示:3060157762给112368822如果颠倒的字节顺序。查找[Endianness](https://en.wikipedia.org/wiki/Endianness) –

+0

为什么使用8字节类型来读取4个字节?在可能会破坏你的程序的小端平台上。 – Slava

+0

@Slava你的意思是unsigned char?它的范围是0-255,所以它应该是1个字节,或者我错了吗? – Darlyn

回答

2

首先,使用4字节类型来存储4个字节。你不需要64位的类型。问题在于你在循环中颠倒你的号码。 你的第二个方法读取4个字节到testtest[0] = 0x4, test[1] = 0xd, test[2] = 0x4, test[3] = 0x2。然后你要做的是从右到左填充t的字节反向顺序。首先,用0x4填充最右边的字节,然后相应地向左移动0xd,0x4和0x2。所以你得到t == 0x24d4。该做的事儿


代码:

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;