Groovy: Generate random string from given character set

Using Groovy, I'd like to generate a random sequence of characters from a given regular expression.

  • Allowed charaters are: [A-Z0-9]
  • Length of generated sequence: 9

Example: A586FT3HS

However, I can't find any code snippet which would help me. If using regular expressions is too complicated, I'll be fine defining the allowed set of characters manually.


Solution 1:

If you don't want to use apache commons, or aren't using Grails, an alternative is:

def generator = { String alphabet, int n ->
  new Random().with {
    (1..n).collect { alphabet[ nextInt( alphabet.length() ) ] }.join()
  }
}

generator( (('A'..'Z')+('0'..'9')).join(), 9 )

but again, you'll need to make your alphabet yourself... I don't know of anything which can parse a regular expression and extract out an alphabet of passing characters...

Solution 2:

import org.apache.commons.lang.RandomStringUtils

String charset = (('A'..'Z') + ('0'..'9')).join()
Integer length = 9
String randomString = RandomStringUtils.random(length, charset.toCharArray())

The imported class RandomStringUtils is already on the Grails classpath, so you shouldn't need to add anything to the classpath if you're writing a Grails app.

Update

If you only want alphanumeric characters to be included in the String you can replace the above with

String randomString = org.apache.commons.lang.RandomStringUtils.random(9, true, true)

Solution 3:

For SoupUI users:

def generator = { String alphabet, int n ->
  new Random().with {
    (1..n).collect { alphabet[ nextInt( alphabet.length() ) ] }.join()
  }
}
randomValue = generator( (('A'..'Z')+('0'..'9')+('a'..'z')).join(), 15 )
testRunner.getTestCase().setPropertyValue("randomNumber", randomValue);

Solution 4:

Here is a single line command/statement to generate random text string

print new Random().with {(1..9).collect {(('a'..'z')).join()[ nextInt((('a'..'z')).join().length())]}.join()}

or

def randText = print new Random().with {(1..9).collect {(('a'..'z')).join()[ nextInt((('a'..'z')).join().length())]}.join()}