Java 生成词表
Java generate wordlist
我在这个主题上卡了大约 3 天,我想不出合适的算法。
那么你们能帮帮我吗?
我想用给定的字符集、最小和最大长度[=生成单词表16=]
给定 charset:abcdef min:2 max:5
结果:
aa
ab
ac
...
ffffd
ffffe
fffff
喜欢linux命令行crunch
。
但是有些事情,我需要在 for 循环中实现它,这与循环次数无关但很重要不调用任何用户创建的函数*。
喜欢:
for (...) {
// Password is ready!
pass = ...;
}
不喜欢:
pass = get_pass(...);
谢谢。
一种方法是使用库数组,它从给定的正则表达式创建字符串,如 Generex。使用 Generex,您的任务非常简单:
import com.mifmif.common.regex.Generex;
public class Example {
public static void main(String[] args) {
Generex gen = new Generex("[abcdef]{2,5}");
gen.getAllMatchedStrings().forEach(System.out::println);
}
}
输出:
aa
aaa
aaaa
aaaaa
aaaab
aaaac
aaaad
aaaae
aaaaf
...
...
ffffa
ffffb
ffffc
ffffd
ffffe
fffff
查看此 post 了解其他库,例如 generex using-regex-to-generate-strings-rather-than-match-them
我很确定这不是最好的解决方案,但它确实有效。
public static void main(String[] args) {
List<Character> charset = new ArrayList<>();
charset.add('a');
charset.add('b');
charset.add('c');
charset.add('d');
charset.add('e');
int min = 2;
int max = 5;
List<Integer> word = new ArrayList<>();
for (int len = min; len <= max; len++) {
word.clear();
for (int i = 0; i < len; i++) {
word.add(0);
}
while (word.get(0) < charset.size()) {
System.out.println(word.stream()
.map(e -> charset.get(e).toString())
.collect(Collectors.joining()));
word.set(len - 1, word.get(len - 1) + 1);
for (int i = len - 1; i > 0; i--) {
if (word.get(i).equals(charset.size())) {
word.set(i - 1, word.get(i - 1) + 1);
word.set(i, 0);
} else {
break;
}
}
}
}
}
另一种方法是将您的字符集解释为数字系统的数字,并将您想要的输出解释为所有 n 位数字。例如,在十进制系统中,我们有数字 0 到 9,所有两位数字(前导零)都是数字
00 - 99
三位数
000 - 999
等等。然而,在八进制系统中,您的数字将从
00 - 77
或来自
000 - 777
和二进制
00 - 11
或
000 - 111
如果我们现在将字符集中的字母替换为数字,即 a
替换为 0
,b
替换为 1
,c
替换为 2
...
输出中的 aaa
与 000
相同,fff
与 555
相同。这意味着任务是在基数六数字系统(字符集长度)中创建所有两位数、三位数、……、五位数字,并将数字转换回给定字符集中的字母。这种算法的起点可能是这样的:
public static void main(String[] args) {
String str = "abcdef";
//create a map which looks like {0=a, 1=b, 2=c, 3=d, 4=e, 5=f}
Map<Character,Character> map = new HashMap<>();
for(int i = 0; i <str.length(); i ++){
map.put((char)(i+'0'), str.charAt(i));
}
//convert numbers to string using //Integer.toString(int i, int radix)
//use String#format & String#replace to have a string representation with leading zeros
for(int n = 2; n <= 5; n++){
int maxValue = (int)Math.pow(str.length(), n);
for(int i = 0; i < maxValue; i++){
String temp = String.format("%"+n+"s", Integer.toString(i, str.length())).replace(' ', '0');
for(char c: map.keySet()){
temp = temp.replace(c, map.get(c));
}
System.out.println(temp);
}
}
}
我在这个主题上卡了大约 3 天,我想不出合适的算法。 那么你们能帮帮我吗?
我想用给定的字符集、最小和最大长度[=生成单词表16=]
给定 charset:abcdef min:2 max:5
结果:
aa
ab
ac
...
ffffd
ffffe
fffff
喜欢linux命令行crunch
。
但是有些事情,我需要在 for 循环中实现它,这与循环次数无关但很重要不调用任何用户创建的函数*。
喜欢:
for (...) {
// Password is ready!
pass = ...;
}
不喜欢:
pass = get_pass(...);
谢谢。
一种方法是使用库数组,它从给定的正则表达式创建字符串,如 Generex。使用 Generex,您的任务非常简单:
import com.mifmif.common.regex.Generex;
public class Example {
public static void main(String[] args) {
Generex gen = new Generex("[abcdef]{2,5}");
gen.getAllMatchedStrings().forEach(System.out::println);
}
}
输出:
aa
aaa
aaaa
aaaaa
aaaab
aaaac
aaaad
aaaae
aaaaf
...
...
ffffa
ffffb
ffffc
ffffd
ffffe
fffff
查看此 post 了解其他库,例如 generex using-regex-to-generate-strings-rather-than-match-them
我很确定这不是最好的解决方案,但它确实有效。
public static void main(String[] args) {
List<Character> charset = new ArrayList<>();
charset.add('a');
charset.add('b');
charset.add('c');
charset.add('d');
charset.add('e');
int min = 2;
int max = 5;
List<Integer> word = new ArrayList<>();
for (int len = min; len <= max; len++) {
word.clear();
for (int i = 0; i < len; i++) {
word.add(0);
}
while (word.get(0) < charset.size()) {
System.out.println(word.stream()
.map(e -> charset.get(e).toString())
.collect(Collectors.joining()));
word.set(len - 1, word.get(len - 1) + 1);
for (int i = len - 1; i > 0; i--) {
if (word.get(i).equals(charset.size())) {
word.set(i - 1, word.get(i - 1) + 1);
word.set(i, 0);
} else {
break;
}
}
}
}
}
另一种方法是将您的字符集解释为数字系统的数字,并将您想要的输出解释为所有 n 位数字。例如,在十进制系统中,我们有数字 0 到 9,所有两位数字(前导零)都是数字
00 - 99
三位数
000 - 999
等等。然而,在八进制系统中,您的数字将从
00 - 77
或来自
000 - 777
和二进制
00 - 11
或
000 - 111
如果我们现在将字符集中的字母替换为数字,即 a
替换为 0
,b
替换为 1
,c
替换为 2
...
aaa
与 000
相同,fff
与 555
相同。这意味着任务是在基数六数字系统(字符集长度)中创建所有两位数、三位数、……、五位数字,并将数字转换回给定字符集中的字母。这种算法的起点可能是这样的:
public static void main(String[] args) {
String str = "abcdef";
//create a map which looks like {0=a, 1=b, 2=c, 3=d, 4=e, 5=f}
Map<Character,Character> map = new HashMap<>();
for(int i = 0; i <str.length(); i ++){
map.put((char)(i+'0'), str.charAt(i));
}
//convert numbers to string using //Integer.toString(int i, int radix)
//use String#format & String#replace to have a string representation with leading zeros
for(int n = 2; n <= 5; n++){
int maxValue = (int)Math.pow(str.length(), n);
for(int i = 0; i < maxValue; i++){
String temp = String.format("%"+n+"s", Integer.toString(i, str.length())).replace(' ', '0');
for(char c: map.keySet()){
temp = temp.replace(c, map.get(c));
}
System.out.println(temp);
}
}
}