1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.xbill.DNS.utils;
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.*;
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Routines for converting between Strings of hex-encoded data and arrays of
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * binary data.  This is not actually used by DNS.
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Brian Wellington
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class base16 {
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static final String Base16 = "0123456789ABCDEF";
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenbase16() {}
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Convert binary data to a hex-encoded String
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param b An array containing binary data
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return A String containing the encoded data
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static String
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChentoString(byte [] b) {
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	ByteArrayOutputStream os = new ByteArrayOutputStream();
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	for (int i = 0; i < b.length; i++) {
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		short value = (short) (b[i] & 0xFF);
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		byte high = (byte) (value >> 4);
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		byte low = (byte) (value & 0xF);
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		os.write(Base16.charAt(high));
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		os.write(Base16.charAt(low));
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return new String(os.toByteArray());
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Convert a hex-encoded String to binary data
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param str A String containing the encoded data
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return An array containing the binary data, or null if the string is invalid
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static byte []
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenfromString(String str) {
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	ByteArrayOutputStream bs = new ByteArrayOutputStream();
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	byte [] raw = str.getBytes();
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	for (int i = 0; i < raw.length; i++) {
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if (!Character.isWhitespace((char)raw[i]))
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			bs.write(raw[i]);
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	byte [] in = bs.toByteArray();
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	if (in.length % 2 != 0) {
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		return null;
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	bs.reset();
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	DataOutputStream ds = new DataOutputStream(bs);
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	for (int i = 0; i < in.length; i += 2) {
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		byte high = (byte) Base16.indexOf(Character.toUpperCase((char)in[i]));
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		byte low = (byte) Base16.indexOf(Character.toUpperCase((char)in[i+1]));
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		try {
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			ds.writeByte((high << 4) + low);
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		catch (IOException e) {
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return bs.toByteArray();
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
74