1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.castor.core.util;
15
16 import java.io.IOException;
17 import java.io.OutputStream;
18 import java.io.ByteArrayOutputStream;
19
20
21
22
23
24
25
26
27 public final class HexDecoder {
28
29
30
31
32 public static final String DATA_TYPE = "hexBinary";
33
34
35
36
37 private static final int DECODING_TABLE_SIZE = 128;
38
39
40
41
42 protected static final byte[] ENCODING_TABLE = {(byte) '0', (byte) '1', (byte) '2', (byte) '3',
43 (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'A',
44 (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F'};
45
46
47
48
49 protected static final byte[] DECODING_TABLE = new byte[DECODING_TABLE_SIZE];
50
51
52
53
54 protected static void initialiseDecodingTable() {
55 for (int i = 0; i < ENCODING_TABLE.length; i++) {
56 DECODING_TABLE[ENCODING_TABLE[i]] = (byte) i;
57 }
58
59
60 DECODING_TABLE['a'] = DECODING_TABLE['A'];
61 DECODING_TABLE['b'] = DECODING_TABLE['B'];
62 DECODING_TABLE['c'] = DECODING_TABLE['C'];
63 DECODING_TABLE['d'] = DECODING_TABLE['D'];
64 DECODING_TABLE['e'] = DECODING_TABLE['E'];
65 DECODING_TABLE['f'] = DECODING_TABLE['F'];
66 }
67
68 static {
69 initialiseDecodingTable();
70 }
71
72
73
74
75 private HexDecoder() {
76
77 }
78
79
80
81
82
83
84
85
86
87
88
89 public static int encode(final byte[] data, final int off, final int length,
90 final OutputStream out) throws IOException {
91 for (int i = off; i < (off + length); i++) {
92 int v = data[i] & 0xff;
93
94 out.write(ENCODING_TABLE[(v >>> 4)]);
95 out.write(ENCODING_TABLE[v & 0xf]);
96 }
97
98 return length * 2;
99 }
100
101
102
103
104
105
106
107 private static boolean ignore(final char c) {
108 return (c == '\n' || c == '\r' || c == '\t' || c == ' ');
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122 public static int decode(final byte[] data, final int off, final int length,
123 final OutputStream out) throws IOException {
124 byte b1, b2;
125 int outLen = 0;
126
127 int end = off + length;
128
129 while (end > off) {
130 if (!ignore((char) data[end - 1])) {
131 break;
132 }
133
134 end--;
135 }
136
137 int i = off;
138 while (i < end) {
139 while (i < end && ignore((char) data[i])) {
140 i++;
141 }
142
143 b1 = DECODING_TABLE[data[i++]];
144
145 while (i < end && ignore((char) data[i])) {
146 i++;
147 }
148
149 b2 = DECODING_TABLE[data[i++]];
150
151 out.write((b1 << 4) | b2);
152
153 outLen++;
154 }
155
156 return outLen;
157 }
158
159
160
161
162
163
164
165
166
167
168 public static int decode(final String data, final OutputStream out) throws IOException {
169 byte b1, b2;
170 int length = 0;
171
172 int end = data.length();
173
174 while (end > 0) {
175 if (!ignore(data.charAt(end - 1))) {
176 break;
177 }
178
179 end--;
180 }
181
182 int i = 0;
183 while (i < end) {
184 while (i < end && ignore(data.charAt(i))) {
185 i++;
186 }
187
188 b1 = DECODING_TABLE[data.charAt(i++)];
189
190 while (i < end && ignore(data.charAt(i))) {
191 i++;
192 }
193
194 b2 = DECODING_TABLE[data.charAt(i++)];
195
196 out.write((b1 << 4) | b2);
197
198 length++;
199 }
200
201 return length;
202 }
203
204
205
206
207
208
209
210 public static String encode(final byte[] data) {
211 try {
212 final ByteArrayOutputStream out = new ByteArrayOutputStream();
213 encode(data, 0, data.length, out);
214 out.close();
215 return new String(out.toByteArray());
216 } catch (IOException e) {
217 e.printStackTrace();
218 throw new RuntimeException(e.getMessage(), e);
219 }
220 }
221
222
223
224
225
226
227
228 public static byte[] decode(final String data) {
229 try {
230 final ByteArrayOutputStream out = new ByteArrayOutputStream();
231 decode(data, out);
232 out.close();
233 return out.toByteArray();
234 } catch (IOException e) {
235 e.printStackTrace();
236 throw new RuntimeException(e.getMessage(), e);
237 }
238 }
239
240 }