
org.seppiko.commons.utils.codec.HexUtil Maven / Gradle / Ivy
/*
* Copyright 2023 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
*
* 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.seppiko.commons.utils.codec;
import java.io.Serial;
import java.io.Serializable;
import org.seppiko.commons.utils.StringUtil;
/**
* Hexadecimal Encoder / Decoder Util.
*
* @author Leonard Woo
*/
public class HexUtil implements Serializable {
@Serial
private static final long serialVersionUID = -6597436615085466807L;
private HexUtil() {}
/** Hexadecimal length */
public static final int HEXADECIMAL_LENGTH = 16;
/** Hexadecimal character array with lower letters */
public static final char[] HEXADECIMAL = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'
};
/** Hexadecimal character array with upper letters */
public static final char[] HEXADECIMAL_UPPER = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'
};
/** Hexadecimal decode table and ignore case */
public static final byte[] HEXADECIMAL_DECODE_TABLE = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20-2f
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 30-3f 0-9
-1, 10, 11, 12, 13, 14, 15, // 40-46 A-F
-1, -1, -1, -1, -1, -1, -1, -1, -1, // 47-4f
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 50-5f
-1, 10, 11, 12, 13, 14, 15 // 60-66 a-f
};
/**
* convert byte array to string
*
* @param data byte array data.
* @return string.
*/
public static String encodeString(byte[] data) {
return encodeString(data, " ", true);
}
/**
* convert byte array to string with every 2 char with split
*
* @param data byte array data.
* @param split string object split.
* @param toLowerCase true is lower case, false is upper case.
* @return string.
*/
public static String encodeString(byte[] data, String split, boolean toLowerCase) {
return StringUtil.convertToString(new String(encode(data, toLowerCase)), 2, split);
}
/**
* convert byte array to hex char array
*
* @param data byte array data.
* @return hex char array.
*/
public static char[] encode(byte[] data) {
return encode(data, true);
}
/**
* convert byte array to hex char array
*
* @param data byte array data.
* @param toLowerCase true is lowercase, false is uppercase.
* @return hex char array.
*/
public static char[] encode(byte[] data, boolean toLowerCase) {
return encode0(data, toLowerCase? HEXADECIMAL: HEXADECIMAL_UPPER);
}
private static char[] encode0(byte[] data, char[] hexChar) {
char[] hex = new char[data.length * 2];
for (int i = 0, j = 0; i < data.length; i++) {
byte b = data[i];
hex[j++] = hexChar[(0xF0 & b) >> 4];
hex[j++] = hexChar[0x0F & b];
}
return hex;
}
/**
* convert hex string with whitespace split to byte array
*
* @param data hex string.
* @return byte array.
* @throws IllegalArgumentException data include invalid character.
* @throws NullPointerException when data or separator is {@code null}.
*/
public static byte[] decodeString(String data)
throws IllegalArgumentException, NullPointerException {
return decode(data, " ");
}
/**
* convert hex string with split to byte array
*
* @param data hex string.
* @param split split.
* @return byte array.
* @throws IllegalArgumentException data include invalid character.
* @throws NullPointerException when data or separator is {@code null}.
*/
public static byte[] decode(String data, String split)
throws IllegalArgumentException, NullPointerException {
return decode(StringUtil.convertToCharArray(data, split));
}
/**
* convert hex char array to byte array
*
* @param data hex char array.
* @return byte array.
* @throws IllegalArgumentException data include invalid character.
* @throws NullPointerException data is null or empty.
*/
public static byte[] decode(char[] data) throws IllegalArgumentException, NullPointerException {
if (null == data || data.length == 0) {
throw new NullPointerException();
}
return decode0(data);
}
private static byte[] decode0(char[] data) {
byte[] hex = new byte[data.length / 2];
for (int i = 0, j = 0; i < hex.length; i++, j = j + 2) {
int f = toDigit(data[j]) << 4;
f |= toDigit(data[j + 1]);
hex[i] = (byte) (f & 0xFF);
}
return hex;
}
/**
* Return the numeric value of the hexadecimal character.
*
* @param hexChar the character to be converted.
* @return the numeric value represented by the hexadecimal character.
* @throws IllegalArgumentException the numeric is not hexadecimal character.
*/
private static int toDigit(char hexChar) throws IllegalArgumentException {
int digit = HEXADECIMAL_DECODE_TABLE[hexChar];
if (digit < 0) {
throw new IllegalArgumentException("Invalid Hexadecimal Character: " + hexChar);
}
return digit;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy