简体   繁体   English

确保没有随机序列被无限期重复

[英]Ensuring No Random Sequence Is Repeated Indefinitely

I'm attempting to generate a random string of length X. I want to ensure that no two sequences are ever identically produced, even if this code is being run on multiple machines and at the same time. 我试图生成一个长度为X的随机字符串。我想确保即使两个代码同时在多台机器上运行,也不会完全相同地产生两个序列。

"list" is the list of characters I'm using, "min" and "max" are the range of indexes, and "length" is the desired length of the String. “列表”是我正在使用的字符的列表,“最小”和“最大”是索引的范围,“长度”是所需的String长度。

Currently, I am using System.nanoTime() as the seed for the Random object. 当前,我使用System.nanoTime()作为Random对象的种子。 While I realize it is likely improbable for 2 machines to run at the exact same time down to the nano second and produce the same output, I want to make this a foolproof solution. 虽然我意识到让两台机器精确地同时运行至纳秒级并产生相同的输出是不可能的,但我想使它成为一个万无一失的解决方案。

How can I increase the randomness of this code so that no 2 strings will ever be the same without increasing the length of the string or increasing the number of characters available to be included in the string? 如何增加此代码的随机性,以便在增加字符串长度或增加字符串中包含的字符数的情况下 ,没有两个字符串是相同的?

String seq = "";
for (int i = 0; i < length; i++)
    {
      Random rnd = new Random();
      rnd.setSeed(System.nanoTime());
      int randomNum = rnd.nextInt((max - min) + 1) + min;
      seq = seq + list[randomNum];
    }

return seq;

This is not possible in principle: if you generate a String with length n of k different characters there are exactly k^n possible Strings. 从原则上讲这是不可能的:如果生成的字符串长度为nk个不同的字符,则可能有k ^ n个字符串。 Once you generated as much Strings, repetitions will occur, in practice much earlier. 一旦生成了足够多的字符串,重复就会发生,实际上要早得多。

When running on a single machine, you might remember generated Strings and only output new ones, but on two machines without synchronization even this will not be possible. 在单台计算机上运行时,您可能会记住生成的字符串,并且仅输出新的字符串,但是在两台没有同步的计算机上,即使这样做也不可能。

Furthermore, taking system nanos into account will not help, since the same Strings might occur in different positions of the generated sequences. 此外,将系统纳秒考虑在内将无济于事,因为相同的字符串可能会出现在所生成序列的不同位置。

But if you are asking that the sequence of the generated Strings must differ for two machines, your solution is probably fine, but ... 但是,如果您要求两台机器的生成字符串的顺序必须不同,则您的解决方案可能很好,但是...

  • there might be a correlation between the boot times of the involved machines which can in turn increase the chance of a collision of System.nanoTime() . 所涉及机器的启动时间之间可能存在关联,这反过来又会增加System.nanoTime()发生冲突的机会。

  • As the Javadoc for System.nanoTime() says, the accuracy of the returned long might be worse than the precision, ie not every possible long value might be returned actually. 正如System.nanoTime()的Javadoc所说,返回的long的精度可能比精度差,即,并非实际上可能会返回所有可能的long值。

BTW, new Random() would have the same effect as your code, since System.nanoTime() is used internally for seeding in this case. 顺便说一句, new Random()与您的代码具有相同的效果,因为在这种情况下,内部使用System.nanoTime()进行播种。

You could use SecureRandom or the built-in UUID system. 您可以使用SecureRandom或内置的UUID系统。

The UUID library generates unique random strings for you. UUID库为您生成唯一的随机字符串。 (see https://docs.oracle.com/javase/7/docs/api/java/util/UUID.html ) (请参阅https://docs.oracle.com/javase/7/docs/api/java/util/UUID.html

Using UUIDs: 使用UUID:

import java.util.UUID;

public class GetRandString {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        String randString = uuid.toString();

        System.out.println("Random string: " + randString);
    }
}

You second option is SecureRandom ( https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html ). 第二个选项是SecureRandomhttps://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html )。

Another stackoverflow question answers how to generate a SecureRandom string: How to generate a SecureRandom string of length n in Java? 另一个stackoverflow问题回答了如何生成SecureRandom字符串: 如何在Java中生成长度为n的SecureRandom字符串?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM