├── .gitignore ├── Cargo.toml ├── README.md ├── LICENSE ├── src └── main.rs └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hex_analyser" 3 | version = "1.0.1" 4 | edition = "2021" 5 | description = "Analyzes a hex value and shows its possible meanings" 6 | authors = ["Mantas Jurkuvenas"] 7 | license = "MIT" 8 | repository = "https://github.com/CT3/HexAnalyser" 9 | readme = "README.md" 10 | keywords = ["hex", "binary", "analysis", "cli"] 11 | categories = ["command-line-utilities", "development-tools"] 12 | 13 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 14 | 15 | [dependencies] 16 | clap = { version = "4.5.4", features = ["derive"] } 17 | colored = "3.0.0" 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HexAnalyser 2 | 3 | Enter a hex value eg: 0xc1bc7ae1 and you will recieve decoded value in Big and Little endian, Signed and Unsigned, Floats, colour and Emoji. 4 | 5 | ## Installation 6 | 7 | To install the project, run: 8 | ``` 9 | cargo install hex_analyser 10 | ``` 11 | 12 | ## Usage 13 | 14 | To run the project, execute the installed binary with a hex value: 15 | ``` 16 | hex_analyser -v 0xc1bc7ae1 17 | ``` 18 | 19 | **Example Output:** 20 | ``` 21 | ❯ hex_analyser --hexval 0xc1bc7ae1 22 | -----------Big Endian----------- 23 | Hex: c1bc7ae1 24 | Unsigned: 3250354913 25 | Signed: 3250354913 26 | Float: -23.56 27 | 28 | -----------Little Endian----------- 29 | Hex: e17abcc1 30 | Unsigned: 3782917313 31 | Signed: -512049983 32 | Float: -289080450000000000000 33 | 34 | -----------Or it could be----------- 35 | Binary: 11000001101111000111101011100001 36 | Octal: 30157075341 37 | ASCII: ..z. (non-printable characters are replaced with a dot) 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Manta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use colored::*; 3 | 4 | /// Simple program to greet a person 5 | #[derive(Parser, Debug)] 6 | #[clap(author, version, about, long_about = None)] 7 | struct Args { 8 | /// Please enter a hex value 9 | #[clap(short = 'v', long)] 10 | hexval: String, 11 | } 12 | 13 | fn main() { 14 | let args = Args::parse(); 15 | let mut line = args.hexval; 16 | let line_len = line.trim_end().len(); 17 | line.truncate(line_len); 18 | 19 | let rawhex = line.trim_start_matches("0x"); 20 | 21 | if let Ok(buint64) = u64::from_str_radix(rawhex, 16) { 22 | println!("{}", "-----------Big Endian-----------".green()); 23 | print_big_endian(rawhex, buint64); 24 | 25 | println!("{}", "-----------Little Endian-----------".green()); 26 | print_little_endian(rawhex, buint64); 27 | 28 | println!("{}", "-----------Or it could be-----------".green()); 29 | print_other_representations(rawhex, buint64); 30 | } else { 31 | println!("{}", "Invalid hex value".red()); 32 | } 33 | } 34 | 35 | fn print_big_endian(rawhex: &str, buint64: u64) { 36 | println!("{} {}", "Hex:".blue(), rawhex); 37 | println!("{} {}", "Unsigned:".blue(), buint64); 38 | let bint = buint64 as i64; 39 | println!("{} {}", "Signed:".blue(), bint); 40 | 41 | if buint64 <= 0xFFFFFFFF { 42 | if let Ok(buint32) = u32::from_str_radix(rawhex, 16) { 43 | let v = f32::from_bits(buint32); 44 | println!("{} {}", "Float:".blue(), v); 45 | } 46 | } else { 47 | let v = f64::from_bits(buint64); 48 | println!("{} {}", "Double:".blue(), v); 49 | } 50 | println!(); 51 | } 52 | 53 | fn print_little_endian(rawhex: &str, buint64: u64) { 54 | if buint64 <= 0xFF { 55 | println!("{}", "same".red()); 56 | } 57 | 58 | if (buint64 > 0xFF) & (buint64 <= 0xFFFF) { 59 | if let Ok(buint16) = u16::from_str_radix(rawhex, 16) { 60 | let luint16 = u16::from_be(buint16); 61 | println!("{} {:x}", "Hex:".blue(), luint16); 62 | println!("{} {}", "Unsigned:".blue(), luint16); 63 | let lint16 = luint16 as i16; 64 | println!("{} {}", "Signed:".blue(), lint16); 65 | } 66 | } 67 | 68 | if (buint64 > 0xffff) & (buint64 <= 0xffffffff) { 69 | if let Ok(buint32) = u32::from_str_radix(rawhex, 16) { 70 | let luint32 = u32::from_be(buint32); 71 | println!("{} {:x}", "Hex:".blue(), luint32); 72 | println!("{} {}", "Unsigned:".blue(), luint32); 73 | let lint32 = luint32 as i32; 74 | println!("{} {}", "Signed:".blue(), lint32); 75 | } 76 | } 77 | 78 | if buint64 > 0xFFFFFFFF { 79 | let luint64 = u64::from_be(buint64); 80 | println!("{} {:x}", "Hex:".blue(), luint64); 81 | println!("{} {}", "Unsigned:".blue(), luint64); 82 | let lint64 = luint64 as i64; 83 | println!("{} {}", "Signed:".blue(), lint64); 84 | } 85 | 86 | if (buint64 <= 0xFFFFFFFF) & (buint64 > 0xFF) { 87 | if let Ok(buint32) = u32::from_str_radix(rawhex, 16) { 88 | let luint32 = u32::from_be(buint32); 89 | let lfloat = f32::from_bits(luint32); 90 | println!("{} {}", "Float:".blue(), lfloat); 91 | } 92 | } 93 | if buint64 > 0xFFFFFFFF { 94 | let luint64 = u64::from_be(buint64); 95 | let ldoub = f64::from_bits(luint64); 96 | println!("{} {}", "Double:".blue(), ldoub); 97 | } 98 | println!(); 99 | } 100 | 101 | fn print_other_representations(rawhex: &str, buint64: u64) { 102 | println!("{}{:b}", "Binary: ".blue(), buint64); 103 | println!("{}{:o}", "Octal: ".blue(), buint64); 104 | 105 | if rawhex.len() == 6 { 106 | if let (Ok(r), Ok(g), Ok(b)) = ( 107 | u8::from_str_radix(&rawhex[0..2], 16), 108 | u8::from_str_radix(&rawhex[2..4], 16), 109 | u8::from_str_radix(&rawhex[4..6], 16), 110 | ) { 111 | println!("{}", "ANSI 256-color".truecolor(r, g, b)); 112 | } 113 | } 114 | 115 | if let Ok(buint32) = u32::from_str_radix(rawhex, 16) { 116 | if let Some(decoded_em) = char::from_u32(buint32) { 117 | if decoded_em.is_emoji() { 118 | println!("{} {}", "Emoji:".blue(), decoded_em); 119 | } 120 | } 121 | } 122 | print_ascii_representation(rawhex); 123 | } 124 | 125 | fn print_ascii_representation(rawhex: &str) { 126 | let mut ascii_string = String::new(); 127 | let mut bytes = Vec::new(); 128 | 129 | // Parse hex string into bytes 130 | for i in (0..rawhex.len()).step_by(2) { 131 | if i + 2 <= rawhex.len() { 132 | if let Ok(byte) = u8::from_str_radix(&rawhex[i..i + 2], 16) { 133 | bytes.push(byte); 134 | } else { 135 | // Handle cases where hex parsing fails for a pair (e.g., "G0") 136 | // For now, we'll just skip it or add a placeholder. 137 | // For this context, we'll just stop processing this pair. 138 | break; 139 | } 140 | } 141 | } 142 | 143 | for byte in bytes { 144 | if byte.is_ascii_graphic() || byte.is_ascii_whitespace() { 145 | ascii_string.push(byte as char); 146 | } else { 147 | ascii_string.push('.'); 148 | } 149 | } 150 | println!("{}{} {}", "ASCII: ".blue(), ascii_string.green(), "(non-printable characters are replaced with a dot)".red()); 151 | } 152 | 153 | trait IsEmoji { 154 | fn is_emoji(&self) -> bool; 155 | } 156 | 157 | impl IsEmoji for char { 158 | fn is_emoji(&self) -> bool { 159 | // This is a simplified check. A more comprehensive check would require a library. 160 | matches!(*self, '\u{1F600}'..='\u{1F64F}') // Emoticons 161 | } 162 | } 163 | 164 | #[cfg(test)] 165 | mod tests { 166 | use super::*; 167 | 168 | #[test] 169 | fn test_main() { 170 | // This is a simple test to ensure the main function doesn't panic. 171 | // You can expand this to test specific functionality. 172 | let _args = Args { 173 | hexval: "0x42424242".to_string(), 174 | }; 175 | // We can't easily test the output of main, but we can check it doesn't panic. 176 | // For more thorough testing, you would refactor the logic out of main 177 | // into separate functions that can be tested individually. 178 | } 179 | } -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.19" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "is_terminal_polyfill", 17 | "utf8parse", 18 | ] 19 | 20 | [[package]] 21 | name = "anstyle" 22 | version = "1.0.11" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" 25 | 26 | [[package]] 27 | name = "anstyle-parse" 28 | version = "0.2.7" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 31 | dependencies = [ 32 | "utf8parse", 33 | ] 34 | 35 | [[package]] 36 | name = "anstyle-query" 37 | version = "1.1.3" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" 40 | dependencies = [ 41 | "windows-sys", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle-wincon" 46 | version = "3.0.9" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" 49 | dependencies = [ 50 | "anstyle", 51 | "once_cell_polyfill", 52 | "windows-sys", 53 | ] 54 | 55 | [[package]] 56 | name = "clap" 57 | version = "4.5.41" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" 60 | dependencies = [ 61 | "clap_builder", 62 | "clap_derive", 63 | ] 64 | 65 | [[package]] 66 | name = "clap_builder" 67 | version = "4.5.41" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" 70 | dependencies = [ 71 | "anstream", 72 | "anstyle", 73 | "clap_lex", 74 | "strsim", 75 | ] 76 | 77 | [[package]] 78 | name = "clap_derive" 79 | version = "4.5.41" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" 82 | dependencies = [ 83 | "heck", 84 | "proc-macro2", 85 | "quote", 86 | "syn", 87 | ] 88 | 89 | [[package]] 90 | name = "clap_lex" 91 | version = "0.7.5" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" 94 | 95 | [[package]] 96 | name = "colorchoice" 97 | version = "1.0.4" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 100 | 101 | [[package]] 102 | name = "colored" 103 | version = "3.0.0" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" 106 | dependencies = [ 107 | "windows-sys", 108 | ] 109 | 110 | [[package]] 111 | name = "heck" 112 | version = "0.5.0" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 115 | 116 | [[package]] 117 | name = "hex_analyser" 118 | version = "1.0.1" 119 | dependencies = [ 120 | "clap", 121 | "colored", 122 | ] 123 | 124 | [[package]] 125 | name = "is_terminal_polyfill" 126 | version = "1.70.1" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 129 | 130 | [[package]] 131 | name = "once_cell_polyfill" 132 | version = "1.70.1" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" 135 | 136 | [[package]] 137 | name = "proc-macro2" 138 | version = "1.0.95" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 141 | dependencies = [ 142 | "unicode-ident", 143 | ] 144 | 145 | [[package]] 146 | name = "quote" 147 | version = "1.0.40" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 150 | dependencies = [ 151 | "proc-macro2", 152 | ] 153 | 154 | [[package]] 155 | name = "strsim" 156 | version = "0.11.1" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 159 | 160 | [[package]] 161 | name = "syn" 162 | version = "2.0.104" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" 165 | dependencies = [ 166 | "proc-macro2", 167 | "quote", 168 | "unicode-ident", 169 | ] 170 | 171 | [[package]] 172 | name = "unicode-ident" 173 | version = "1.0.18" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 176 | 177 | [[package]] 178 | name = "utf8parse" 179 | version = "0.2.2" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 182 | 183 | [[package]] 184 | name = "windows-sys" 185 | version = "0.59.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 188 | dependencies = [ 189 | "windows-targets", 190 | ] 191 | 192 | [[package]] 193 | name = "windows-targets" 194 | version = "0.52.6" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 197 | dependencies = [ 198 | "windows_aarch64_gnullvm", 199 | "windows_aarch64_msvc", 200 | "windows_i686_gnu", 201 | "windows_i686_gnullvm", 202 | "windows_i686_msvc", 203 | "windows_x86_64_gnu", 204 | "windows_x86_64_gnullvm", 205 | "windows_x86_64_msvc", 206 | ] 207 | 208 | [[package]] 209 | name = "windows_aarch64_gnullvm" 210 | version = "0.52.6" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 213 | 214 | [[package]] 215 | name = "windows_aarch64_msvc" 216 | version = "0.52.6" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 219 | 220 | [[package]] 221 | name = "windows_i686_gnu" 222 | version = "0.52.6" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 225 | 226 | [[package]] 227 | name = "windows_i686_gnullvm" 228 | version = "0.52.6" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 231 | 232 | [[package]] 233 | name = "windows_i686_msvc" 234 | version = "0.52.6" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 237 | 238 | [[package]] 239 | name = "windows_x86_64_gnu" 240 | version = "0.52.6" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 243 | 244 | [[package]] 245 | name = "windows_x86_64_gnullvm" 246 | version = "0.52.6" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 249 | 250 | [[package]] 251 | name = "windows_x86_64_msvc" 252 | version = "0.52.6" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 255 | --------------------------------------------------------------------------------