2015-04-25 86 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