Author | Message | Time |
---|---|---|
iago | One annoying part of converting c to Java is when the C programmer uses a byte pointer into an int array or an int pointer into a byte array. This happens, for instance, in SHA1. Here is a workaround i wrote for both ways: [code]/* * ByteFromIntArray.java * * Created on May 21, 2004, 11:39 AM */ package bot.util; /** This is a class to take care of treating an array of ints like a an array of bytes. * Note that this always works in Little Endian * * @author Ron - Home */ public class ByteFromIntArray { private boolean littleEndian; public static final ByteFromIntArray LITTLEENDIAN = new ByteFromIntArray(true); public static final ByteFromIntArray BIGENDIAN = new ByteFromIntArray(false); /** * @param args the command line arguments */ public static void main(String[] args) { int []test = { 0x01234567, 0x89abcdef }; ByteFromIntArray bfia = new ByteFromIntArray(false); byte []newArray = bfia.getByteArray(test); for(int i = 0; i < newArray.length; i++) System.out.print(" " + PadString.padHex(newArray[i], 2)); } public ByteFromIntArray(boolean littleEndian) { this.littleEndian = littleEndian; } public byte getByte(int[] array, int location) { if((location / 4) >= array.length) throw new ArrayIndexOutOfBoundsException("location = " + location + ", number of bytes = " + (array.length * 4)); int theInt = location / 4; // rounded int theByte = location % 4; // remainder // reverse the byte to simulate little endian if(littleEndian) theByte = 3 - theByte; // I was worried about sign-extension here, but then I realized that they are being // put into a byte anyway so it wouldn't matter. if(theByte == 0) return (byte)((array[theInt] & 0x000000FF) >> 0); else if(theByte == 1) return (byte)((array[theInt] & 0x0000FF00) >> 8); else if(theByte == 2) return (byte)((array[theInt] & 0x00FF0000) >> 16); else if(theByte == 3) return (byte)((array[theInt] & 0xFF000000) >> 24); return 0; } /** This function is used to insert the byte into a specified spot in * an int array. This is used to simulate pointers used in C++. * Note that this works in little endian only. * @param intBuffer The buffer to insert the int into. * @param b The byte we're inserting. * @param location The location (which byte) we're inserting it into. * @return The new array - this is returned for convenience only. */ public int[] insertByte(int[] intBuffer, int location, byte b) { // Get the location in the array and in the int int theInt = location / 4; int theByte = location % 4; // If we're using little endian reverse the hex position if(littleEndian == false) theByte = 3 - theByte; int replaceInt = intBuffer[theInt]; // Creating a new variable here because b is a byte and I need an int int newByte = b << (8 * theByte); if(theByte == 0) replaceInt &= 0xFFFFFF00; else if(theByte == 1) replaceInt &= 0xFFFF00FF; else if(theByte == 2) replaceInt &= 0xFF00FFFF; else if(theByte == 3) replaceInt &= 0x00FFFFFF; replaceInt = replaceInt | newByte; intBuffer[theInt] = replaceInt; return intBuffer; } public byte[] getByteArray(int[] array) { byte[] newArray = new byte[array.length * 4]; int pos = 0; for(int i = 0; i < array.length; i++) { if(littleEndian) { newArray[pos++] = (byte)((array[i] >> 0) & 0xFF); newArray[pos++] = (byte)((array[i] >> 8) & 0xFF); newArray[pos++] = (byte)((array[i] >> 16) & 0xFF); newArray[pos++] = (byte)((array[i] >> 24) & 0xFF); } else { newArray[pos++] = (byte)((array[i] >> 24) & 0xFF); newArray[pos++] = (byte)((array[i] >> 16) & 0xFF); newArray[pos++] = (byte)((array[i] >> 8) & 0xFF); newArray[pos++] = (byte)((array[i] >> 0) & 0xFF); } } return newArray; } } [/code] -- and -- [code]/* * IntFromByteArray.java * * Created on May 21, 2004, 12:35 PM */ package bot.util; /** This is a class to take care of inserting or getting the value of an int in an array of * bytes. * @author Ron - Home */ public class IntFromByteArray { private boolean littleEndian; public static final IntFromByteArray LITTLEENDIAN = new IntFromByteArray(true); public static final IntFromByteArray BIGENDIAN = new IntFromByteArray(false); /** * @param args the command line arguments */ public static void main(String args[]) { byte[] test = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; IntFromByteArray ifba = new IntFromByteArray(true); int[] newArray = ifba.getIntArray(test); for(int i = 0; i < newArray.length; i++) System.out.print(PadString.padHex(newArray[i], 8) + " "); } public IntFromByteArray(boolean littleEndian) { this.littleEndian = littleEndian; } public int getInteger(byte[] array, int location) { if((location + 3) >= array.length) throw new ArrayIndexOutOfBoundsException("location = " + location + ", number of bytes = " + array.length + " (note: 4 available bytes are needed)"); int retVal = 0; // reverse the byte to simulate little endian if(littleEndian) { retVal = retVal | ((array[location++] << 0) & 0x000000FF); retVal = retVal | ((array[location++] << 8) & 0x0000FF00); retVal = retVal | ((array[location++] << 16) & 0x00FF0000); retVal = retVal | ((array[location++] << 24) & 0xFF000000); } else { retVal = retVal | ((array[location++] << 24) & 0xFF000000); retVal = retVal | ((array[location++] << 16) & 0x00FF0000); retVal = retVal | ((array[location++] << 8) & 0x0000FF00); retVal = retVal | ((array[location++] << 0) & 0x000000FF); } return retVal; } /** This function is used to insert the byte into a specified spot in * an int array. This is used to simulate pointers used in C++. * Note that this works in little endian only. * @param intBuffer The buffer to insert the int into. * @param b The byte we're inserting. * @param location The location (which byte) we're inserting it into. * @return The new array - this is returned for convenience only. */ public byte[] insertInteger(byte[] array, int location, int b) { if(location + 3 >= array.length) throw new ArrayIndexOutOfBoundsException("location = " + location + ", length = " + array.length + " - note that we need 4 bytes to insert an int"); if(littleEndian) { array[location++] = (byte)((b & 0x000000FF) >> 0); array[location++] = (byte)((b & 0x0000FF00) >> 8); array[location++] = (byte)((b & 0x00FF0000) >> 16); array[location++] = (byte)((b & 0xFF000000) >> 24); } else { array[location++] = (byte)((b & 0xFF000000) >> 24); array[location++] = (byte)((b & 0x00FF0000) >> 16); array[location++] = (byte)((b & 0x0000FF00) >> 8); array[location++] = (byte)((b & 0x000000FF) >> 0); } return array; } /** Note: This will cut off the end bytes to ensure it's a multiple of 4 */ public int[] getIntArray(byte[] array) { int[] newArray = new int[array.length / 4]; int pos = 0; for(int i = 0; i < newArray.length; i++) { if(littleEndian) { newArray[i] |= ((array[pos++] << 0) & 0x000000FF); newArray[i] |= ((array[pos++] << 8) & 0x0000FF00); newArray[i] |= ((array[pos++] << 16) & 0x00FF0000); newArray[i] |= ((array[pos++] << 24) & 0xFF000000); } else { newArray[i] |= array[pos++] << 24; newArray[i] |= array[pos++] << 16; newArray[i] |= array[pos++] << 8; newArray[i] |= array[pos++] << 0; } } return newArray; } } [/code] If you know of a better way to do this, I would love to hear! :) | May 21, 2004, 9:59 PM |
After-Death | I cant read C, how would I find out what the SHA-1 hash does to attempt to write my own in java ? | May 26, 2004, 11:59 PM |
Tuberload | http://www.itl.nist.gov/fipspubs/fip180-1.htm HTH | May 27, 2004, 12:47 AM |
iago | If you want real SHA-1, see java.security.MessageDigest. If you want BrokenSHA1, talk to me privately or even just ask here, I'll post it. | May 27, 2004, 12:52 AM |
After-Death | Oh yeah I forget its altered. Well post it, or if you don't like to post it you have me on AIM: AfterDeaf and PM Your chat bot that you sent me has inspired me to write a clientless bot :) | May 28, 2004, 11:59 AM |