Linux-Fan

Simple BrouteForce Benchmark

Jan 19th, 2012
106
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.io.*;
  2. import java.security.*;
  3.  
  4. public class BrouteForce3 {
  5.  
  6.     private final String againstMD5;
  7.  
  8.     private int stringLength;
  9.     private Thread statusDisplay;
  10.  
  11.     public BrouteForce3(String againstMD5) {
  12.         super();
  13.         this.againstMD5 = againstMD5;
  14.         System.out.println("Trying to crack " + againstMD5 + "...");
  15.         stringLength = 1;
  16.     }
  17.  
  18.     void startCracking() {
  19.         short[] numberData = new short[againstMD5.length() / 2]; // 0x10
  20.         int j;
  21.         for(int i = 0; i < numberData.length; i++) {
  22.             j = 2 * i;
  23.             numberData[i] = Short.parseShort(againstMD5.substring(j, j + 2), 0x10);
  24.         }
  25.         final byte[] md5 = MiniToolbox.signBytes(numberData);
  26.         final int processors = Runtime.getRuntime().availableProcessors();
  27.         System.out.println("Using " + processors + " Threads to search.");
  28.         System.out.println("Creating and starting threads...");
  29.         final SearchThread[] allSearchers = new SearchThread[processors];
  30.         for(int i = 0; i < allSearchers.length; i++) {
  31.             allSearchers[i] = new SearchThread(this, md5);
  32.             allSearchers[i].start();
  33.         }
  34.         final Thread cancelThread = new Thread() {
  35.             public void run() {
  36.                 setName("Ma_Sys.ma Broute Force 3 Cancel Thread");
  37.                 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  38.                 try {
  39.                     in.readLine();
  40.                 } catch(IOException ex) {
  41.                     System.err.println("Aborting via [Enter] not supported -- use CTRL-C");
  42.                     ex.printStackTrace();
  43.                     return;
  44.                 }
  45.                 if(statusDisplay.isInterrupted()) {
  46.                     System.exit(0);
  47.                 } else {
  48.                     statusDisplay.interrupt();
  49.                 }
  50.             }
  51.         };
  52.         statusDisplay = new Thread() {
  53.             public void run() {
  54.                 setName("Ma_Sys.ma Broute Force 3 Status Display Thread");
  55.                 long start = System.currentTimeMillis();
  56.                 int clear = 0, cursor = 0;
  57.                 long doneTotal = 0, max = 0;
  58.                 final int diagramSize = 78;
  59.                 long[] diagramContent = new long[diagramSize];
  60.                 boolean diagramComplete = false;
  61.                 while(!isInterrupted()) {
  62.                     try {
  63.                         Thread.sleep(1000);
  64.                     } catch(InterruptedException ex) {
  65.                         System.out.println("Status Display Thread interrupted.");
  66.                         break;
  67.                     }
  68.                     char[] clearer = new char[clear];
  69.                     for(int i = 0; i < clear; i++) {
  70.                         clearer[i] = '\b';
  71.                     }
  72.                     System.out.print(new String(clearer));
  73.                     long doneThisSec = 0;
  74.                     for(int i = 0; i < allSearchers.length; i++) {
  75.                         doneThisSec += allSearchers[i].fetchDoneWork();
  76.                     }
  77.                     doneTotal += doneThisSec;
  78.                     diagramContent[cursor] = doneThisSec;
  79.                     if(doneThisSec > max) {
  80.                         max = doneThisSec;
  81.                     }
  82.                     if(cursor == diagramSize - 1) {
  83.                         cursor = 0;
  84.                         if(!diagramComplete) {
  85.                             diagramComplete = true;
  86.                         }
  87.                     } else {
  88.                         cursor++;
  89.                     }
  90.                     String toBeDisplayed = "STATUS speed=" + doneThisSec + "/s strlen=" + stringLength;
  91.                     clear = toBeDisplayed.length();
  92.                     System.out.print(toBeDisplayed);
  93.                 }
  94.                 final int stringLengthF = stringLength;
  95.                 if(cancelThread.getState() != Thread.State.TERMINATED) {
  96.                     cancelThread.interrupt();
  97.                 }
  98.                 for(int i = 0; i < allSearchers.length; i++) {
  99.                     allSearchers[i].interrupt();
  100.                 }
  101.                 System.out.println();
  102.                 System.out.println("Statistics");
  103.                 long time = System.currentTimeMillis() - start;
  104.                 System.out.println("\tTime                 " + time + " ms.");
  105.                 System.out.println("\tCombinations total   " + doneTotal);
  106.                 System.out.println("\tAvg Combinations/ms  " + (doneTotal / time));
  107.                 System.out.println("\tStrlen               " + stringLength);
  108.                 System.out.println("\tFully searched       " + (stringLengthF - processors));
  109.                 System.out.println("\tMax Combinations/ms  " + (max / 1000));
  110.                 System.out.println();
  111.                 // draw a diagram
  112.                 int diagramHeight = 15; // Lines
  113.                 int length, beginIndex;
  114.                 if(diagramComplete) {
  115.                     beginIndex = cursor;
  116.                     length     = diagramSize;
  117.                 } else {
  118.                     beginIndex = 0;
  119.                     length     = cursor;
  120.                 }
  121.                 int[] xyData = new int[length];
  122.                 int j = 0;
  123.                 for(int i = beginIndex; i < length; i++) {
  124.                     xyData[j] = (int)(((double)diagramContent[i]) / (double)max * diagramHeight);
  125.                     j++;
  126.                 }
  127.                 if(diagramComplete) {
  128.                     for(int i = 0; i < cursor; i++) {
  129.                         xyData[j] = (int)(((double)diagramContent[i]) / (double)max * diagramHeight);
  130.                         j++;
  131.                     }
  132.                 }
  133.                 for(int i = 0; i < diagramHeight; i++) {
  134.                     char[] lineContent = new char[xyData.length];
  135.                     for(j = 0; j < xyData.length; j++) {
  136.                         if(i >= diagramHeight - xyData[j]) {
  137.                             lineContent[j] = '#';
  138.                         } else {
  139.                             lineContent[j] = '_';
  140.                         }
  141.                     }
  142.                     System.out.println(' ' + new String(lineContent));
  143.                 }
  144.                 // Cancel remaining thread
  145.                 if(cancelThread.getState() != Thread.State.TERMINATED) {
  146.                     System.out.println();
  147.                     System.out.println("Press enter to exit...");
  148.                 }
  149.             }
  150.         };
  151.         cancelThread.start();
  152.         statusDisplay.start();
  153.     }
  154.  
  155.     void exit() {
  156.         statusDisplay.interrupt();
  157.     }
  158.  
  159.     int requestNewLengthToCrack() {
  160.         // First return 1 (as already initialized) and then 2 to the next thread, etc.
  161.         return stringLength++;
  162.     }
  163.  
  164.     private static void crack(String md5) {
  165.         new BrouteForce3(md5).startCracking();
  166.     }
  167.  
  168.     private static void usage(String msg) {
  169.         System.out.println(msg);
  170.         System.out.println();
  171.         System.out.println("Usage: java BrouteForce3 --benchmark|--crack|--md5 [md5|string]");
  172.         System.out.println();
  173.         System.out.println("--benchmark");
  174.         System.out.println("\tMakes a benchmark against a md5 of zeroes.");
  175.         System.out.println("\tWrites statistics and current status as usual.");
  176.         System.out.println("--crack");
  177.         System.out.println("\tTries to crack the given MD5.");
  178.         System.out.println("\tIf you really want to do this: Do not use this program.");
  179.         System.out.println("\tIt is WAY to slow for your goal then.");
  180.         System.out.println("--md5");
  181.         System.out.println("\tCalculates the MD5 of the given string.");
  182.         System.out.println();
  183.         System.out.println("Our alphabet:");
  184.         System.out.println(SearchThread.ALPHABET);
  185.         System.out.println();
  186.         System.out.println("When running, the program can be stopped via [Enter].");
  187.     }
  188.  
  189.     public static void main(String[] args) {
  190.         System.out.println("Broute Force 3.0.0.1, Copyright (c) 2012 Ma_Sys.ma.");
  191.         System.out.println("For further info send an e-mail to Ma_Sys.ma@web.de.");
  192.         System.out.println();
  193.         if(args.length == 0 || args.length > 2) {
  194.             usage("Invalid number of arguments.");
  195.         } else if(args.length == 1) {
  196.             if(args[0].equals("--benchmark")) {
  197.                 crack("00000000000000000000000000000000");
  198.             } else {
  199.                 usage("When giving only one argument, it must be --benchmark.");
  200.             }
  201.         } else {
  202.             if(args[0].equals("--crack")) {
  203.                 if(args[1].length() == 32) {
  204.                     crack(args[1]);
  205.                 } else {
  206.                     usage("An MD5 sum must be given and it must have a length of excactly 32 characters.");
  207.                 }
  208.             } else if(args[0].equals("--md5")) {
  209.                 MessageDigest md5;
  210.                 try {
  211.                     md5 = MessageDigest.getInstance("md5");
  212.                 } catch(NoSuchAlgorithmException ex) {
  213.                     System.err.println("Message Digest could not be initialized.");
  214.                     ex.printStackTrace();
  215.                     return;
  216.                 }
  217.                 byte[] checksumBytes = md5.digest(args[1].getBytes());
  218.                 StringBuffer checksumString = new StringBuffer(checksumBytes.length * 2);
  219.                 for(int i = 0; i < checksumBytes.length; i++) {
  220.                     checksumString.append(MiniToolbox.formatAsHex(checksumBytes[i]));
  221.                 }
  222.                 System.out.println(checksumString.toString());
  223.             }
  224.         }
  225.         System.out.println();
  226.     }
  227.  
  228. }
  229.  
  230. class SearchThread extends Thread {
  231.    
  232.     private static final String alphabet = "abcdefghijklmnopqrstuvwxyz";
  233.     private static final String numbers  = "0123456789";
  234.     private static final String special  = "!§$%&/\\{([)]}=?+*~#-_.:,;><|";
  235.     public static final String ALPHABET = alphabet + alphabet.toUpperCase() + numbers + special;
  236.     private static final char[] alphabetArray = ALPHABET.toCharArray();
  237.  
  238.     private final byte[] md5ToCrack;
  239.  
  240.     private int doneSec;
  241.     private int currentStringLength;
  242.  
  243.     private BrouteForce3 controller;
  244.  
  245.     public SearchThread(BrouteForce3 controller, byte[] md5ToCrack) {
  246.         super("Ma_Sys.ma Broute Force 3 Search Thread");
  247.         this.md5ToCrack = md5ToCrack;
  248.         this.controller = controller;
  249.         doneSec = 0;
  250.         currentStringLength = controller.requestNewLengthToCrack();
  251.     }
  252.    
  253.     // TODO OPTIMIZE
  254.     public void run() {
  255.         MessageDigest md5;
  256.         try {
  257.             md5 = MessageDigest.getInstance("md5");
  258.         } catch(NoSuchAlgorithmException ex) {
  259.             System.err.println("Message Digest could not be initialized.");
  260.             ex.printStackTrace();
  261.             return;
  262.             // TODO EXIT APPLICATION
  263.         }
  264.         int i, j;
  265.         boolean ok;
  266.         short[] nr;
  267.         char[] cdata;
  268.         byte[] bdata, digest;
  269.         while(!isInterrupted()) {
  270.             nr = new short[currentStringLength];
  271.             for(i = 0; i < currentStringLength; i++) {
  272.                 nr[i] = 0;
  273.             }
  274.             while(!isInterrupted()) {
  275.                 // Generate String from combination and store it as a byte array
  276.                 cdata = new char[currentStringLength];
  277.                 j = 0;
  278.                 for(i = nr.length-1; i >= 0; i--) {
  279.                     cdata[j] = alphabetArray[nr[i]];
  280.                     j++;
  281.                 }
  282.                 bdata = new String(cdata).getBytes();
  283.  
  284.                 // Checksum it and compare it to the stored checksum
  285.                 digest = md5.digest(bdata);
  286.                 i = 0;
  287.                 while(i < 0x10 && md5ToCrack[i] == digest[i]) {
  288.                     i++;
  289.                 }
  290.                 if(i == 0x10) {
  291.                     System.out.println();
  292.                     System.out.println("Combination found: " + new String(cdata));
  293.                     controller.exit();
  294.                     return;
  295.                 }
  296.                 md5.reset();
  297.  
  298.                 // Calculate the next combination
  299.                 doneSec++;
  300.                 ok = false;
  301.                 for(i = 0; i < nr.length; i++) {
  302.                     nr[i]++;
  303.                     if(nr[i] >= alphabetArray.length) {
  304.                         nr[i] = 0;
  305.                     } else {
  306.                         ok = true;
  307.                         break;
  308.                     }
  309.                 }
  310.                 if(!ok) {
  311.                     break;
  312.                 }
  313.             }
  314.             currentStringLength = controller.requestNewLengthToCrack();
  315.         }
  316.     }
  317.  
  318.     int fetchDoneWork() {
  319.         int ret = doneSec;
  320.         doneSec = 0;
  321.         return ret;
  322.     }
  323.  
  324. }
  325.  
  326. /**
  327.  * Auszüge aus der Ma_Sys.ma Tools Bibliothek 2
  328.  */
  329. class MiniToolbox {
  330.    
  331.     // Aus den MathUtils
  332.     /**
  333.      * Macht aus notierten Hexadezimalzahlen (0xff, 0xa5, 0x17, etc.) entsprechende bytes
  334.      * und fügt dafür entsprechend Vorzeichen ein.
  335.      *
  336.      * @param unsignedInput Nicht vorzeichenbehaftete Hexadezimalzahlen 0-255
  337.      * @return Vorzeichenbehaftete bytes
  338.      */
  339.     public static byte[] signBytes(short[] unsignedInput) {
  340.         byte[] ret = new byte[unsignedInput.length];
  341.         for(int i = 0; i < unsignedInput.length; i++) {
  342.             if(unsignedInput[i] > 127) {
  343.                 ret[i] = (byte)(unsignedInput[i] - 0x100);
  344.             } else {
  345.                 ret[i] = (byte)unsignedInput[i];
  346.             }
  347.         }
  348.         return ret;
  349.     }
  350.  
  351.     // Aus der Klasse StringUtils
  352.     /**
  353.      * Formatiert den angegebenen byte als Hexadezimalzahl mit zwei Stellen.
  354.      * <br>
  355.      * Beispiel :
  356.      * <pre>
  357.      * import ma.tools.StringUtils;
  358.      *
  359.      * public class FormatHexTest {
  360.      *  public static void main(String[] args) {
  361.      *      byte theByte = 56;
  362.      *      System.out.println(StringUtils.formatAsHex(theByte);
  363.      *  }
  364.      * }
  365.      * </pre>
  366.      *
  367.      * @param number Der zu formatierende byte.
  368.      * @return Einen String, der die Hexadezimaldarstellung von number enth&auml;lt.
  369.      */
  370.     public static String formatAsHex(byte number) {
  371.         String ret = null;
  372.         String hex = Integer.toHexString(number);
  373.         int len = hex.length();
  374.         if(len == 1) {
  375.             ret = "0" + hex;
  376.         } else if(len == 2) {
  377.             ret = hex;
  378.         } else if(len > 2) {
  379.             ret = hex.substring(len-2);
  380.         }
  381.         return ret;
  382.     }
  383. }
RAW Paste Data