/** * This software is GPLv2. * Take a look at the LICENSE file for more info. */ package de.tu.dresden.dud.dc; /** * In this class you'll find a lot of useful stuff, that Java does not offer by * itself. I.e. comfortably concatenate arrays, convert hex to string or vice * versa, etc. * * @author klobs * */ public class Util { /** * Concatenate two byte arrays * @param a * @param b * @return concatenation of a and b */ public static byte[] concatenate(byte[] a, byte[] b){ // source http://forums.sun.com/thread.jspa?threadID=571260&messageID=2827711 byte c[] = new byte[a.length + b.length]; System.arraycopy(a, 0, c, 0, a.length); System.arraycopy(b, 0, c, a.length, b.length); return c; } /** * Convert a byte array to a hex string. * * @param a * the byte array that you want to represent as hex string * @return a hex string representation of the byte array a */ public static String convertToHex(byte [] a){ String hexStr = ""; for (int i = 0; i < a.length; i++) { hexStr += Integer.toString( ( a[i] & 0xff ) + 0x100, 16).substring( 1 ); } return hexStr; } /** * Take a hex string, and convert it to the corresponding byte array. There * is no checking whether the string, that you pass is actually a hex-value, * so please don't mess with this method. * * @param a the string that you want have to be converted. * @return the corresponding byte []. */ public static byte[] convertFromHex(String a){ int len = a.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(a.charAt(i), 16) << 4) + Character.digit(a.charAt(i+1), 16)); } return data; } /** * Merge two unequally sized byte arrays (by xoring each element). The * shorter one will be padded up to the length of the longer one with 0s. * * @param a * @param b * @return */ public static byte[] fillAndMergeSending(byte[] a, byte[] b) { if (a == null | b == null) throw new IllegalArgumentException("The arrays a, b are null."); int i; byte[] shorterone = null; byte[] longerone = null; if (a.length <= b.length) { shorterone = a; longerone = b; } else { shorterone = b; longerone = a; } byte[] c = new byte[longerone.length]; for (i = 0; i < shorterone.length; i++) { c[i] = (byte) (a[i] ^ b[i]); } while (i < longerone.length) { c[i] = longerone[i]; i++; } return c; } /** * Returns the first n bytes of array a * @param a The array that contains the info * @param n indicating how many bytes you want to have cut of the head. * @return the first n bytes of a. If n > a.length or !(n>0) it returns a new byte[0] array. */ public static byte[] getFirstBytes(byte[] a, int n){ if( n > a.length || !(n > 0)) return new byte[0]; byte[] b = new byte[n]; for( int i = 0; i < n; i++){ b[i] = a[i]; } return b; } /** * Take byte[] a and return n bytes out of it, starting by offset o. * @param a The byte[] with the content. * @param o The offset. * @param n The desired number of bytes. * @return The information, or - if you provide bogus values for a,o, or n a new byte[0]. */ public static byte[] getBytesByOffset(byte[] a, int o, int n){ if ( a == null ) return new byte[0]; if ( a.length - o < n && o >= 0 && n > 0 ) return new byte[0]; byte[] b = new byte[n]; for(int i = o; i < o + n; i++ ){ b[i - o] = a[i]; } return b; } public static byte[] getLastBytes(byte[] a, int n) { if (n == a.length) return a; if (n > a.length || !(n > 0)) return new byte[0]; byte[] b = new byte[n]; for (int i = 1; i <= n; i++) { b[n - i] = a[a.length - i]; } return b; } /** * Merge two equally sized byte arrays (by xoring each element). * * @param a * @param b * @return */ public static byte[] mergeDCwise(byte[] a, byte[] b, final long modulus) { if (a == null | b == null | a.length != b.length) throw new IllegalArgumentException( "The arrays a, b are null or do not have the same length."); byte[] c = new byte[a.length]; for (int i = 0; i< a.length; i = i+4){ long ka = Util.stuffBytesIntoLongUnsigned(Util.getBytesByOffset(a,i, 4)) % modulus; long kb = Util.stuffBytesIntoLongUnsigned(Util.getBytesByOffset(b,i, 4)) % modulus; long d = (ka + kb) % modulus; c[i] = (byte) (d >>> 24); c[i+1] = (byte) (d >>> 16); c[i+2] = (byte) (d >>> 8 ); c[i+3] = (byte) d; } return c; } /** * Put a byte array into an integer. Interpret the byte array as unsigned. * Ugly work has to be done. * Length checking will be done. * @throws IllegalArgumentException when b is too long * @param b the byte array that you would like to have converted * @return the corresponding int. */ public static int stuffBytesIntoUInt(byte[] b){ int r = 0; if (!(b.length <= 4 && b.length > 0)) throw new IllegalArgumentException("The value you provided can not be stuffed into an int."); for (int i=0; i < b.length; i++){ r = r | ((b[b.length - 1 - i] & 0x000000FF) << 8 *i); } return r; } /** * Put a byte array into a long. * Same ugly stuff as the int version. * Length checking will be done. * @throws IllegalArgumentException when b is too long * @param b the byte array that you would like to have converted * @return the corresponding long. */ public static long stuffBytesIntoLong(byte[] b){ long r = 0; if (!(b.length <= 8 && b.length > 0)) throw new IllegalArgumentException("The value you provided can not be stuffed into an long."); for (int i=0; i < b.length; i++){ r = r | ((b[b.length - 1 - i])<< 8 *i); } return r; } /** * Put a byte array into a long. * Same ugly stuff as the int version. * Length checking will be done. * <b>*WARNING*</b>Signs will be removed in each byte * @throws IllegalArgumentException when b is too long * @param b the byte array that you would like to have converted * @return the corresponding long. */ public static long stuffBytesIntoLongUnsigned(byte[] b){ long r = 0; if (!(b.length <= 8 && b.length > 0)) throw new IllegalArgumentException("The value you provided can not be stuffed into an long."); for (int i=0; i < b.length; i++){ r = r | (((b[b.length - 1 - i]) & 0x00000000000000FFL)<< 8 *i); } return r; } /** * Take an integer and return it as byte[1]. * * @param i * the integer that you want to convert. * @return the byte[1] representation of i. If i is beyond max/min values * for a byte, an {@link IllegalArgumentException} is thrown. */ public static byte[] stuffIntIntoByte(int i){ if(i > Byte.MAX_VALUE || i < Byte.MIN_VALUE) throw new IllegalArgumentException("The value you provided can not be stuffed into a byte."); byte []b = new byte[1]; b[0] = (byte) i; return b; } /** * Take an integer and return it as byte[4]. * * @param i * the integer that you want to convert. * @return the byte[4] representation of i. If i is beyond max/min values * for an integer, an {@link IllegalArgumentException} is thrown. */ public static byte[] stuffIntIntoInt(int i){ byte []b = new byte[4]; b[3] = (byte) i; b[2] = (byte) (i >>> 8); b[1] = (byte) (i >>> 16); b[0] = (byte) (i >>> 24); return b; } /** * Take an integer and return it as byte[2]. * * @param i * the integer that you want to convert. * @return the byte[2] representation of i. If i is beyond max/min values * for a short, an {@link IllegalArgumentException} is thrown. */ public static byte[] stuffIntIntoShort(int i){ if(i > Short.MAX_VALUE || i < Short.MIN_VALUE) throw new IllegalArgumentException("The value you provided can not be stuffed into a short."); byte []b = new byte[2]; b[1] = (byte) i; b[0] = (byte) (i >>> 8); return b; } /** * Take an integer and return it as byte[8]. * * @param l * the integer that you want to convert. * @return the byte[8] representation of l. If l is beyond max/min values * for a long, an {@link IllegalArgumentException} is thrown. */ public static byte[] stuffLongIntoLong(long l){ byte []b = new byte[8]; b[7] = (byte) l; b[6] = (byte) (l >>> 8); b[5] = (byte) (l >>> 16); b[4] = (byte) (l >>> 24); b[3] = (byte) (l >>> 32); b[2] = (byte) (l >>> 40); b[1] = (byte) (l >>> 48); b[0] = (byte) (l >>> 56); return b; } /** * Take a string and return it as byte[]. * * Actually only a wrapper for getBytes() of the {@link String} class. * * @param s * the string that you want to convert. * @return the byte[] representation of s. */ public static byte[] stuffStringIntoCharArray(String s){ return s.getBytes(); } }