Author | Message | Time |
---|---|---|
shout | I am trying to create a check revison algorithum... but it does not give the correct values. I am using the string "A=153298715 B=515653871 C=630933526 4 A=A+S B=B^C C=C^A A=A^B" (which I got from packetlogging brood war), and when I use mine ( from iago's Java) I get 0x44c0733a, but with BNLS I get 0xff887946. Here is my code (sorry for lack of comments): [code] private static uint[] hashcodes = new uint[] { 0xE7F4CB62, 0xF6A14FFC,0xAA5504AF,0x871FCDC2,0x11BF6A18,0xC57292E6,0x7927D27E,0x2FEC8733 }; public static uint CheckRevision(string VersionString, string[] FileNames, string client, int mpqNum) { char[] Operations = new char[4]; ulong[] Values = new ulong[4]; int[] opDest = new int[4]; int[] opSrc1 = new int[4]; int[] opSrc2 = new int[4]; SeperateVerString(VersionString, Operations, Values, opDest, opSrc1, opSrc2); Values[0] ^= hashcodes[mpqNum]; for (int i = 0; i < 3; i++) { FileStream fileStream = new FileStream(FileNames[i],FileMode.Open, FileAccess.Read); FileInfo fileInfo = new FileInfo(FileNames[i]); int fileLength = (int)fileInfo.Length; byte[] Buffer = new byte[4]; int roundedLength = (fileLength / 1024) * 1024; for (int j = 0; j < roundedLength; j += 4) { fileStream.Read(Buffer, 0, 4); Values[3] = BitConverter.ToUInt32(Buffer, 0); for (int k = 0; k < 4; k++) { switch (Operations[k]) { case '+': Values[opDest[k]] = Values[opSrc1[k]] + Values[opSrc2[k]]; break; case '-': Values[opDest[k]] = Values[opSrc1[k]] - Values[opSrc2[k]]; break; case '^': Values[opDest[k]] = Values[opSrc1[k]] ^ Values[opSrc2[k]]; break; default: break; } } } } return (uint)Values[2]; } private static void SeperateVerString(string VersionString, char[] Operations, ulong[] Values, int[] opDest, int[] opSrc1, int[] opSrc2) { char equals = '='; char space = ' '; string[] verString = VersionString.Split(space); string[] values = new string[4]; string[] tmp = new string[2]; for (int i = 0; i < 4; i++) { values[i] = verString[i]; } for (int i = 0; i < 3; i++) { tmp = values[i].Split(equals); Values[i] = (ulong)int.Parse(tmp[1]); } for (int i = 0; i < 3; i++) { opDest[i] = getNum((char)verString[i + 4][0]); opSrc1[i] = getNum((char)verString[i + 4][2]); opSrc2[i] = getNum((char)verString[i + 4][4]); Operations[i] = verString[i + 4][3]; } } [/code] Don't ask why I put the chars in a variable in SeperateVerString but I did so oh well. And just for good measure, iago's code: [code] /* * CheckRevision.java * * Created on March 10, 2004, 9:05 AM */ package bot.bnet.util; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.MappedByteBuffer; import java.nio.ByteOrder; import java.util.StringTokenizer; import timer.Timer; /** * * @author iago */ public class CheckRevision { private static final int hashcodes[] = { 0xE7F4CB62, 0xF6A14FFC, 0xAA5504AF, 0x871FCDC2, 0x11BF6A18, 0xC57292E6, 0x7927D27E, 0x2FEC8733 }; /** This class simply does the version check on the three main files. */ public static int checkRevision(String versionString, String[] files, int mpqNum) throws FileNotFoundException, IOException { // First, parse the versionString to name=value pairs and put them // in the appropriate place int[] values = new int[4]; int[] opValueDest = new int[4]; int[] opValueSrc1 = new int[4]; char[] operation = new char[4]; int[] opValueSrc2 = new int[4]; // Break this apart at the spaces StringTokenizer s = new StringTokenizer(versionString, " "); int currentFormula = 0; while(s.hasMoreTokens()) { String thisToken = s.nextToken(); // As long as there is an '=' in the string if(thisToken.indexOf('=') > 0) { // Break it apart at the '=' StringTokenizer nameValue = new StringTokenizer(thisToken, "="); if(nameValue.countTokens() != 2) return 0; int variable = getNum(nameValue.nextToken().charAt(0)); String value = nameValue.nextToken(); //System.out.println((int)variable + " = " + value); // If it starts with a number, assign that number to the appropriate variable if(Character.isDigit(value.charAt(0))) { values[variable] = Integer.parseInt(value); } else { opValueDest[currentFormula] = variable; opValueSrc1[currentFormula] = getNum(value.charAt(0)); operation[currentFormula] = value.charAt(1); opValueSrc2[currentFormula] = getNum(value.charAt(2)); currentFormula++; } } } // Now we actually do the hashing for each file // Start by hashing A by the hashcode values[0] ^= hashcodes[mpqNum]; for(int i = 0; i < files.length; i++) { Timer thisFile = new Timer(); File currentFile = new File(files[i]); int roundedSize = (int)((currentFile.length() / 1024) * 1024); // Load the file into memory FileInputStream input = new FileInputStream(new File(files[i])); MappedByteBuffer file = input.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, roundedSize); file.order(ByteOrder.LITTLE_ENDIAN); file.load(); //System.out.println("Processing " + currentFile.toString() + " (" + (roundedSize/4) + " DWords)"); //System.out.print("Processing " + currentFile.toString() + "........"); for(int j = 0; j < roundedSize; j += 4) { values[3] = file.getInt(j); //values[3] = (file.get() & 0xFF) | // ((file.get() & 0xFF) << 8) | // ((file.get() & 0xFF) << 16) | // ((file.get() & 0xFF) << 24); for(int k = 0; k < currentFormula; k++) { switch(operation[k]) { case '+': values[opValueDest[k]] = values[opValueSrc1[k]] + values[opValueSrc2[k]]; break; case '-': values[opValueDest[k]] = values[opValueSrc1[k]] - values[opValueSrc2[k]]; break; case '^': values[opValueDest[k]] = values[opValueSrc1[k]] ^ values[opValueSrc2[k]]; break; default: return 0; } } } //System.out.println(thisFile.getTime() + "ms."); } //System.out.println(Integer.toHexString(values[0])); //System.out.println(Integer.toHexString(values[1])); //System.out.println(Integer.toHexString(values[2])); return values[2]; } private static int getNum(char c) { c = Character.toUpperCase(c); if(c == 'S') return 3; else return c - 'A'; } public static void main(String args[]) throws Exception { String[] files = { "/home/iago/Projects/Java/bot/starcraft.exe", "/home/iago/Projects/Java/bot/storm.dll", "/home/iago/Projects/Java/bot/battle.snp" } ; long totalTime = 0; final int MAX = 100; long min = -1; long max = -1; for(int i = 0; i < MAX; i++) { int val1 = (int) (Math.random() * (double)Integer.MAX_VALUE); int val2 = (int) (Math.random() * (double)Integer.MAX_VALUE); int val3 = (int) (Math.random() * (double)Integer.MAX_VALUE); String testString = "A=" + val1 + " B=" + val2 + " C=" + val3 + " 4 A=A^S B=B-C C=C+A A=A+B"; Timer checkRevision = new Timer(); checkRevision(testString, files, 6); long elapsed = checkRevision.getTime(); System.out.println("checkRevision took " + elapsed + "ms."); totalTime += elapsed; if(elapsed < min || min == -1) min = elapsed; if(elapsed > max || max == -1) max = elapsed; } System.out.println("For " + MAX + "runs:"); System.out.println("Total time: " + totalTime + "ms"); System.out.println("Average time: " + (totalTime / MAX) + "ms"); System.out.println("Min time: " + min + "ms"); System.out.println("Max time: " + max + "ms"); //System.out.println(Integer.toHexString(a)); } } [/code] | November 24, 2004, 8:01 PM |
Mephisto | Immediately looking at your switch statement I see that you're not doing as you should. In the case of xor, you're adding, same with the case of subtraction, you still add. | November 24, 2004, 8:12 PM |
shout | LOL... I am so FUCKING STUPID!!! ** Hits head on keyboard ** (Crying)Stupid, stupid, stupid... Fixed that. Now I get 0xab919d86. I guess I will have to go through the grueling task of installing java on my machine... **sigh** It seems although my SeperateVerString method is faulty. I shall fix it. | November 24, 2004, 8:14 PM |
Myndfyr | [quote author=shout link=topic=9666.msg89918#msg89918 date=1101327266] I guess I will have to go through the grueling task of installing java on my machine... **sigh** [/quote] Or maybe you could just fix it and get it right...? | November 25, 2004, 2:09 AM |
shout | It was more so I could tell exactly what iago's code was doing. Well, anyway, it works now. It's kind of ugly and it may only work with SC/BW [code] public class CheckRevision { private static bool SeperateVerString(string VersionString, char[] Operations, ulong[] Values, int[] opDest, int[] opSrc1, int[] opSrc2) { string[] verString = VersionString.Split(' '); //Split the string at the spaces string[] NumericASValues = new string[4]; //The A=320842304 and so fourth for (int i = 0; i != 4; i++) //Puts the string values into an array { NumericASValues[i] = verString[i]; } string[] tmpstr = new string[2]; //Temp storage for split string of values for (int i = 0; i != 3; i++) { tmpstr = NumericASValues[i].Split('='); //Splits the string at the = Values[i] = ulong.Parse(tmpstr[1]); //Parses values into ulongs } Values[3] = 4; for (int i = 0; i != 4; i++) { opDest[i] = getNum((char)verString[i + 4][0]); //Gets the destination for the calculation opSrc1[i] = getNum((char)verString[i + 4][2]); //Gets the first source for the calculation opSrc2[i] = getNum((char)verString[i + 4][4]); //Gets the 2nd source for the calculation Operations[i] = verString[i + 4][3]; //Gets the operator for the calculation } return true; } private static uint[] hashcodes = new uint[] { 0xE7F4CB62, 0xF6A14FFC,0xAA5504AF,0x871FCDC2,0x11BF6A18,0xC57292E6,0x7927D27E,0x2FEC8733 }; public static uint CheckRevision(string VersionString, string[] FileNames, string client, int mpqNum) { char[] Operations = new char[4]; ulong[] Values = new ulong[4]; int[] opDest = new int[4]; int[] opSrc1 = new int[4]; int[] opSrc2 = new int[4]; SeperateVerString(VersionString, Operations, Values, opDest, opSrc1, opSrc2); Values[0] ^= hashcodes[mpqNum]; for (int i = 0; i < 3; i++) { FileStream fileStream = new FileStream(FileNames[i],FileMode.Open, FileAccess.Read); FileInfo fileInfo = new FileInfo(FileNames[i]); int fileLength = (int)fileInfo.Length; byte[] Buffer = new byte[4]; int roundedLength = (fileLength / 1024) * 1024; for (int j = 0; j < roundedLength; j += 4) { fileStream.Read(Buffer, 0, 4); Values[3] = BitConverter.ToUInt32(Buffer, 0); for (int k = 0; k < 4; k++) { switch (Operations[k]) { case '+': Values[opDest[k]] = Values[opSrc1[k]] + Values[opSrc2[k]]; break; case '-': Values[opDest[k]] = Values[opSrc1[k]] - Values[opSrc2[k]]; break; case '^': Values[opDest[k]] = Values[opSrc1[k]] ^ Values[opSrc2[k]]; break; default: break; } } } } return (uint)Values[2]; } private static int getNum(char c) { c = char.ToUpper(c); if(c == 'S') { return 3; } else { return c - 'A'; } } } [/code] | November 25, 2004, 2:24 AM |