2017-10-29 163 views
1

我想读取文件的一些原始字节,所以我查看了文档,并将一个函数放在一起,看起来应该将字节读入一个向量并读取从头开始的32位整数。为什么File :: bytes以不同于hexdump的顺序迭代字节?

fn filetobytes(name: &'static str) -> Vec<u8> { 
    let file = File::open(name).expect("No such file"); 
    let filebytes: Vec<u8> = file.bytes().map(|readbyte| readbyte.unwrap()).collect(); 

    return filebytes; 
} 

fn parse_int(index: usize, vector: &Vec<u8>) -> u32 { 
    let mut num: u32 = 0; 
    for i in 0..4 { 
     num = num << 8; 
     num = num | ((vector[index + i] as u32) & 0xff); 
     println!("Byte is {:x}", vector[index + i]); 
    } 
    return num; 
} 

fn main() { 
    let filebytes = filetobytes("diddy.h"); 
    println!("0x{:x}", parse_int(0, &filebytes)); 
} 

然后,我试图前进,但很快发现我的逻辑没有任何工作。在做了一些嗅探之后,我发现我没有按照我预期的顺序获取字节。例如,上面的代码(用于打印的前四个字节分别然后合成为一个整数)产生以下输出

Byte is 23 
Byte is 64 
Byte is 65 
Byte is 66 
0x23646566 

如果我上diddy.h一个hexdump,我得到以下输出。

0000000 6423 6665 6e69 2065 4944 4444 5f59 4957 
0000010 5444 2048 3031 0a35 6423 6665 6e69 2065 
0000020 4944 4444 5f59 4548 4749 5448 3120 3035 
0000030 630a 6e6f 7473 7520 736e 6769 656e 2064 
0000040 6873 726f 2074 6964 6464 5f79 6164 6174 
0000050 315b 3735 3035 3b5d 000a    
0000059 

奇怪的是,似乎vector[0]访问字节1,vector[1]访问字节0,vector[2]得到字节3,vector[3]得到字节2,依此类推。

我可能做了什么导致这种行为,我该如何解决它?

+1

尝试'hexdump -C' – ildjarn

+1

@ pipsqueaker117如果你回答自己的问题,你可以做它作为答案,所以你可以把它标记为已解决? – heinrich5991

+0

是的,请删除已编辑的部分并将其作为回答发布。这是[非常好](https://stackoverflow.com/help/self-answer)在stackoverflow上回答你自己的问题。 – user4815162342

回答

-1

我会建议使用Bytes create,你应该可以写你的parse_int功能:

use bytes::{ByteOrder, BigEndian, LittleEndian}; 

fn parse_int(index: usize, vector: &[u8]) -> u32 { 
    // BigEndian/Little Edian here should be determined by the file format, NOT the system format 
    LittleEndian::read_u32(&vector[index]) 
} 
0

似乎hexdump是什么错误的顺序被实际显示。 hexdump -C正确地读取它。

+0

hexdump默认为其“-x”选项,该选项将每2个字节显示为一个十六进制数字。 –

1

月Zerebecki的评论是正确的,但可能会受益于一点的阐述:

hexdump都默认为您展示文件作为16位整数值的集合。他们似乎错误顺序的原因是Hexdump尊重主机的字节序,并将其运行在小端机器上。

让我们做一个使用hexdump的自定义输出格式选项的例子。首先,我们将编写一个兼容xxd的hexdump,并将其转换为二进制。

$ echo 00000000: 01 23 45 67 89 ab cd ef > num.hex 
$ xxd -r num.hex num.bin 

然后,我们将证明自己,hexdump都可以使用规范输出模式阅读:

$ hexdump -C num.bin 
00000000 01 23 45 67 89 ab cd ef       |.#Eg....| 
00000008 

接下来,我们将使用它的默默无闻的输出格式选项来显示值作为十六进制,但选择1,2,4,和8个字节是一次:

$ hexdump -e '1/1 "%02x "' num.bin 
01 23 45 67 89 ab cd ef 
$ hexdump -e '1/2 "%02x "' num.bin 
2301 6745 ab89 efcd 
$ hexdump -e '1/4 "%02x "' num.bin 
67452301 efcdab89 
$ hexdump -e '1/8 "%02x "' num.bin 
efcdab8967452301 

你看到的是hexdump都可以解释这些字节varyin作为小端整数g的大小,并执行所需的字节交换,以将最重要的数字放在左边......我们喜欢表示数字的方式。

相关问题