/* ************************************************************************
#
# DivConq
#
# http://divconq.com/
#
# Copyright:
# Copyright 2014 eTimeline, LLC. All rights reserved.
#
# License:
# See the license.txt file in the project's top-level directory for details.
#
# Authors:
# * Andy White
#
************************************************************************ */
package divconq.util;
import divconq.lang.Memory;
public class HexUtil {
/**
* Take a chunk of memory and format as a hex string
* (set the memory position before calling, use 0 if all memory desired)
*
* @param buffer bytes to format
* @return formatted hex string
*/
public static String bufferToHex(Memory buffer) {
if (buffer == null)
return null;
return HexUtil.bufferToHex(buffer, buffer.getLength());
}
/**
* Take a chunk of memory and format as a hex string
* (set the memory position before calling)
*
* @param buffer bytes to format
* @param length how many bytes past start to format
* @return formatted hex string
*/
public static String bufferToHex(Memory buffer, int length) {
if (buffer == null)
return null;
StringBuilder hexString = new StringBuilder(length << 1);
char highNibble;
char lowNibble;
for (int i = 0; i < length; i++) {
int cb = buffer.readByte();
highNibble = HexUtil.HexChars[(cb & 0xF0) >> 4];
lowNibble = HexUtil.HexChars[cb & 0x0F];
hexString.append(highNibble);
hexString.append(lowNibble);
}
return hexString.toString();
}
/**
* Take an array of bytes and format as a hex string
*
* @param buffer bytes to format
* @return formatted hex string
*/
public static String bufferToHex(byte[] buffer) {
if (buffer == null)
return null;
return HexUtil.bufferToHex(buffer, 0, buffer.length);
}
/**
* Take a range of bytes and format as a hex string
*
* @param buffer bytes to format
* @param startOffset position in buffer to start
* @param length how many bytes past start to format
* @return formatted hex string
*/
public static String bufferToHex(byte[] buffer, int startOffset, int length) {
if (buffer == null)
return null;
StringBuilder hexString = new StringBuilder(length << 1);
int endOffset = startOffset + length;
char highNibble;
char lowNibble;
for (int i = startOffset; i < endOffset; i++) {
highNibble = HexUtil.HexChars[(buffer[i] & 0xF0) >> 4];
lowNibble = HexUtil.HexChars[buffer[i] & 0x0F];
hexString.append(highNibble);
hexString.append(lowNibble);
}
return hexString.toString();
}
public static String charToHex(int chr) {
StringBuilder hexString = new StringBuilder(2);
char highNibble;
char lowNibble;
highNibble = HexUtil.HexChars[(chr & 0xF0) >> 4];
lowNibble = HexUtil.HexChars[chr & 0x0F];
hexString.append(highNibble);
hexString.append(lowNibble);
return hexString.toString();
}
public static byte[] decodeHexClean(String data) {
return HexUtil.decodeHex(data.replace(":", "").replace("-", ""));
}
/**
* convert hex characters into corresponding byte array
*
* @param data hex characters
* @return bytes from hex
*/
public static byte[] decodeHex(CharSequence data) {
if (data == null)
return null;
int len = data.length();
if ((len & 0x01) != 0)
return null;
byte[] out = new byte[len >> 1];
// two characters form the hex value.
for (int i = 0, j = 0; j < len; i++) {
int d1 = Character.digit(data.charAt(j++), 16);
int d2 = Character.digit(data.charAt(j++), 16);
if ((d1 == -1) || (d2 == -1))
return null;
int f = (d1 << 4) | d2;
out[i] = (byte) (f & 0xFF);
}
return out;
}
static public void hexDump(byte[] array, int offset, int length) {
int d = 0;
for (int i = 0; i < length; i++) {
System.out.print(HexUtil.charToHex(array[offset + i]) + " ");
d++;
if (d == 32) {
System.out.println();
d = 0;
}
}
}
public static final char HexChars[] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
}