2015-04-25 85 views
0

我需要一个帮助来完成一个程序,将从选定的字符和长度(它需要支持一个很大的长度)生成一个单词列表。支持BigIntegers为巨大数字的Wordlist生成器

首先,您需要通过添加想要的长度(字长)和制作指定字符(字母表)的字符串来解决这个问题。

所以字的全部数量是:

long MAX_WORDS = (long) Math.pow(alphabet.length(), wordlength); 

事实上,我使它和它的工作(对于2首或66个字符的短字的例子)。

import java.math.BigInteger; 
public class wordlistgenenreg { 

public static void main(String[] args) { 
generate(); 
} 

private static void generate(){ 
int wordlength =2; 
String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~"; 
final long MAX_WORDS = (long) Math.pow(alphabet.length(), wordlength); 
final int RADIX = alphabet.length(); 

for (long i = 0; i < MAX_WORDS; i++) { 
    int[] indices = convertToRadix(RADIX, i, wordlength); 
    char[] word = new char[wordlength]; 
    for (int k = 0; k < wordlength; k++) {word[k] = alphabet.charAt(indices[k]);} 
    String fullword=new String(word); 
    System.out.println(fullword); 
} 

System.out.println("completed!"); 
} 

private static int[] convertToRadix(int radix, long number, int wordlength) { 
int[] indices = new int[wordlength]; 
for (int i = wordlength - 1; i >= 0; i--) { 
    if (number > 0) { 
     int rest = (int) (number % radix); 
     number /= radix; 
     indices[i] = rest; 
    } else { 
     indices[i] = 0; 
    } 

} 
return indices; 
} 
} 

但也有一个问题,当我想从66产生的64个字符一个非常大的字符串,因为:

MAX_WORDS = 66^64 = 282365657377235405270307754780751252031361330095689004197961218014051357270480550051149871489969454245263206971867136

所以我试图改变它以使其与BigInteger一起工作。但是我们的结果,我总是得到字符串:

“0000000000000000000000000000000000000000000000000000000000000000”

因此,有我没弄明白的一个问题。这是我上改变它的工作:

import java.math.BigInteger; 

public class wordlistgen { 

public static void main(String[] args) { 
    generate(); 
} 

private static void generate() { 
int wordlength = 64; 
String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~"; 
BigInteger max_words=new BigInteger("282365657377235405270307754780751252031361330095689004197961218014051357270480550051149871489969454245263206971867136"); 
final int RADIX = alphabet.length(); 
BigInteger plus=BigInteger.valueOf(1); 

for (BigInteger i = new BigInteger("0"); i.compareTo(max_words) <0; i.add(plus)) { 
    int[] indices = convertToRadix(RADIX, i, wordlength); 
    char[] word = new char[wordlength]; 
    for (int k = 0; k < wordlength; k++) {word[k] = alphabet.charAt(indices[k]);} 
    String fullword=new String(word); 
    System.out.println(fullword);   
} 
} 

private static int[] convertToRadix(int radix, BigInteger i2, int wordlength) { 
BigInteger zero=BigInteger.valueOf(0); 
BigInteger big_radix=BigInteger.valueOf(radix); 
int[] indices = new int[wordlength]; 
for (int i = wordlength - 1; i >= 0; i--) { 
    if (i2.compareTo(zero)==0) { 

     BigInteger rest =i2.remainder(big_radix); 
     BigInteger ab=i2.divide(big_radix); 
     i2=ab; 
     indices[i] = rest.intValue(); 
    } else { 
     indices[i] = 0; 
    } 
} 
return indices; 
} 
} 

回答

1

这是从您的原始版本if

if (number > 0) { 
    int rest = (int) (number % radix); 
    number /= radix; 
    indices[i] = rest; 
} else { 
    indices[i] = 0; 
} 

而且在BigInteger版相同if

if (i2.compareTo(zero)==0) { 

    BigInteger rest =i2.remainder(big_radix); 
    BigInteger ab=i2.divide(big_radix); 
    i2=ab; 
    indices[i] = rest.intValue(); 
} else { 
    indices[i] = 0; 
} 

正如你所看到的,在您的新if中,您在询问是否number == 0而不是number > 0。所以你总是在else

附注:您正在运行从0到您的max_words的循环。如果每次迭代只需要一纳秒即可完成,它仍然需要368788667672120349090672500612638816231217766896306723928560063188563281831044121479026746095987887263264265年。足够的时间让宇宙分解成完全的熵。我建议重新考虑你的算法。

+0

甚至使它> = 0它仍然是同样的问题。我知道这需要很长时间,但我认为这不过是一个月而已。你能帮我纠正它吗?我真的需要这样做。 –

+1

不,这要比一个月多得多,我给出的数字是我做过的计算的结果。这是几年。很多很多年。我无法帮助您使用您的算法,因为您的问题没有关于此作业的完整信息,我怀疑您误解了它。 – RealSkeptic