/**
* collection of utility routines for converting and displaying binary
* saved in byte/short/int arrays, and loaded/displayed using hex.
*
* @author Lawrie Brown, Oct 2001
*/
package uk.ac.cam.db538.crypto;
class Util {
//......................................................................
// utility conversions between byte, short and int arrays
public static byte[] short2byte (short[] sa) {
int length = sa.length;
byte[] ba = new byte[length * 2];
for (int i = 0, j = 0, k; i < length; ) {
k = sa[i++];
ba[j++] = (byte)((k >>> 8) & 0xFF);
ba[j++] = (byte)( k & 0xFF);
}
return (ba);
}
//......................................................................
public static short[] byte2short (byte[] ba) {
int length = ba.length;
short[] sa = new short[length / 2];
for (int i = 0, j = 0; j < length / 2; ) {
sa[j++] = (short)(((ba[i++] & 0xFF) << 8) |
((ba[i++] & 0xFF) ));
}
return (sa);
}
//......................................................................
public static byte[] int2byte (int[] ia) {
int length = ia.length;
byte[] ba = new byte[length * 4];
for (int i = 0, j = 0, k; i < length; ) {
k = ia[i++];
ba[j++] = (byte)((k >>>24) & 0xFF);
ba[j++] = (byte)((k >>>16) & 0xFF);
ba[j++] = (byte)((k >>> 8) & 0xFF);
ba[j++] = (byte)( k & 0xFF);
}
return (ba);
}
//......................................................................
public static int[] byte2int (byte[] ba) {
int length = ba.length;
int[] ia = new int[length / 4];
for (int i = 0, j = 0; j < length / 4; ) {
ia[j++] = (((ba[i++] & 0xFF) << 24) |
((ba[i++] & 0xFF) << 16) |
((ba[i++] & 0xFF) << 8) |
((ba[i++] & 0xFF) ));
}
return (ia);
}
//......................................................................
// utility methods (adapted from cryptix.util.core.Hex class)
/** array mapping hex value (0-15) to corresponding hex digit (0-9a-f). */
public static final char[] HEX_DIGITS = {
'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
};
/**
* utility method to convert a byte array to a hexadecimal string.
* <p>
* Each byte of the input array is converted to 2 hex symbols,
* using the HEX_DIGITS array for the mapping, with spaces after each pair.
* @param ba array of bytes to be converted into hex
* @return hex representation of byte array
*/
public static String toHEX (byte[] ba) {
int length = ba.length;
char[] buf = new char[length * 3];
for (int i = 0, j = 0, k; i < length; ) {
k = ba[i++];
buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
buf[j++] = HEX_DIGITS[ k & 0x0F];
buf[j++] = ' ';
}
return new String(buf);
}
/**
* utility method to convert a short array to a hexadecimal string.
* <p>
* Each word of the input array is converted to 4 hex symbols,
* using the HEX_DIGITS array for the mapping, with spaces after every 4.
* @param ia array of shorts to be converted into hex
* @return hex representation of short array
*/
public static String toHEX (short[] ia) {
int length = ia.length;
char[] buf = new char[length * 5];
for (int i = 0, j = 0, k; i < length; ) {
k = ia[i++];
buf[j++] = HEX_DIGITS[(k >>>12) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>> 8) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
buf[j++] = HEX_DIGITS[ k & 0x0F];
buf[j++] = ' ';
}
return new String(buf);
}
/**
* utility method to convert an int array to a hexadecimal string.
* <p>
* Each word of the input array is converted to 8 hex symbols,
* using the HEX_DIGITS array for the mapping, with spaces after every 4.
* @param ia array of ints to be converted into hex
* @return hex representation of int array
*/
public static String toHEX (int[] ia) {
int length = ia.length;
char[] buf = new char[length * 10];
for (int i = 0, j = 0, k; i < length; ) {
k = ia[i++];
buf[j++] = HEX_DIGITS[(k >>>28) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>>24) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>>20) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>>16) & 0x0F];
buf[j++] = ' ';
buf[j++] = HEX_DIGITS[(k >>>12) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>> 8) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
buf[j++] = HEX_DIGITS[ k & 0x0F];
buf[j++] = ' ';
}
return new String(buf);
}
/**
* utility method to convert a byte to a hexadecimal string.
* <p>
* the byte is converted to 2 hex symbols,
* using the HEX_DIGITS array for the mapping.
* @param b byte to be converted into hex
* @return hex representation of byte
*/
public static String toHEX1 (byte b) {
char[] buf = new char[2];
int j = 0;
buf[j++] = HEX_DIGITS[(b >>> 4) & 0x0F];
buf[j++] = HEX_DIGITS[ b & 0x0F];
return new String(buf);
}
/**
* utility method to convert a byte array to a hexadecimal string.
* <p>
* Each byte of the input array is converted to 2 hex symbols,
* using the HEX_DIGITS array for the mapping.
* @param ba array of bytes to be converted into hex
* @return hex representation of byte array
*/
public static String toHEX1 (byte[] ba) {
int length = ba.length;
char[] buf = new char[length * 2];
for (int i = 0, j = 0, k; i < length; ) {
k = ba[i++];
buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
buf[j++] = HEX_DIGITS[ k & 0x0F];
}
return new String(buf);
}
/**
* utility method to convert a short array to a hexadecimal string.
* <p>
* Each word of the input array is converted to 4 hex symbols,
* using the HEX_DIGITS array for the mapping.
* @param ia array of shorts to be converted into hex
* @return hex representation of short array
*/
public static String toHEX1 (short[] ia) {
int length = ia.length;
char[] buf = new char[length * 4];
for (int i = 0, j = 0, k; i < length; ) {
k = ia[i++];
buf[j++] = HEX_DIGITS[(k >>>12) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>> 8) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
buf[j++] = HEX_DIGITS[ k & 0x0F];
}
return new String(buf);
}
/**
* utility method to convert an int to a hexadecimal string.
* <p>
* the int is converted to 8 hex symbols,
* using the HEX_DIGITS array for the mapping.
* @param i int to be converted into hex
* @return hex representation of int
*/
public static String toHEX1 (int i) {
char[] buf = new char[8];
int j = 0;
buf[j++] = HEX_DIGITS[(i >>>28) & 0x0F];
buf[j++] = HEX_DIGITS[(i >>>24) & 0x0F];
buf[j++] = HEX_DIGITS[(i >>>20) & 0x0F];
buf[j++] = HEX_DIGITS[(i >>>16) & 0x0F];
buf[j++] = HEX_DIGITS[(i >>>12) & 0x0F];
buf[j++] = HEX_DIGITS[(i >>> 8) & 0x0F];
buf[j++] = HEX_DIGITS[(i >>> 4) & 0x0F];
buf[j++] = HEX_DIGITS[ i & 0x0F];
return new String(buf);
}
/**
* utility method to convert an int array to a hexadecimal string.
* <p>
* Each word of the input array is converted to 8 hex symbols,
* using the HEX_DIGITS array for the mapping.
* @param ia array of ints to be converted into hex
* @return hex representation of int array
*/
public static String toHEX1 (int[] ia) {
int length = ia.length;
char[] buf = new char[length * 8];
for (int i = 0, j = 0, k; i < length; ) {
k = ia[i++];
buf[j++] = HEX_DIGITS[(k >>>28) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>>24) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>>20) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>>16) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>>12) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>> 8) & 0x0F];
buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
buf[j++] = HEX_DIGITS[ k & 0x0F];
}
return new String(buf);
}
//......................................................................
/**
* Returns a byte array from a string of hexadecimal digits.
*
* @param hex string of hex characters
* @return byte array of binary data corresponding to hex string input
*/
public static byte[] hex2byte(String hex) {
int len = hex.length();
byte[] buf = new byte[((len + 1) / 2)];
int i = 0, j = 0;
if ((len % 2) == 1)
buf[j++] = (byte) hexDigit(hex.charAt(i++));
while (i < len) {
buf[j++] = (byte) ((hexDigit(hex.charAt(i++)) << 4) |
hexDigit(hex.charAt(i++)));
}
return buf;
}
//......................................................................
/**
* Returns true if the string consists ONLY of valid hex characters
*
* @param hex string of hex characters
* @return true if a valid hex string
*/
public static boolean isHex(String hex) {
int len = hex.length();
int i = 0;
char ch;
while (i < len) {
ch = hex.charAt(i++);
if (! ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') ||
(ch >= 'a' && ch <= 'f'))) return false;
}
return true;
}
//......................................................................
/**
* Returns the number from 0 to 15 corresponding to the hex digit <i>ch</i>.
*
* @param ch hex digit character (must be 0-9A-Fa-f)
* @return numeric equivalent of hex digit (0-15)
*/
public static int hexDigit(char ch) {
if (ch >= '0' && ch <= '9')
return ch - '0';
if (ch >= 'A' && ch <= 'F')
return ch - 'A' + 10;
if (ch >= 'a' && ch <= 'f')
return ch - 'a' + 10;
return(0); // any other char is treated as 0
}
}