Generate random code java

Class Random

An instance of this class is used to generate a stream of pseudorandom numbers; its period is only 2 48 . The class uses a 48-bit seed, which is modified using a linear congruential formula. (See Donald E. Knuth, The Art of Computer Programming, Volume 2, Third edition: Seminumerical Algorithms , Section 3.2.1.)

If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers. In order to guarantee this property, particular algorithms are specified for the class Random . Java implementations must use all the algorithms shown here for the class Random , for the sake of absolute portability of Java code. However, subclasses of class Random are permitted to use other algorithms, so long as they adhere to the general contracts for all the methods.

The algorithms implemented by class Random use a protected utility method that on each invocation can supply up to 32 pseudorandomly generated bits.

Many applications will find the method Math.random() simpler to use.

Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using ThreadLocalRandom in multithreaded designs.

Instances of java.util.Random are not cryptographically secure. Consider instead using SecureRandom to get a cryptographically secure pseudo-random number generator for use by security-sensitive applications.

Источник

Java Random Number Generator – How to Generate Numbers with Math.random() and Convert to Integers

Sebastian Sigl

Sebastian Sigl

Java Random Number Generator – How to Generate Numbers with Math.random() and Convert to Integers

In many applications, you need random numbers. You might need to throw dice in video games, create a private cryptography key, or create a user’s temporary password.

All these applications depend on random number creation. It’s sometimes challenging to differentiate what to use when, and security is a deep topic. Without spending a few years digging into it, it’s hard to quickly understand the documentation about available implementations and pick the proper way for your use case.

Читайте также:  Java 8 update 321 64 bit

So in this tutorial, I’ll summarize the prominent use cases and how to choose the best-performing implementation based on your your Java code.

brainstorming---Frame-1--1-

In this article, you will learn:

  • How to generate integers, floats, and booleans,
  • How generate random numbers for performance-critical use cases,
  • How generate random numbers for security-critical use cases,
  • How numbers generators work,
  • The differences between pseudo random number generators and true random number generators,
  • How to use a seed to your advantage.

All the code examples are minimal, and you can find the complete source code on GitHub.

Constraints of Math.random()

Math.random did exist even before Java 6. It’s easy to access and still widely used. With Java 17, a new common interface called RandomGenerator is available, which consolidates all random generator implementations in the current Java SDK.

Math.random() nowadays simply delegates to Random().nextFloat() . But, it only returns a double . So it doesn’t allow you to request different types of numbers or generate numbers between ranges. It also doesn’t allow you to select from different implementations.

In the following sections, you will learn about a more flexible number generation and learn how to generate numbers optimized for efficiency or security.

Common Interface Since Java 17

With Java 17, a common interface is implemented by the available number generators in the Java SDK. You have methods available for all essential data types, and you can define the expected range you would like to generate numbers for:

RandomGenerator randomGenerator = new Random(); // generate int between 0 - 9 randomGenerator.nextInt(10); // generate int between 1 - 9 randomGenerator.nextInt(1, 9); // generate long between 1 - 9 randomGenerator.nextLong(1, 9); // generate float between 1 - 9 randomGenerator.nextFloat(1, 9); // generate double between 1 - 9 randomGenerator.nextDouble(1, 9); // generate random boolean randomGenerator.nextBoolean();

Performance Optimized Random Number Generation in a Single-Threaded Environment

For many non-security-relevant cases, you do not care how predictable your random number is. Usually, you just want to have a reliable distribution.

More performant implementations than Random are available if your application is single-threaded. One very efficient alternative is called SplittableRandom :

new SplittableRandom().nextInt();
SingleThreaded.Random 116528253,100 ops/s SingleThreaded.SplittableRandom 619630768,299 ops/s

SplittableRandom performs about 5 times faster than Random in a single-threaded environment.

Читайте также:  How to make discord bot with python

Additional advantages to Random() are deterministic behavior and splittable fork/join implementation. Summing up, you should prefer using SplittableRandom over Random in single-threaded environments.

Performance Optimized Random Number Generation in a Multi-Threaded Environment

High throughput applications leverage multiple threads. So you want to use a number generator which is made for parallel usage.

The implementation of Random is thread-safe but is relatively slow and slows down even more because of locks. Because SplittableRandom is not thread-safe, it’s not an alternative here.

But, you gain better performance by using ThreadLocalRandom in a multi-threaded environment. It uses SplittableRandom , but ensures performant and secure usage in multiple threads:

ThreadLocalRandom.current().nextInt();

The benchmark executed on a MacBook Pro comparing ThreadLocalRandom and Random generating numbers in parallel using 10 threads shows the following results:

MultiThreaded Random 8308724,791 ops/s MultiThreaded ThreadLocalRandom 3537955530,922 ops/s

As you can see, using ThreadLocalRandom is 425 times faster. ThreadLocalRandom is lock-free and, therefore, more performant than the thread-safe Random class.

Security Optimized Random Number Generation

The methods we just discussed are speedy and sufficient for most of your applications. But, they are creating so-called pseudo-random-generated numbers.

Instead of always creating a truly random number, they predict a new number based on the previously predicted number, which comes with a state and a severe problem of predictability.

Maybe you want to create long-living secrets for encryption, and you don’t want others, by any chance, to be able to predict the next generated token.

In Java, you have SecureRandom for more security-relevant use cases:

SecureRandom.getInstanceStrong().nextInt();

SecureRandom.getInstanceStrong() gives you a provider, which creates secure tokens. In many Linux systems, you use /dev/random , generating numbers based on the random noise of real devices.

But, if you don’t have enough random data being collected, so-called missing entropy, the execution can block and take an unexpectedly long time. Especially in machines with a lot of Docker containers, this can lead to a slow execution in practice.

As an alternative, new SecureRandom() does not block by default in case no entropy is available. It also uses a less secure way of number generation as a fallback.

How to Use Seeds to Your Advantage

By default, a pseudo number generator uses a random seed, which reflects the start values used to generate values. So a seed is quite handy for testing, as it gives you control over predictions and allows you to reset how numbers are created.

Читайте также:  Сумма чисел питон for

Until now, we haven’t talked about anything related to seeds.

@Test public void splittableRandomWithSeedIsDeterministic() < assertEquals(new SplittableRandom(9999).nextInt(), -788346102); >@Test public void randomWithSeedIsDeterministic()

This makes testing a lot easier. Otherwise, you would need to always mock dependencies.

Why Number Generation is Hard

Understanding why number generation is hard to get a sense of security is essential.

Engineers write code, which is eventually compiled into machine-readable code executed in a real processing unit (CPU). A CPU is built upon electronic circuits, which consist of logic gates.

Long story short, there is no real randomness you can create with a traditional computer because output requires some input and, by definition, that can not be random.

This means that you need some kind of true random input from the real world, like Thermal noise from a resistor. There are expensive hardware number generators that use real-world physics to give you a lot of capacity for random number creation.

Risks of Unsafe Random Number Generation

Although many protocols are secure by design, they are not if an attacker can predict encryption keys.

Nowadays, a lot of applications require true random number generation behind the scenes. Otherwise, attackers might be able to predict generated numbers and, by doing so, infiltrate applications.

For example, security-related processing breakthroughs based on quantum computing can be a real threat if suddenly attackers can solve encryptions in no time.

Summary

In this blog post, you learned how to generate numbers in Java efficiently. You also learned how to optimize towards performance or security, and you learned what a seed is and how it can be used.

Also, you should now understand the key differences between pseudo and truely random generated numbers, and you should be able to describe why secure random number generation is important.

I hope you enjoyed the article.

If you liked it and felt the need to give me a round of applause or just want to get in touch, follow me on Twitter.

References

Источник

Оцените статью