SuperLeaf
SuperLeaf

Reputation: 35

Brute Force Algorithm w/Java Passing String Error

I think this may be a very simple solution but I am not too sure.

I am trying to create an array of characters, sort through them by incrementing a particular index of the array and throwing them into a string at the end.

I have accomplished this, (verified via printing the result out to the console. "aaaaaaaa" to "aaaaaaab" and so on. However, my new version of the code sorts through ASCII Values 33 - 126. '!' to '~'

Now, the one thing I am trying to do is call that string in the main method so that the encryption/decryption program that we were assigned, can use this string over and over again.

The program we were originally assigned can be found here: http://www.avajava.com/tutorials/lessons/how-do-i-encrypt-and-decrypt-files-using-des.html

    import java.lang.Class.*;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import javax.crypto.Cipher;
    import javax.crypto.CipherInputStream;
    import javax.crypto.CipherOutputStream;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;

public class Example1 {

public String keyGen() {
//create an array used for storing each character    
char array[] = new char[8];

    //for loop checks for each character between '!' and '~'
    for (char c0 = '!'; c0 <= '~'; c0++) {
    array[0] = c0;

    for (char c1 = '!'; c1 <= '~'; c1++) {
    array[1] = c1;

    for (char c2 = '!'; c2 <= '~'; c2++) {
    array[2] = c2;

    for (char c3 = '!'; c3 <= '~'; c3++) {
    array[3] = c3;

    for (char c4 = '!'; c4 <= '~'; c4++) {
    array[4] = c4;

    for (char c5 = '!'; c5 <= '~'; c5++) {
    array[5] = c5;

    for (char c6 = '!'; c6 <= '~'; c6++) {
    array[6] = c6;

    for (char c7 = '!'; c7 <= '~'; c7++) {
    array[7] = c7;

    //create new string that stores the array
    String pKey = new String(array);

    //trying to return the new string 
    return pKey;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } 
                }
            }

public static void main(String []args) {
try {

// I am getting an error here; I know it has something to do with static references

    String key = new String(keyGen(pKey); 

                    // needs to be at least 8 characters for DES

        FileInputStream fis = new FileInputStream("original.txt");
        FileOutputStream fos = new FileOutputStream("encrypted.txt");
        encrypt(key, fis, fos);

        FileInputStream fis2 = new FileInputStream("encrypted.txt");
        FileOutputStream fos2 = new FileOutputStream("decrypted.txt");
        decrypt(key, fis2, fos2);
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

public static void encrypt(String key, InputStream is, OutputStream os) throws Throwable {
    encryptOrDecrypt(key, Cipher.ENCRYPT_MODE, is, os);
}

public static void decrypt(String key, InputStream is, OutputStream os) throws Throwable {
    encryptOrDecrypt(key, Cipher.DECRYPT_MODE, is, os);
}

public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {

    DESKeySpec dks = new DESKeySpec(key.getBytes());
    SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
    SecretKey desKey = skf.generateSecret(dks);
    Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE

    if (mode == Cipher.ENCRYPT_MODE) {
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        CipherInputStream cis = new CipherInputStream(is, cipher);
        doCopy(cis, os);
    } else if (mode == Cipher.DECRYPT_MODE) {
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        CipherOutputStream cos = new CipherOutputStream(os, cipher);
        doCopy(is, cos);
    }
}

public static void doCopy(InputStream is, OutputStream os) throws IOException {
    byte[] bytes = new byte[64];
    int numBytes;
    while ((numBytes = is.read(bytes)) != -1) {
        os.write(bytes, 0, numBytes);
    }
    os.flush();
    os.close();
    is.close();
}

}

Thi

Upvotes: 2

Views: 1293

Answers (1)

jlordo
jlordo

Reputation: 37813

Hope this helps you solve the problem. As for right now, your keyGen() is equivalent to the following code:

public String keyGen() {
    return "!!!!!!!!";
}

because you return the value as soon as you enter the innermost for loop. Maybe you want to change the method to return a List<String> and add your strings in the innermost for loop to that list, and return that list after all of the for loops? This way you could iterate through the list in your main method.


If I have counted correct, there are 93^8 = 5.595.818.096.650.401 different strings. It was bad advice to store all those in a list. Dukeling noted in the comments, that it would be better to use a custom Iterator<String> for that.


EDIT

Here's an implementation of such an iterator:

import java.util.Arrays;
import java.util.Iterator;

public class BruteForceIterator implements Iterator<String> {

    private char min, max;

    private char[] current;

    private char[] last;

    private int reachedLast = 0;

    public BruteForceIterator(char min, char max, int length) {
        this.min = min;
        this.max = max;
        current = new char[length];
        Arrays.fill(current, min);
        last = new char[length];
        Arrays.fill(last, max);
    }

    @Override
    public boolean hasNext() {
        return reachedLast < 2;
    }

    @Override
    public String next() {
        String str = new String(current);
        for(int i = current.length - 1; i >= 0; i--) {
            char next = following(current[i]);
            current[i] = next;
            if (next != min) {
                break;
            }
        }
        if (Arrays.equals(current, last) || reachedLast > 0) {
            reachedLast++;
        }
        return str;
    }

    private char following(char in) {
        if (in < max) {
            return (char) (in + 1);
        } else {
            return min;
        }
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("No with me, sir!");
    }

    public static void main(String[] args) {
        BruteForceIterator bit = new BruteForceIterator('a', 'c', 3);
        while (bit.hasNext()) {
            System.out.println(bit.next());
        }
    }
}

Upvotes: 3

Related Questions