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