Usage
For multiple bytes per line:C:\> PrintHex.exe -h PrintHex.cs
Sample output:
75 73 69 6E 67 20 53 79 73 74 65 6D 3B 0D 0A 75 using System;__u 73 69 6E 67 20 53 79 73 74 65 6D 2E 49 4F 3B 0D sing System.IO;_ 0A 0D 0A 2F 2A 2A 0D 0A 2A 20 41 70 70 6C 69 63 ___/**__* Applic 61 74 69 6F 6E 20 66 6F 72 20 70 72 69 6E 74 69 ation for printi 6E 67 20 66 69 6C 65 20 74 6F 20 63 6F 6E 73 6F ng file to conso 6C 65 20 61 73 20 68 65 78 61 64 65 63 69 6D 61 le as hexadecima 6C 2E 0D 0A 2A 2F 0D 0A 70 75 62 6C 69 63 20 63 l.__*/__public c
For single byte per line:
C:\> PrintHex.exe -s PrintHex.cs
Sample output:
u 117 75 s 115 73 i 105 69 n 110 6E g 103 67 32 20 S 83 53 y 121 79 s 115 73 t 116 74 e 101 65 m 109 6D ; 59 3B
Listing: PrintHex.cs
using System; using System.IO; /** * Application for printing file to console as hexadecimal. */ public class PrintHex { public static void Main(String[] args) { if(args.Length!=2) { PrintUsage(); return; } IEmitter emitter; if(args[0] == "-h") { emitter = new HexEmitter(); } else if(args[0] == "-s") { emitter = new PerLineEmitter(); } else { PrintUsage(); return; } try { string path = args[1]; if(!File.Exists(path)) { Console.WriteLine("File does not exist: {0}", path); return; } using(FileStream fs = File.OpenRead(path)) { while(true) { int b = fs.ReadByte(); if(b == -1) { break; } emitter.PrintByte(b); } emitter.Flush(); } } catch(Exception e) { Console.WriteLine(e); } } public static void PrintUsage() { Console.WriteLine("usage: PrintHex.exe -<switch> <filename>"); Console.WriteLine(" -h hex dump"); Console.WriteLine(" -s one byte per line"); } } /** * Interface for formatting byte output. */ public interface IEmitter { /**Called for every byte*/ void PrintByte(int b); /**Called after class is finished with*/ void Flush(); } /** * Prints one byte per line as character, decimal and hex value. */ public class PerLineEmitter : IEmitter { public void PrintByte(int b) { char ch = Util.ToSafeAscii(b); Console.WriteLine(ch+"\t"+b+"\t"+Util.ToHexString(b)); } public void Flush() {} } /** * Prints multiple bytes per line followed by characters. */ public class HexEmitter : IEmitter { private const int NBUFF = 16; private int buffered = 0; private int[] bytes = new int[NBUFF]; public void PrintByte(int b) { bytes[buffered] = b; buffered++; if(buffered == NBUFF) { Flush(); } } public void Flush() { if(buffered<=0) { return; } for(int i=0; i<NBUFF; i++) { if(i >= buffered) { Console.Write(" "); } else { string hex = Util.ToHexString(bytes[i]); Console.Write(hex); Console.Write(" "); } } Console.Write(" "); for(int i=0; i<NBUFF; i++) { if(i >= buffered) { Console.Write(" "); } else { char ch = Util.ToSafeAscii(bytes[i]); Console.Write(ch); } } Console.WriteLine(); buffered = 0; } } /** * Utility methods. */ public class Util { /** * Converts a byte to a hexadecimal string value. */ public static string ToHexString(int b) { const int mask1 = 0x0F; const int mask2 = 0xF0; string ret = ""; int c1 = (b & mask1); int c2 = (b & mask2) >> 4; ret = ret + ToHexChar(c2) + ToHexChar(c1); return ret; } /** * Converts the given byte to a hex character. */ private static char ToHexChar(int b) { const int ascii_zero = 48; const int ascii_a = 65; if(b>=0 && b<=9) { return (char) (b + ascii_zero); } if(b>=10 && b<=15) { return (char) (b + ascii_a - 10); } return '?'; } /** * Converts the byte to a visible ASCII character or * underscore if it is not. */ public static char ToSafeAscii(int b) { if(b>=32 && b<=126) { return (char) b; } return '_'; } }
Thanks, I was having the hardest time finding something like this.
ReplyDeleteEasy typo to fix, had to use lowercase 's' in void Main(String[] args) to avoid the "Does not contain a static 'Main' method suitable for an entry point" compiler error for me, at least when using the command-line csc compiler. Works like a charm and is a life saver! At a client site where they don't have internet access, no clipboard copy+paste and transferring files/installers is a red-taped process so it was easiest for me to re-type this by hand and compile it there. Thanks!
ReplyDelete