org.kuali.common.util.HexUtils Maven / Gradle / Ivy
/**
* Copyright 2010-2012 The Kuali Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ecl2.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kuali.common.util;
import java.io.UnsupportedEncodingException;
import org.apache.commons.lang3.CharSet;
import org.apache.commons.lang3.StringUtils;
/**
* A few (highly inefficient) methods that, when given an encoding, can convert Java String's
into the hex for that encoding
* and also convert the hex back into the original string.
*/
public class HexUtils {
private static final String ZERO = "0";
private static final int BYTE_MASK = 0x000000ff;
private static final String[] HEX_RANGES = new String[] { "0-9", "A-F", "a-f" };
private static final String HEX_RANGES_STRING = toString(HEX_RANGES);
private static final CharSet HEX_CHARSET = CharSet.getInstance(HEX_RANGES);
public static final CharSet getHexCharSet() {
return HEX_CHARSET;
}
public static final String[] getHexRanges() {
return HEX_RANGES;
}
protected static final String toString(String[] tokens) {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < HEX_RANGES.length; i++) {
if (i != 0) {
sb.append(",");
}
sb.append(HEX_RANGES[i]);
}
sb.append("]");
return sb.toString();
}
/**
* Convert string
into a byte[]
using the specified encoding, then convert each byte
into its 2
* digit hexadecimal form.
*/
public static String toHexString(String string, String encoding) throws UnsupportedEncodingException {
byte[] bytes = encoding == null ? string.getBytes() : string.getBytes(encoding);
return toHexString(bytes);
}
/**
* Convert each byte
into its 2 digit hexadecimal form.
*/
public static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
int masked = BYTE_MASK & b;
String hex = Integer.toHexString(masked).toUpperCase();
String padded = StringUtils.leftPad(hex, 2, ZERO);
sb.append(padded);
}
return sb.toString();
}
/**
* Return true if every character is valid hex 0-9
, a-f
, or A-F
*/
public static final boolean isHex(char... chars) {
for (char c : chars) {
if (!HEX_CHARSET.contains(c)) {
return false;
}
}
return true;
}
/**
* Given a string in strictly hex
format, return the corresponding byte[]
. strictly hex
in the
* context of this method means that the string:
* 1 - Contains only the characters a-f
, A-F
, and 0-9
* 2 - Its length is an even number.
*/
public static final byte[] getBytesFromHexString(String hex) {
char[] chars = hex.toCharArray();
int length = chars.length;
if (length % 2 != 0) {
throw new IllegalArgumentException("Invalid hex string [" + hex + "]. String must contain an even number of characters. " + length + " is not an even number!");
}
byte[] bytes = new byte[length / 2];
int byteIndex = 0;
for (int i = 0; i < length; i += 2) {
char c1 = chars[i];
char c2 = chars[i + 1];
String s = c1 + "" + c2;
if (!isHex(c1, c2)) {
int byteNumber = i / 2 + 1;
throw new IllegalArgumentException("Invalid hex string [" + hex + "]. Invalid hex detected at byte " + byteNumber + " [" + s
+ "]. Both characters must be in the range " + HEX_RANGES_STRING);
}
int integer = Integer.parseInt(s, 16);
int masked = integer & BYTE_MASK;
byte b = (byte) masked;
bytes[byteIndex++] = b;
}
return bytes;
}
/**
* Given a string in strictly hex
format and the encoding
that was used to produce the hex, convert it back to
* a Java String
. strictly hex
in the context of this method means that the string:
* 1 - Contains only the characters a-f
, A-F
, and 0-9
* 2 - Its length is an even number.
*/
public static final String toStringFromHex(String hex, String encoding) throws UnsupportedEncodingException {
byte[] bytes = getBytesFromHexString(hex);
return StringUtils.toString(bytes, encoding);
}
}