【发布时间】:2010-12-25 21:47:30
【问题描述】:
我有点困惑,如何做到这一点。我知道我可以使用 Random 类来生成随机数,但是我不知道如何指定和生成 8 字节数?
谢谢, 武克
【问题讨论】:
标签: java
我有点困惑,如何做到这一点。我知道我可以使用 Random 类来生成随机数,但是我不知道如何指定和生成 8 字节数?
谢谢, 武克
【问题讨论】:
标签: java
您应该注意,java.util.Random 类使用 48 位种子,因此并非所有 8 字节值(64 位序列)都可以使用该类生成。由于这个限制,我建议你在这种情况下使用SecureRandom 和nextBytes method。
用法与java.util.Random解决方案非常相似。
SecureRandom sr = new SecureRandom();
byte[] rndBytes = new byte[8];
sr.nextBytes(rndBytes);
以下是 48 位种子不够用的原因:
Random 类实现了一个伪随机生成器,这意味着它是确定性的。Random 的当前“状态”决定了未来的位序列。Random 对象中读取。基于@Peter Lawreys excellent answer(它值得更多的支持!):这是使用 2×48 位种子创建 java.util.Random 的解决方案。也就是说,java.util.Random 实例能够生成所有可能的longs。
class Random96 extends Random {
int count = 0;
ExposedRandom extra48bits;
class ExposedRandom extends Random {
public int next(int bits) { // Expose the next-method.
return super.next(bits);
}
}
@Override
protected int next(int bits) {
if (count++ == 0)
extra48bits = new ExposedRandom();
return super.next(bits) ^ extra48bits.next(bits) << 1;
}
}
【讨论】:
FF FF 与 FF AA 一样可能。它应该是独立的,但由于它是伪随机的,它不是完全独立的。也就是说,给定序列中过去的 7 个字节,第 8 个字节不能取所有可能的值。下一个字节可能独立于其前一个字节,但不独立于其过去的 7 个字节。
我同意 @aioobe 关于 Random 使用 48 位种子的观点。 SecureRandom 是一个更好的解决方案。但是,要回答 OP 关于如何使用 Random 类并仍然允许所有可能的 8 字节值的问题,就是定期重置种子。
int counter = 0;
Random rand = new Random();
Random rand2 = new Random();
if (++counter == 0) rand = new Random(); // reset every 4 billion values.
long randomLong = rand.nextLong() ^ rand2.nextLong() << 1;
Random 只允许 2^47 长值的序列。通过使用两个随机生成器,一个在序列中不断跳动,你得到两个 2^47 * 2^47 的可能值。
【讨论】:
可以使用长度为 8 的字节数组来完成:
byte[] byteArray = new byte[8];
random.nextBytes(byteArray);
或使用long 类型的变量(表示8 字节数字):
long randomLong = random.nextLong();
【讨论】:
Randoms(具有不同的“起点”)可以。我说的对吗?
Random 类(或使用 2 个随机实例,尽管分布不是很均匀),直到确实有必要从 2^64 范围内生成公平值。只是因为它是众所周知且经常使用的类。
java.util.Random 实例。 (基于 Peter Lawreys 的回答。)
long 类型是一个 8 字节有符号整数,所以 Random.nextLong() 似乎可以满足您的需求。或者,如果您需要一个字节数组作为结果:
byte[] result = new byte[8];
Random.nextBytes(result);
【讨论】:
Random 类无法生成所有可能的 long。
对代码here稍作调整:
import java.util.Random;
/** Generate 10 random integers in the range 0..99. */
public final class RandomByte {
public static final void main(String... aArgs){
log("Generating 10 random integers in range 0..255.");
//note a single Random object is reused here
Random randomGenerator = new Random();
for (int idx = 1; idx <= 10; ++idx){
int randomInt = randomGenerator.nextInt(256);
// int randomInt = randomGenerator.nextBytes(256);
log("Generated : " + randomInt);
}
log("Done.");
}
private static void log(String aMessage){
System.out.println(aMessage);
}
}
【讨论】:
Random 类无法生成所有可能的 8 字节值。