在 Java 中生成 8 字节数字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4531799/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generate 8-byte number in Java
提问by Vuk
I'm a little bit confused, how to do this. I know I can use Random class to generate random numbers, but I don't know how to specify and generate 8-byte number?
我有点困惑,如何做到这一点。我知道我可以使用 Random 类来生成随机数,但我不知道如何指定和生成 8 字节数?
Thanks, Vuk
谢谢,武克
采纳答案by aioobe
You should note that the java.util.Random
class uses a 48-bit seed, so not all 8-byte values (sequences of 64 bits) can be generated using this class. Due to this restriction I suggest you use SecureRandom
and the nextBytes
methodin this situation.
您应该注意java.util.Random
该类使用 48 位种子,因此并非所有 8 字节值(64 位序列)都可以使用此类生成。由于这个限制,我建议你在这种情况下使用SecureRandom
和nextBytes
方法。
The usage is quite similar to the java.util.Random
solution.
用法与java.util.Random
解决方案非常相似。
SecureRandom sr = new SecureRandom();
byte[] rndBytes = new byte[8];
sr.nextBytes(rndBytes);
Here is the reason why a 48-bit seed is not enough:
以下是 48 位种子不够用的原因:
- The
Random
class implements a pseudo random generator which means that it is deterministic. - The current "state" of the
Random
determines the future sequence of bits. - Since it has 248states, it can't have more than 248possible future sequences.
- Since an 8-byte value has 264different possibilities, some of these possibilities will never be read from the
Random
object.
- 所述
Random
类实现一个伪随机数发生器,这意味着它是确定的。 - 的当前“状态”
Random
决定了未来的位序列。 - 因为它有 2 48个状态,所以它不能有超过 2 48 个可能的未来序列。
- 由于一个 8 字节的值有 2 64种不同的可能性,因此这些可能性中的一些永远不会从
Random
对象中读取。
Based on @Peter Lawreys excellent answer(it deserves more upvotes!): Here is a solution for creating a java.util.Random
with 2×48-bit seed. That is, a java.util.Random
instance capable of generating all possible long
s.
基于@Peter Lawreys 的出色回答(值得更多赞!):这是创建java.util.Random
2×48 位种子的解决方案。也就是说,一个java.util.Random
实例能够生成所有可能的long
s。
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;
}
}
回答by Peter Lawrey
I agree with @aioobe' point about Random using a 48-bit seed. SecureRandom is a better solution. However to answer the OP's questions of how to use the Random class and still allow for all possible 8-byte values is to reset the seed periodically.
我同意@aioobe 关于使用 48 位种子的 Random 的观点。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 only allows a sequence of 2^47 long values. By using two Random generators, one which keeps jumping around in the sequence, you get two 2^47 * 2^47 possible values. The use of << 1 is to avoid the impact of having both randoms having the same seed (in which case ^ would produce 0 for 4 billion values in a row)
Random 只允许 2^47 个长值的序列。通过使用两个随机生成器,一个在序列中不断跳跃,你会得到两个 2^47 * 2^47 的可能值。<< 1 的使用是为了避免具有相同种子的两个随机数的影响(在这种情况下, ^ 将连续 40 亿个值产生 0)
回答by Roman
It can be done either with byte array of length 8:
可以使用长度为 8 的字节数组来完成:
byte[] byteArray = new byte[8];
random.nextBytes(byteArray);
or with a variable of type long
(which represents 8-byte numbers):
或使用类型变量long
(代表 8 字节数字):
long randomLong = random.nextLong();
回答by Michael Borgwardt
The long
type is an 8 byte signed integer, so Random.nextLong()
seems to do what you want. Or if you need a byte array as result:
该long
类型是一个 8 字节有符号整数,所以Random.nextLong()
似乎可以做你想做的。或者,如果您需要一个字节数组作为结果:
byte[] result = new byte[8];
Random.nextBytes(result);
回答by Mateen Ulhaq
A little adjusting from the code 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);
}
}
Some further reading: Math.random() versus Random.nextInt(int)