Java十六进制编辑器的实现

所谓的十六进制编辑器,就是把用十六进制的方式打开一个文件,其中读进来的每个字节被做为两个十六进制数看待,例如:

 

读入字节: 01101010; 分解成前后两个16进制数,每四个一组,就成了: 0110 1010 --> 6 A。

 

所以首先我们需要把文件做为字节流读入:

 

 

File file = new File(filePath);
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
byte[] a = new byte[1024];
int count = -1;
StringBuilder sb = new StringBuilder();
while ((count = in.read(a)) != -1) {
	//TODO
}
in.close();

 

以上每次读入一个字节块,并存入数组a中。下面要做的就是把读入的每个字节都分解成两个16进制数,因此我们仅仅需要关心字节的最后8位,并分别提取出前四位和后四位,最后组合成一个16进制数即可。

 

提取和组合的方法相当简单,如下:

 

	private static void convertByte2Hex(byte b, StringBuilder sb) {
		int number = b & 0x00ff;
		if(number<16){
			sb.append(0);
		}
		sb.append(Integer.toHexString(number));
	}
 

有了这个方法,上面代码的//TODO部分就可以完成了:

 

for (int i = 0; i < count; i++) {
				convertByte2Hex(a[i], sb);
}
 

这样,一个文件的16进制表示就完成。例如:

 

package test;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("HelloWorld!");

	}

}

 以上类编译后生成的class文件的16进制表示为:

 

CA FE BA BE 00 00 00 31  00 22 07 00 02 01 00 09  

74 65 73 74 2F 54 65 73  74 07 00 04 01 00 10 6A  

61 76 61 2F 6C 61 6E 67  2F 4F 62 6A 65 63 74 01  

00 06 3C 69 6E 69 74 3E  01 00 03 28 29 56 01 00  

04 43 6F 64 65 0A 00 03  00 09 0C 00 05 00 06 01  

00 0F 4C 69 6E 65 4E 75  6D 62 65 72 54 61 62 6C  

65 01 00 12 4C 6F 63 61  6C 56 61 72 69 61 62 6C  

65 54 61 62 6C 65 01 00  04 74 68 69 73 01 00 0B  

4C 74 65 73 74 2F 54 65  73 74 3B 01 00 04 6D 61  

69 6E 01 00 16 28 5B 4C  6A 61 76 61 2F 6C 61 6E  

67 2F 53 74 72 69 6E 67  3B 29 56 09 00 11 00 13  

07 00 12 01 00 10 6A 61  76 61 2F 6C 61 6E 67 2F  

53 79 73 74 65 6D 0C 00  14 00 15 01 00 03 6F 75  

74 01 00 15 4C 6A 61 76  61 2F 69 6F 2F 50 72 69  

6E 74 53 74 72 65 61 6D  3B 08 00 17 01 00 0B 48  

65 6C 6C 6F 57 6F 72 6C  64 21 0A 00 19 00 1B 07  

00 1A 01 00 13 6A 61 76  61 2F 69 6F 2F 50 72 69  

6E 74 53 74 72 65 61 6D  0C 00 1C 00 1D 01 00 07  

70 72 69 6E 74 6C 6E 01  00 15 28 4C 6A 61 76 61  

2F 6C 61 6E 67 2F 53 74  72 69 6E 67 3B 29 56 01  

00 04 61 72 67 73 01 00  13 5B 4C 6A 61 76 61 2F  

6C 61 6E 67 2F 53 74 72  69 6E 67 3B 01 00 0A 53  

6F 75 72 63 65 46 69 6C  65 01 00 09 54 65 73 74  

2E 6A 61 76 61 00 21 00  01 00 03 00 00 00 00 00  

02 00 01 00 05 00 06 00  01 00 07 00 00 00 2F 00  

01 00 01 00 00 00 05 2A  B7 00 08 B1 00 00 00 02  

00 0A 00 00 00 06 00 01  00 00 00 03 00 0B 00 00  

00 0C 00 01 00 00 00 05  00 0C 00 0D 00 00 00 09  

00 0E 00 0F 00 01 00 07  00 00 00 37 00 02 00 01  

00 00 00 09 B2 00 10 12  16 B6 00 18 B1 00 00 00  

02 00 0A 00 00 00 0A 00  02 00 00 00 09 00 08 00  

0B 00 0B 00 00 00 0C 00  01 00 00 00 09 00 1E 00  

1F 00 00 00 01 00 20 00  00 00 02 00 21 

 

多试几个class,就可以发现其实开头的8个字节都是一样的,这个是描述类文件的版本的。

 

如果有了16进制表示,要还原来内容,用ASCII码来表示内容。我们就需要再还原出每个字节,然后把字节对应的转换成对应的字符。

 

假如我们有一串已经是16进制表示的字符串。根据上面的原则,每两上16进制为一组表示一个字节的内容:

 

 

	public static String convertHex2ASCII(String hexString) {
		int length = hexString.length();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < length - 1; i += 2) {
			String s = hexString.charAt(i) + "" + hexString.charAt(i + 1);
			int parseInt = Integer.parseInt(s, 16);
			if (parseInt < 32 && parseInt != 10) {
				sb.append(" ");
			} else {
				sb.append((char) parseInt);
			}
		}
		return sb.toString();
	}

 因为在ASCII码表中,32以下的字符都是一些不可表示字符,所以用空格代替了。

你可能感兴趣的:(Java相关)