1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.common.util;
17
18 import java.io.UnsupportedEncodingException;
19
20 import org.apache.commons.lang3.CharSet;
21 import org.apache.commons.lang3.StringUtils;
22
23
24
25
26 public class HexUtils {
27
28 private static final String ZERO = "0";
29 private static final int BYTE_MASK = 0x000000ff;
30 private static final String[] HEX_RANGES = new String[] { "0-9", "A-F", "a-f" };
31 private static final String HEX_RANGES_STRING = toString(HEX_RANGES);
32 private static final CharSet HEX_CHARSET = CharSet.getInstance(HEX_RANGES);
33
34 public static final CharSet getHexCharSet() {
35 return HEX_CHARSET;
36 }
37
38 public static final String[] getHexRanges() {
39 return HEX_RANGES;
40 }
41
42 protected static final String toString(String[] tokens) {
43 StringBuilder sb = new StringBuilder();
44 sb.append("[");
45 for (int i = 0; i < HEX_RANGES.length; i++) {
46 if (i != 0) {
47 sb.append(",");
48 }
49 sb.append(HEX_RANGES[i]);
50 }
51 sb.append("]");
52 return sb.toString();
53 }
54
55
56
57
58
59 public static String toHexString(String string, String encoding) throws UnsupportedEncodingException {
60 byte[] bytes = encoding == null ? string.getBytes() : string.getBytes(encoding);
61 return toHexString(bytes);
62 }
63
64
65
66
67 public static String toHexString(byte[] bytes) {
68 StringBuilder sb = new StringBuilder();
69 for (byte b : bytes) {
70 int masked = BYTE_MASK & b;
71 String hex = Integer.toHexString(masked).toUpperCase();
72 String padded = StringUtils.leftPad(hex, 2, ZERO);
73 sb.append(padded);
74 }
75 return sb.toString();
76 }
77
78
79
80
81 public static final boolean isHex(char... chars) {
82 for (char c : chars) {
83 if (!HEX_CHARSET.contains(c)) {
84 return false;
85 }
86 }
87 return true;
88 }
89
90
91
92
93
94
95
96 public static final byte[] getBytesFromHexString(String hex) {
97 char[] chars = hex.toCharArray();
98 int length = chars.length;
99 if (length % 2 != 0) {
100 throw new IllegalArgumentException("Invalid hex string [" + hex + "]. String must contain an even number of characters. " + length + " is not an even number!");
101 }
102 byte[] bytes = new byte[length / 2];
103 int byteIndex = 0;
104 for (int i = 0; i < length; i += 2) {
105 char c1 = chars[i];
106 char c2 = chars[i + 1];
107 String s = c1 + "" + c2;
108 if (!isHex(c1, c2)) {
109 int byteNumber = i / 2 + 1;
110 throw new IllegalArgumentException("Invalid hex string [" + hex + "]. Invalid hex detected at byte " + byteNumber + " [" + s
111 + "]. Both characters must be in the range " + HEX_RANGES_STRING);
112 }
113 int integer = Integer.parseInt(s, 16);
114 int masked = integer & BYTE_MASK;
115 byte b = (byte) masked;
116 bytes[byteIndex++] = b;
117 }
118 return bytes;
119 }
120
121
122
123
124
125
126
127 public static final String toStringFromHex(String hex, String encoding) throws UnsupportedEncodingException {
128 byte[] bytes = getBytesFromHexString(hex);
129 return StringUtils.toString(bytes, encoding);
130 }
131
132 }