Here is the updated code. The original question can be found here.
I would love it if you posted more ways I can improve this code. I am still fairly new to Java so I am not entirely sure how to make it any better.
package hexTox;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
public class Main {
static String newPass = "";
static String chars = "0123456789aABbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyzZ";
public static void main(String[] args) {
Scanner userIn = new Scanner(System.in);
String password = userIn.nextLine();
String choose;
boolean decideSymb = true;
do {
System.out.println("Is using symbols an option? if so type in [Y] if not type in [N]");
choose = userIn.nextLine();
} while (!choose.equalsIgnoreCase("y") && !choose.equalsIgnoreCase("n")); //This was a long while loop with a lot of if and elses, thanks to SirPython's notice I changed it as he suggested.
if (choose.equalsIgnoreCase("n")) {
decideSymb = false;
}
long start = System.currentTimeMillis();
crack(password, decideSymb);
long end = System.currentTimeMillis();
long milliSecs = TimeUnit.MILLISECONDS.toSeconds(end - start);
System.out.println("The password is: " + newPass);
time(milliSecs);
System.exit(0);
}
private static void time(long milliSecs) { //I put this in a method rather than the Main method and changed it up as BenC and SirPython noted
long secs = milliSecs / 1000;
long mins = secs / 60;
long hours = mins / 60;
long days = hours / 24;
long years = days / 365;
days -= (years * 365);
hours -= (days * 24);
mins -= (hours * 60);
secs -= (mins * 60);
milliSecs -= (secs * 1000);
System.out.println("it took " + pluralFormat("year", years) + pluralFormat("day", days)
+ pluralFormat("hour", hours) + pluralFormat("min", mins) + pluralFormat("sec", secs)
+ pluralFormat("millisecond", milliSecs) + "to find the password");
}
private static String pluralFormat(String word, long value) { //This here was put as BenC noted to make my code more efficient
return Long.toString(value) + " " + word + (value > 1 ? "s" : "") + ", ";
}
private static void crack(String password, boolean decideSymb) {
if (decideSymb == true) {
chars = "0123456789#%&@aABbCcDdEeFfGgHh!IiJjKkLlMmNnOoPpQqRr$SsTtUuVvWwXxYyzZ"; //In my original code it started with 1 and now it starts with 0 as it is suppose to do.
}
for (int length = 2; length <= 15; length++) {
newPass = "";
newPass = repeatString("0", length);
int lastInd = length - 1;
while (!newPass.equals(password)) {
String end = repeatString("Z", newPass.length());
if (newPass.equals(end)) {
break;
}
int indInChars = chars.indexOf(newPass.charAt(lastInd));
if (indInChars < chars.length() && indInChars >= 0) {
boolean t = true;
int howManyZs = 0; //This will replace that last Zs that are in order with 0s then update the one in front +1 char. For Example abcZZZ will evaluate to abD000 and will go on.
while (t == true) {
if (newPass.charAt(newPass.length() - 1 - howManyZs) == 'Z') {
howManyZs++;
} else {
t = false;
}
}
String reset0s = "";
for (int l = 0; l < howManyZs; l++) {
reset0s += "0";
}
if (lastInd < newPass.length() - 1 && lastInd > 0) {
lastInd--;
indInChars = chars.indexOf(newPass.charAt(lastInd)) + 1;
newPass = newPass.substring(0, lastInd) + chars.charAt(indInChars)
+ newPass.substring(lastInd + 1);
} else if (newPass.length() - howManyZs == 1) {
newPass = chars.substring(chars.indexOf(newPass.charAt(0)) + 1,
chars.indexOf(newPass.charAt(0)) + 2) + reset0s;
} else if (newPass.length() - howManyZs > 1 && howManyZs != 0) {
newPass = newPass.substring(0, newPass.length() - 1 - howManyZs)
+ chars.substring(chars.indexOf(newPass.charAt(newPass.length() - 1 - howManyZs)) + 1,
chars.indexOf(newPass.charAt(newPass.length() - 1 - howManyZs)) + 2)
+ reset0s;
} else {
indInChars = chars.indexOf(newPass.charAt(lastInd)) + 1;
newPass = newPass.substring(0, lastInd) + chars.charAt(indInChars);
}
System.out.println(newPass);
}
}
if (newPass.equals(password)) {
break;
}
}
}
private static String repeatString(String s, int n) { //This here was put as BenC noted to make my code more efficient
StringBuilder sb = new StringBuilder(n);
while (n-- > 0) {
sb.append(s);
}
return sb.toString();
}
}
howManyZs
)... \$\endgroup\$a
and loop upwards by going tob
, thenabcZZZ
toabD000
and so on? \$\endgroup\$O(n^m)
in worst case, wheren
is the length of the password andm
is the length of the charset being used. (please correct me if I am wrong with the Big O notation) \$\endgroup\$