java-穷举法破解密码——穷举法和递归法
问题+代码:生成一个长度是3的随机字符串,把这个字符串作为当做密码使用穷举法生成长度是3个字符串,匹配上述生成的密码要求: 分别使用多层for循环 和 递归解决上述问题Math.random()的使用及做题思路java.lang.Character.isLetterOrDigit(int codePoint)确定指定字符(Unicode代码点)是一个字母或数字。字符被确定是字母或数字,如果不是is
问题+代码:
-
生成一个长度是3的随机字符串,把这个字符串作为当做密码
-
使用穷举法生成长度是3个字符串,匹配上述生成的密码
要求: 分别使用多层for循环 和 递归解决上述问题
java.lang.Character.isLetterOrDigit(int codePoint)
确定指定字符(Unicode代码点)是一个字母或数字。
字符被确定是字母或数字,如果不是isLetter(codePoint) 也不是 isDigit(codePoint) 的字符,则返回true。
System.currentTimeMillis()计算方式
在开发过程中,通常很多人都习惯使用new Date()来获取当前时间。new Date()所做的事情其实就是调用了System.currentTimeMillis()。如果仅仅是需要或者毫秒数,那么完全可以使用System.currentTimeMillis()去代替new Date(),效率上会高一点。如果需要在同一个方法里面多次使用new Date(),通常性能就是这样一点一点地消耗掉,//获得系统的时间,单位为毫秒,转换为妙
//获得系统的时间,单位为毫秒,转换为妙
long totalMilliSeconds = System.currentTimeMillis();
long totalSeconds = totalMilliSeconds / 1000;
//求出现在的秒
long currentSecond = totalSeconds % 60;
//求出现在的分
long totalMinutes = totalSeconds / 60;
long currentMinute = totalMinutes % 60;
//求出现在的小时
long totalHour = totalMinutes / 60;
long currentHour = totalHour % 24;
//显示时间
System.out.println("总毫秒为: " + totalMilliSeconds);
System.out.println(currentHour + ":" + currentMinute + ":" + currentSecond + " GMT");
package Fengzhaung;
public class demoo2 {
//生成一个长度是3的随机字符串,把这个字符串作为当做密码
public String getPassword() {
char password[] = new char[3];
for (int i = 0; i < password.length; i++) {
while (true) {
char make = (char) (Math.random() * (122 - 48 + 1) + 48); //48-122
if (Character.isLetterOrDigit(make)) {//如果是字母或者数字
password[i] = make;
break;
}
}
}
return new String(password);
}
private String password = getPassword();
public void forMethod() {//使用for循环穷举
// 使用穷举法生成长度是3个字符串,匹配上述生成的密码
long start = System.currentTimeMillis(); //获取开始时间
char password[] = new char[this.password.length()];
boolean flag = true;
while (flag) {
for (int i = '0'; i <= 'z'; i++) {
for (int j = '0'; j <= 'z'; j++) {
for (int z = '0'; z <= 'z'; z++) {
if (!Character.isLetterOrDigit(i) || !Character.isLetterOrDigit(j) || !Character.isLetterOrDigit(z))
//三个不能有一个是false,既不能不是字母或者数字
continue;
password[0] = (char) i;
password[1] = (char) j;
password[2] = (char) z;
if (String.valueOf(password).equals(this.password)) {
//如果password字符串数组转为字符串 与equals this.password 密码比较
System.out.println("密码已经找到:" + String.valueOf(password));
long end = System.currentTimeMillis();//获取结束时间
System.out.printf("使用for循环穷举法耗费的时间是:%d ms %n", (end - start));
flag = false;
}
}
}
}
}
}
//->放外面是为了让isreturn初始化为false但是可以修改,避免方法的递归使得每次isreturn都初始化为false变得无法修改
boolean isreturn = false; //用于程序的结束return
public void diguiMethod(char[] random, int index) { //使用递归法穷举
long start = System.currentTimeMillis(); //开始时间
for (int i = '0'; i <= 'z'; i++) {
if (!Character.isLetterOrDigit(i))
continue;
random[index] = (char) i; //把字符存入random字符串数组中
if (index < random.length - 1) {//如果数组没有填满则递归,进入套娃
if (isreturn)
//判断结束语句应该放这里,因为第一个(套娃)递归结束之后
// 会回到进入递归的方法这里也就是for循环里面,遇到return结束上一个套娃,直到全部结束
return;
diguiMethod(random, index + 1);
} else if (String.valueOf(random).equals(this.password)) {
System.out.println();
System.out.println("密码已经找到:" + String.valueOf(random));
long end = System.currentTimeMillis();
System.out.format("使用递归穷举法耗费的时间是:%d ms %n", (end - start));
isreturn = true; //用于结束全部的方法
return; //结束该递归(套娃)方法
}
}
}
public static void main(String[] args) {
demoo2 demoo2 = new demoo2();
System.out.println("随机三位密码是" + demoo2.password);
System.out.println();
demoo2.forMethod();
demoo2.diguiMethod(new char[3], 0);
}
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)