Генератор списков слов, поддерживающий BigIntegers для огромных номеров

Мне нужна помощь, чтобы завершить программу, которая будет генерировать список слов из выбранных символов и длины (он должен поддерживать большую длину).

Сначала вам нужно исправить это, добавив желаемую длину (длина слова) и составив строку из указанных символов (алфавит).

Итак, полное количество слов:

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 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~";
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;
}
}

но есть проблема, когда я хочу сгенерировать действительно большую строку из 64 символов из 66. Потому что:

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 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~";
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;
}

И то же самое if в BigInteger версия:

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 лет. Достаточно времени, чтобы вселенная распалась в полную энтропию. Я бы предложил переосмыслить ваш алгоритм.

Другие вопросы по тегам