163

How can I create an array of 20 random bytes in Java?

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
novicePrgrmr
  • 18,647
  • 31
  • 81
  • 103

6 Answers6

315

Try the Random.nextBytes method:

byte[] b = new byte[20];
new Random().nextBytes(b);
maerics
  • 151,642
  • 46
  • 269
  • 291
  • 2
    worth adding a note that this is not crypto-safe. see [other answer](https://stackoverflow.com/a/34912596/1220560) if you need such. – morgwai Apr 14 '21 at 17:07
64

If you want a cryptographically strong random number generator (also thread safe) without using a third party API, you can use SecureRandom.

Java 8 (more secure than previous versions):

byte[] bytes = new byte[20];
SecureRandom.getInstanceStrong().nextBytes(bytes);

Java 6 & 7:

SecureRandom random = new SecureRandom();
byte[] bytes = new byte[20];
random.nextBytes(bytes);
isapir
  • 21,295
  • 13
  • 115
  • 116
DavidR
  • 6,622
  • 13
  • 56
  • 70
26

If you are already using Apache Commons Lang, the RandomUtils makes this a one-liner:

byte[] randomBytes = RandomUtils.nextBytes(20);

Note: this does not produce cryptographically-secure bytes.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
  • 11
    After doing some digging, RandomUtils uses Math.random() under the hood, not SecureRandom. Just wanted to make this explicit. – Evo510 May 26 '16 at 18:02
  • This method doesn't exist anymore. – Martijn Hiemstra Dec 21 '18 at 11:16
  • 1
    @MartijnHiemstra It does exist: https://github.com/apache/commons-lang/blob/master/src/main/java/org/apache/commons/lang3/RandomUtils.java#L72 – Duncan Jones Dec 21 '18 at 12:24
  • @DuncanJones I am using Spring boot 2 that uses Commons lang 3.7 and it has been removed. Viewing the source code shows that it has been commented out. So I wouldn't trust this code since an upgrade might render your code uncompilable. – Martijn Hiemstra Dec 21 '18 at 20:46
  • @MartijnHiemstra I checked the latest docs at: https://commons.apache.org/proper/commons-lang/apidocs/index.html and also the docs for version 3.7 at : https://commons.apache.org/proper/commons-lang/javadocs/api-3.7/org/apache/commons/lang3/RandomUtils.html They both seem to have the nextBytes method. Perhaps spring boot is not importing the correct libraries ? – Waleed Oct 28 '20 at 05:54
8

Java 7 introduced ThreadLocalRandom which is isolated to the current thread.

This is an another rendition of maerics's solution.

final byte[] bytes = new byte[20];
ThreadLocalRandom.current().nextBytes(bytes);
Community
  • 1
  • 1
Jin Kwon
  • 20,295
  • 14
  • 115
  • 184
  • 2
    Maybe some parentheses too many after the word `ThreadLocalRandom` ? Better: `ThreadLocalRandom.current().nextBytes(bytes);` – Erwin Bolwidt Jan 18 '16 at 07:26
4

Create a Random object with a seed and get the array random by doing:

public static final int ARRAY_LENGTH = 20;

byte[] byteArray = new byte[ARRAY_LENGTH];
new Random(System.currentTimeMillis()).nextBytes(byteArray);
// get fisrt element
System.out.println("Random byte: " + byteArray[0]);
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
1

For those wanting a more secure way to create a random byte array, yes the most secure way is:

byte[] bytes = new byte[20];
SecureRandom.getInstanceStrong().nextBytes(bytes);

BUT your threads might block if there is not enough randomness available on the machine, depending on your OS. The following solution will not block:

SecureRandom random = new SecureRandom();
byte[] bytes = new byte[20];
random.nextBytes(bytes);

This is because the first example uses /dev/random and will block while waiting for more randomness (generated by a mouse/keyboard and other sources). The second example uses /dev/urandom which will not block.

Tom Hage
  • 11
  • 1
  • You should only use this example if requirements demand timeliness over correctness, or in this case true randomness. /dev/urandom will not block if it can't create true randomness and will do the best it can. /dev/random will block until randomness is guaranteed. – DavidR Mar 31 '21 at 21:08