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 }