hex_dump/
lib.rs

1#[allow(warnings)]
2pub mod hex_vec {
3    use std::error::Error;
4    use std::fs::File;
5    use std::io::{self, Read};
6    use std::path::Path;
7    const BYTES_PER_LINE: usize = 16;
8    pub fn vec_to_hex(vec: &Vec<u8>) -> String {
9        let hex_chars: Vec<char> = "0123456789abcdef".chars().collect();
10        let mut hex_string = String::new();
11        for byte in vec {
12            hex_string.push(hex_chars[(byte >> 4) as usize]);
13            hex_string.push(hex_chars[(byte & 0x0f) as usize]);
14            hex_string.push(' ');
15        }
16        hex_string.to_ascii_uppercase()
17    }
18    pub fn hex_to_vec(hex_string: String) -> Vec<u8> {
19        let mut vec = Vec::new();
20        let mut chars = hex_string.chars().peekable();
21        while let Some(c) = chars.next() {
22            if let Some(nibble1) = "0123456789abcdef".find(c.to_ascii_lowercase()) {
23                if let Some(nibble2) = chars
24                    .next()
25                    .and_then(|c| "0123456789abcdef".find(c.to_ascii_lowercase()))
26                {
27                    vec.push((nibble1 << 4 | nibble2) as u8);
28                }
29            }
30        }
31        vec
32    }
33    #[derive(Clone)]
34    pub struct HexInfo {
35        pub hex_vec: Vec<u8>,
36        pub address_vec: Vec<String>,
37    }
38    pub fn read_file<P: AsRef<Path>>(path: P) -> io::Result<HexInfo> {
39        let mut file = File::open(path)?;
40        let mut buf = Vec::new();
41        file.read_to_end(&mut buf)?;
42        Ok(HexInfo {
43            hex_vec: buf.clone(),
44            address_vec: buf_to_address(buf.clone()),
45        })
46    }
47    pub fn buf_to_address(buf: Vec<u8>) -> Vec<String> {
48        let mut res = vec![];
49        for (i, chunk) in buf.chunks(BYTES_PER_LINE).enumerate() {
50            res.push(format!("{:08X}", i * BYTES_PER_LINE));
51        }
52        res
53    }
54
55    pub fn buf_to_hex(buf: Vec<u8>) -> Vec<String> {
56        buf.into_iter()
57            .map(|b| format!("{:02X}", b))
58            .collect::<Vec<String>>()
59    }
60
61    pub fn hex_to_buf(hex_strings: Vec<String>) -> Vec<u8> {
62        hex_strings
63            .into_iter()
64            .map(|hex_str| u8::from_str_radix(&hex_str, 16).unwrap())
65            .collect::<Vec<u8>>()
66    }
67
68    pub fn find_position(
69        address_vec: Vec<String>,
70        addr: String,
71        column: usize,
72    ) -> Result<usize, usize> {
73        let find_address_position = |addr_vec: Vec<String>, addr: String| -> Result<usize, usize> {
74            addr_vec.binary_search_by(|address| address.cmp(&addr))
75        };
76        match find_address_position(address_vec, addr) {
77            Ok(rows_num) => {
78                let position = BYTES_PER_LINE * rows_num + column;
79                Ok(position)
80            }
81            Err(e) => Err(0),
82        }
83    }
84    pub fn desplay_hex(buf: Vec<u8>) -> io::Result<()> {
85        println(format!(
86            "{:^08}  0   1  2  3  4  5  6  7  8  9 10 11 12 13 14 15",
87            "Adress"
88        ));
89
90        // 遍历缓冲区中每个字节,并打印十六进制和 ASCII 码表示
91        for (i, chunk) in buf.chunks(BYTES_PER_LINE).enumerate() {
92            // 打印十六进制表示
93            print(format!("{:08X}  ", i * BYTES_PER_LINE));
94            for b in chunk {
95                print(format!("{:02X} ", b));
96            }
97            // 打印 ASCII 码表示
98            for _ in chunk.len()..BYTES_PER_LINE {
99                print(format!("   "));
100            }
101            print(format!(" |"));
102            for b in chunk {
103                if *b > 31 && *b < 127 {
104                    print(format!("{}", *b as char));
105                } else {
106                    print(format!("."));
107                }
108            }
109            println(format!("|"));
110        }
111        Ok(())
112    }
113
114    pub fn print(s: String) {
115        use std::io::{self, Write};
116        let mut stdout = io::stdout();
117        match stdout.lock().write_all(s.as_bytes()) {
118            Ok(_) => {}
119            Err(_) => {
120                std::process::exit(1);
121            }
122        }
123        match stdout.flush() {
124            Ok(_) => {}
125            Err(_) => {
126                std::process::exit(1);
127            }
128        }
129    }
130    pub fn println(s: String) {
131        use std::io::{self, Write};
132        let mut stdout = io::stdout();
133        let mut s = s;
134        s.push_str("\n");
135
136        match stdout.lock().write_all(s.as_bytes()) {
137            Ok(_) => {}
138            Err(_) => {
139                std::process::exit(1);
140            }
141        }
142        match stdout.flush() {
143            Ok(_) => {}
144            Err(_) => {
145                std::process::exit(1);
146            }
147        }
148    }
149}