How to Generate Random Strings Using Stream - Java
It is sometimes useful to create random Strings
, maybe as Session-ID for a web-service or an initial password after registration for an application. This can be easily achieved using Streams
.
First, we need to initialize a random number generator. To enhance security for the generated Strings, it is a good idea to use SecureRandom
.
private static final SecureRandom rng = new SecureRandom(SecureRandom.generateSeed(20));
//20 Bytes as a seed is rather arbitrary, it is the number used in the JavaDoc example
When creating random Strings
, we usually want them to use only certain characters (e.g. only letters and digits). Therefore we can create a method returning a boolean
which can later be used to filter the Stream
.
//returns true for all chars in 0-9, a-z and A-Z
boolean useThisCharacter(char c){
//check for range to avoid using all unicode Letter (e.g. some chinese symbols)
return c >= '0' && c <= 'z' && Character.isLetterOrDigit(c);
}
Next we can utilize the RNG to generate a random String of specific length containing the charset which pass our useThisCharacter
check.
public String generateRandomString(long length){
//Since there is no native CharStream, we use an IntStream instead
//and convert it to a Stream<Character> using mapToObj.
//We need to specify the boundaries for the int values to ensure they can safely be cast to char
Stream<Character> randomCharStream = rng.ints(Character.MIN_CODE_POINT, Character.MAX_CODE_POINT).mapToObj(i -> (char)i).filter(c -> this::useThisCharacter).limit(length);
//now we can use this Stream to build a String utilizing the collect method.
String randomString = randomCharStream.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString();
return randomString;
}
Notes[edit]
- Creating a
SecureRandom
is quite expensive, so it is best practice to only do this once and call one of itssetSeed()
methods from time to time to reseed it.