gpt4 book ai didi

java - 在 Java 中生成数百万个随机字符串

转载 作者:行者123 更新时间:2023-12-03 22:59:43 30 4
gpt4 key购买 nike

我想在 400 万到 5000 万之间随机生成数百万个密码。问题是处理器处理它所需的时间。
我想知道是否有解决方案可以在几秒钟内生成大量密码(最多 1 分钟,5000 万次)。
我现在已经这样做了,但我花了超过 3 分钟的时间(配置非常好,我想在小配置上运行它)。

private final static String policy = "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890";
private static List<String> names = new ArrayList<String>();


public static void main(String[] args) {
names.add("de");
init();
}



private static String generator(){
String password="";
int randomWithMathRandom = (int) ((Math.random() * ( - 6)) + 6);
for(var i=0;i<8;i++){
randomWithMathRandom = (int) ((Math.random() * ( - 6)) + 6);
password+= policy.charAt(randomWithMathRandom);
}
return password;
}

public static void init() {
for (int i = 0; i < 40000000; i++) {
names.add(generator());
}
}
顺便说一句,我不能拿现成的 list 。我认为最“昂贵”的时间浪费是输入列表。
我目前的配置:
锐龙 7 4800h
rtx 2600
固态硬盘
内存 3200MHZ
更新 :
我尝试了 20Millions,它显示了一个错误:java.lang.OutOfMemoryError 从线程“main”中的 UncaughtExceptionHandler 抛出

最佳答案

将 5000 万个密码作为 String 存储在内存中可能会导致问题,因为堆栈或堆可能会溢出。从这个角度来看,我认为我们能做的最好的事情是生成一组密码,将它们存储在一个文件中,生成下一个密码块,将它们附加到文件中......直到创建所需数量的密码。我编写了一个小程序,它生成长度为 String 的随机 32 s。作为字母表,我使用了 '!'(ASCII 值 33)和 '~'(ASCII 值 126)之间的所有 ASCII 字符。

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Random;
import java.util.concurrent.TimeUnit;

class Scratch {
private static final int MIN = '!';
private static final int MAX = '~';
private static final Random RANDOM = new Random();

public static void main(final String... args) throws IOException {
final Path passwordFile = Path.of("passwords.txt");
if (!Files.exists(passwordFile)) {
Files.createFile(passwordFile);
}
final DecimalFormat df = new DecimalFormat();
final DecimalFormatSymbols ds = df.getDecimalFormatSymbols();
ds.setGroupingSeparator('_');
df.setDecimalFormatSymbols(ds);
final int numberOfPasswordsToGenerate = 50_000_000;
final int chunkSize = 1_000_000;
final int passwordLength = 32;
int generated = 0;
int chunk = 0;
final long start = System.nanoTime();
while (generated < numberOfPasswordsToGenerate) {
final StringBuilder passwords = new StringBuilder();
for (
int index = chunk * chunkSize;
index < (chunk + 1) * chunkSize && index < numberOfPasswordsToGenerate;
++index) {
final StringBuilder password = new StringBuilder();
for (int character = 0; character < passwordLength; ++character) {
password.append(fetchRandomLetterFromAlphabet());
}
passwords.append(password.toString()).append(System.lineSeparator());
++generated;
if (generated % 500_000 == 0) {
System.out.printf(
"%s / %s%n",
df.format(generated),
df.format(numberOfPasswordsToGenerate));
}
}
++chunk;
Files.writeString(passwordFile, passwords.toString(), StandardOpenOption.APPEND);
}
final long consumed = System.nanoTime() - start;
System.out.printf("Done. Took %d seconds%n", TimeUnit.NANOSECONDS.toSeconds(consumed));
}

private static char fetchRandomLetterFromAlphabet() {
return (char) (RANDOM.nextInt(MAX - MIN + 1) + MIN);
}
}
在我的笔记本电脑上,该程序产生了良好的效果。它在大约 33 秒内完成,所有密码都存储在一个文件中。
该程序是概念验证,而不是生产就绪。例如,如果 password.txt 已经存在,则将附加内容。对我来说,运行一次后文件已经有 1.7 GB,所以请注意这一点。此外,生成的密码临时存储在 StringBuilder 中,这可能会带来安全风险,因为 StringBuilder 无法清除(即其内部存储器结构无法清零)。通过多线程运行密码生成可以进一步提高性能,但我将把它作为练习留给读者。
要使用问题中提供的字母表,我们可以删除静态字段 MINMAX ,定义一个新的静态字段 private static final char[] ALPHABET = "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890".toCharArray(); 并重新实现 fetchRandomLetterFromAlphabet 为:
  private static char fetchRandomLetterFromAlphabet() {
return ALPHABET[RANDOM.nextInt(ALPHABET.length)];
}
我们可以使用以下代码片段在恒定时间内从文件中读回 n -th(从 0 开始)密码:
final int n = ...;
final RandomAccessFile raf = new RandomAccessFile(passwordFile.toString(), "r");
final long start = System.nanoTime();
final byte[] bytes = new byte[passwordLength];

// byte-length of the first n passwords, including line breaks:
final int offset = (passwordLength + System.lineSeparator().toCharArray().length) * n;

raf.seek(offset); // skip the first n passwords
raf.read(bytes);

// reset to the beginning of the file, in case we want to read more passwords later:
raf.seek(0);

System.out.println(new String(bytes));

关于java - 在 Java 中生成数百万个随机字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66909107/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com