Quick tip: Random alphanumerics in Scala
Once in a while in my Java projects, I need a function that gives a pseudorandom String
of alphanumeric gibberish. For example, “UvYB8qDS2nhn9wu”. So I wrote a Java function for that:
public static String alphanumeric(int length) {
// TODO: Check length is greater than 0
char[] asciiChars = new char[length];
for (int i = 0; i < length; i++) {
char ch = '?';
if (RANDOM.nextBoolean()) {
ch = (char) (RANDOM.nextInt(10) + '0');
} else {
if (RANDOM.nextBoolean()) {
ch = (char) (RANDOM.nextInt(26) + 'A');
} else {
ch = (char) (RANDOM.nextInt(26) + 'a');
}
}
asciiChars[i] = ch;
}
return new String(asciiChars);
}
Could use some refactoring, but it’ll do for now. Here are a few outputs for that function with a length of ten: “CuWPo95A2m”, “306z9VAy55”, “9C7kRthD7q”, “a5895srg6K”.
In a Scala project, I wouldn’t need to write my own function for that. I can just put in an import for scala.util.Random
.
I deliberately named my function alphanumeric()
, the same as alphanumeric()
from scala.util.Random
. However, that Scala function doesn’t take a length parameter and it doesn’t return a String
. It returns a LazyList[Char]
(or a Stream[Char]
if you’re using Scala 2.8 or later but before 2.13).
That’s no problem. Just do take(10)
or whatever length you need on that to get… an uncomputed LazyList[Char]
? Yeah, I know, that can be kind of confusing. So use toArray()
, to get an Array[Char]
, such as [‘w’, ‘X’, ‘H’, ‘Y’, ‘s’, ‘x’, ‘H’, ‘i’, ‘5’, ‘8’].
I’m not sure if an Array[Char]
really is a Java char[]
under the hood, but for this purpose, we don’t actually need to worry about that. The Scala compiler will make whatever adjustments are needed to make sure the java.lang.String
constructor accepts the Array[Char]
, to give us, for example, “wXHYsxHi58”.
Putting it all together on the local Scala REPL:
scala> import scala.util.Random
import scala.util.Random
scala> new String(Random.alphanumeric.take(10).toArray)
res0: String = OfVabheJLU
scala> new String(Random.alphanumeric.take(10).toArray)
res1: String = kXqdKBC6ja
scala> new String(Random.alphanumeric.take(10).toArray)
res2: String = V08VTfor7s
scala> new String(Random.alphanumeric.take(10).toArray)
res3: String = 66FwtwvI1z
A new Stream[Char]
or LazyList[Char]
is created in each of these four examples. If you want to use a single one of those for several String
instances, you can, but maybe that’s a topic for another short article.