/*
* Copyright (C) 2005 Luca Veltri - University of Parma - Italy
*
* This file is part of MjSip (http://www.mjsip.org)
*
* MjSip is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* MjSip is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MjSip; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author(s):
* Luca Veltri (luca.veltri@unipr.it)
*/
package org.zoolu.tools;
import java.io.*;
import java.util.Vector;
import java.util.Random;
/** Mangle collects some static methods for mangling binary-data structures
*/
public class Mangle
{
/** Compares two arrays of bytes */
public static boolean compare(byte[] a, byte[] b)
{ if (a.length!=b.length) return false;
for (int i=0; i<a.length; i++)
if (a[i]!=b[i]) return false;
return true;
}
/** Initalizes a byte array with value <i>value</i> */
public static byte[] initBytes(byte[] b, int value)
{ for (int i=0; i<b.length; i++) b[i]=(byte)value;
return b;
}
/** Gets the unsigned representatin of a byte (into a short) */
public static short uByte(byte b)
{ return (short)(((short)b+256)%256);
}
/** Gets the unsigned representatin of a 32-bit word (into a long) */
public static long uWord(int n)
{ long wmask=0x10000;
wmask*=wmask;
return (long)(((long)n+wmask)%wmask);
}
/** Rotates w left n bits. */
private static int rotateLeft(int w, int n)
{ return (w << n) | (w >>> (32-n));
}
/** Rotates w right n bits. */
private static int rotateRight(int w, int n)
{ return (w >>> n) | (w << (32-n));
}
/** Rotates an array of int (words), shifting 1 word left. */
private static int[] rotateLeft(int[] w)
{ int len=w.length;
int w1=w[len-1];
for (int i=len-1; i>1; i--) w[i]=w[i-1];
w[0]=w1;
return w;
}
/** Rotates an array of int (words), shifting 1 word right. */
private static int[] rotateRight(int[] w)
{ int len=w.length;
int w0=w[0];
for (int i=1; i<len; i++) w[i-1]=w[i];
w[len-1]=w0;
return w;
}
/** Rotates an array of bytes, shifting 1 byte left. */
private static byte[] rotateLeft(byte[] b)
{ int len=b.length;
byte b1=b[len-1];
for (int i=len-1; i>1; i--) b[i]=b[i-1];
b[0]=b1;
return b;
}
/** Rotates an array of bytes, shifting 1 byte right. */
private static byte[] rotateRight(byte[] b)
{ int len=b.length;
byte b0=b[0];
for (int i=1; i<len; i++) b[i-1]=b[i];
b[len-1]=b0;
return b;
}
/** Returns a copy of an array of bytes <i>b</i> */
public static byte[] clone(byte[] b) { return getBytes(b,0,b.length); }
/** Returns a <i>len</i>-byte array from array <i>b</i> with offset <i>offset</i> */
public static byte[] getBytes(byte[] b, int offset, int len) { byte[] bb=new byte[len]; for (int k=0; k<len; k++) bb[k]=b[offset+k]; return bb; }
/** Returns a 2-byte array from array <i>b</i> with offset <i>offset</i> */
public static byte[] twoBytes(byte[] b, int offset) { return getBytes(b,offset,2); }
/** Returns a 4-byte array from array <i>b</i> with offset <i>offset</i> */
public static byte[] fourBytes(byte[] b, int offset) { return getBytes(b,offset,4); }
/** Copies all bytes of array <i>src</i> into array <i>dst</i> with offset <i>offset</i> */
public static void copyBytes(byte[] src, byte[] dst, int offset) { for (int k=0; k<src.length; k++) dst[offset+k]=src[k]; }
/** Copies the first <i>len</i> bytes of array <i>src</i> into array <i>dst</i> with offset <i>offset</i> */
public static void copyBytes(byte[] src, byte[] dst, int offset, int len) { for (int k=0; k<len; k++) dst[offset+k]=src[k]; }
/** Copies the first 2 bytes of array <i>src</i> into array <i>dst</i> with offset <i>offset</i> */
public static void copyTwoBytes(byte[] src, byte[] dst, int offset) { copyBytes(src,dst,offset,2); }
/** Copies a the first 4 bytes of array <i>src</i> into array <i>dst</i> with offset <i>index</i> */
public static void copyFourBytes(byte[] src, byte[] dst, int offset) { copyBytes(src,dst,offset,4); }
/** Transforms the first <i>len</i> bytes of an array into a string of hex values */
public static String bytesToHexString(byte[] b, int len)
{ String s=new String();
for (int i=0; i<len; i++)
{ s+=Integer.toHexString((((b[i]+256)%256)/16)%16);
s+=Integer.toHexString(((b[i]+256)%256)%16);
}
return s;
}
/** Transforms a byte array into a string of hex values */
public static String bytesToHexString(byte[] b)
{ return bytesToHexString(b,b.length);
}
/** Transforms a string of hex values into an array of bytes of max length <i>len</i>.
* The string may include ':' chars.
* If <i>len</i> is set to -1, all string is converted. */
public static byte[] hexStringToBytes(String str, int len)
{ // if the string is of the form xx:yy:zz:ww.., remove all ':' first
if (str.indexOf(":")>=0)
{ String aux="";
char c;
for (int i=0; i<str.length(); i++) if ((c=str.charAt(i))!=':') aux+=c;
str=aux;
}
// if len=-1, set the len value
if (len<0) len=str.length()/2;
byte[] b=new byte[len];
for (int i=0; i<len; i++)
{ if (len<str.length()/2) b[i]=(byte)Integer.parseInt(str.substring(i*2,i*2+2),16);
else b[i]=0;
}
return b;
}
/** Transforms a string of hex values into an array of bytes.
* The string may include ':' chars. */
public static byte[] hexStringToBytes(String str)
{ return hexStringToBytes(str,-1);
}
/** Transforms a four-bytes array into a dotted four-decimals string */
public static String bytesToAddress(byte[] b)
{ return Integer.toString(uByte(b[0]))+"."+Integer.toString(uByte(b[1]))+"."+Integer.toString(uByte(b[2]))+"."+Integer.toString(uByte(b[3]));
}
/** Transforms a dotted four-decimals string into a four-bytes array */
public static byte[] addressToBytes(String addr)
{ int begin=0, end;
byte[] b=new byte[4];
for (int i=0; i<4; i++)
{ String num;
if (i<3)
{ end=addr.indexOf('.',begin);
b[i]=(byte)Integer.parseInt(addr.substring(begin,end));
begin=end+1;
}
else b[3]=(byte)Integer.parseInt(addr.substring(begin));
}
return b;
}
/** Transforms a 4-bytes array into a 32-bit int */
public static long bytesToInt(byte[] b)
{ return ((((((long)uByte(b[0])<<8)+uByte(b[1]))<<8)+uByte(b[2]))<<8)+uByte(b[3]);
}
/** Transforms a 32-bit int into a 4-bytes array */
public static byte[] intToBytes(long n)
{ byte[] b=new byte[4];
b[0]=(byte)(n>>24);
b[1]=(byte)((n>>16)%256);
b[2]=(byte)((n>>8)%256);
b[3]=(byte)(n%256);
return b;
}
/** Transforms a 4-bytes array into a 32-bit word (with the more significative byte at left) */
public static long bytesToWord(byte[] b, int offset)
{ return ((((((long)uByte(b[offset+3])<<8)+uByte(b[offset+2]))<<8)+uByte(b[offset+1]))<<8)+uByte(b[offset+0]);
}
/** Transforms a 4-bytes array into a 32-bit word (with the more significative byte at left) */
public static long bytesToWord(byte[] b)
{ return ((((((long)uByte(b[3])<<8)+uByte(b[2]))<<8)+uByte(b[1]))<<8)+uByte(b[0]);
}
/** Transforms a 32-bit word (with the more significative byte at left) into a 4-bytes array */
public static byte[] wordToBytes(long n)
{ byte[] b=new byte[4];
b[3]=(byte)(n>>24);
b[2]=(byte)((n>>16)%256);
b[1]=(byte)((n>>8)%256);
b[0]=(byte)(n%256);
return b;
}
private static void print(String str)
{
}
// *************************** MAIN ****************************
private static void decode(byte buffer[], int[] out)
{ int offset=0;
int len=64;
for (int i = 0; offset < len; i++, offset += 4)
{ out[i] = ((int) (buffer[offset] & 0xff)) |
(((int) (buffer[offset + 1] & 0xff)) << 8) |
(((int) (buffer[offset + 2] & 0xff)) << 16) |
(((int) buffer[offset + 3]) << 24);
}
}
public static void main(String[] args)
{
byte[] buff=new byte[64];
for (int i=0; i<64; i++) buff[i]=(byte)i;
int[] x=new int[16];
for (int i=0; i<16; i++) x[i]=(int)bytesToWord(buff,(i*4));
for (int i=0; i<16; i++) print("x["+i+"]: "+bytesToHexString(wordToBytes(x[i])));
decode(buff,x);
for (int i=0; i<16; i++) print("x["+i+"]: "+bytesToHexString(wordToBytes(x[i])));
}
}