2017-10-29 118 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的大小,並執行所需的字節交換,以將最重要的數字放在左邊......我們喜歡錶示數字的方式。