View Javadoc
1   package emissary.util;
2   
3   import org.apache.commons.codec.binary.Hex;
4   import org.apache.commons.io.IOUtils;
5   
6   import java.io.DataInputStream;
7   import java.io.IOException;
8   import java.io.InputStream;
9   import java.nio.file.Files;
10  import java.nio.file.Paths;
11  
12  /**
13   * Pretend to be Emacs hexl mode
14   */
15  public class Hexl {
16  
17      static final int CHARS_PER_LINE = 16;
18      static final int COUNTER_SIZE = 4;
19      static final String printable = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+|~-=\\`{}[]:;<>?,./'\"";
20  
21      /**
22       * Unformatted hex string
23       */
24      public static String toUnformattedHexString(byte[] data) {
25          return Hex.encodeHexString(data);
26      }
27  
28  
29      /**
30       * Print out the whole byte array as hex
31       */
32      public static String toHexString(byte[] data) {
33          return toHexString(data, data.length);
34      }
35  
36      /**
37       * Print out a portion of the data as a hexdump for debugging
38       * 
39       * @param limit how many bytes of data to print starting from 0
40       */
41      @SuppressWarnings("PMD.UselessParentheses")
42      public static String toHexString(byte[] data, int limit) {
43  
44          StringBuilder output = new StringBuilder(2048);
45  
46          int stop = data.length;
47  
48          if (limit < stop) {
49              stop = limit;
50          }
51  
52          int lineCount = 0;
53  
54          byte[] rhs = new byte[CHARS_PER_LINE];
55  
56          int j = 0;
57  
58          for (int i = 0; i < stop; i++, j++) {
59  
60  
61              // end a line
62              if (j >= CHARS_PER_LINE) {
63                  output.append("  ").append(new String(rhs));
64                  output.append(System.getProperty("line.separator", "\n"));
65                  j = 0;
66                  lineCount++;
67              }
68  
69              // start a new line
70              if (j == 0) {
71                  String s = Integer.toHexString(lineCount);
72                  int pad = COUNTER_SIZE - s.length();
73                  while (pad-- > 0) {
74                      output.append("0");
75                  }
76                  output.append(s);
77                  output.append(": ");
78              }
79  
80              String s = Integer.toHexString(data[i] & 0xff);
81              if (s.length() < 2) {
82                  output.append("0").append(s);
83              } else {
84                  output.append(s);
85              }
86  
87              // Group hex entries
88              if (j % 2 != 0) {
89                  output.append(" ");
90              }
91  
92              // Build the rhs
93              if (printable.indexOf(data[i]) > -1) {
94                  rhs[j] = data[i];
95              } else {
96                  rhs[j] = (byte) '.';
97              }
98          }
99  
100         int pad = ((CHARS_PER_LINE * 2) + (CHARS_PER_LINE / 2) + 1) - ((j * 2) + (j / 2) - 1);
101         while (pad-- > 0) {
102             output.append(" ");
103         }
104         while (j < CHARS_PER_LINE) {
105             rhs[j++] = (byte) ' ';
106         }
107         output.append(new String(rhs));
108 
109         return output.toString();
110     }
111 
112     /** This class is not meant to be instantiated. */
113     private Hexl() {}
114 
115     @SuppressWarnings("SystemOut")
116     public static void main(String[] argv) {
117 
118         if (argv.length < 1) {
119             System.err.println("usage: java emissary.util.Hexl datafile1 datafile2 ...");
120             return;
121         }
122 
123         byte[] theContent;
124 
125         for (int i = 0; i < argv.length; i++) {
126 
127             try (InputStream theFile = Files.newInputStream(Paths.get(argv[i]));
128                     DataInputStream theStream = new DataInputStream(theFile)) {
129                 theContent = IOUtils.toByteArray(theStream);
130             } catch (IOException e) {
131                 System.err.println("Error reading from " + argv[i]);
132                 continue;
133             }
134 
135             System.out.println("File " + argv[i]);
136             System.out.println(toHexString(theContent));
137         }
138     }
139 }