48

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.

cdeszaq
  • 30,869
  • 25
  • 117
  • 173
Robert Strauch
  • 12,055
  • 24
  • 120
  • 192

6 Answers6

78

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...

tim_yates
  • 167,322
  • 27
  • 342
  • 338
64
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)
Dónal
  • 185,044
  • 174
  • 569
  • 824
  • You can also use `@Grab(group='commons-lang', module='commons-lang', version='2.4')` and then `import org.apache.commons.lang.RandomStringUtils`in standard groovy script – Nicolas Zozol Jun 19 '12 at 13:07
  • `org.apache.commons.lang3.RandomStringUtils` now has `randomAlphaNumeric(int count)` – nerdherd Apr 17 '15 at 13:29
  • 1
    You may get "org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod org.apache.commons.lang.RandomStringUtils random int boolean boolean". Just follow these instructions: https://stackoverflow.com/a/39412951/1092815 – GabLeRoux Nov 07 '17 at 15:19
8

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);
user3215161
  • 81
  • 1
  • 1
6

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()}
Jonathan
  • 20,053
  • 6
  • 63
  • 70
vkrams
  • 7,267
  • 17
  • 79
  • 129
1

This code is pure Groovy I found on the web:

def key
def giveMeKey(){
    String alphabet = (('A'..'N')+('P'..'Z')+('a'..'k')+('m'..'z')+('2'..'9')).join() 
    def length = 6
     key = new Random().with {
           (1..length).collect { alphabet[ nextInt( alphabet.length() ) ] }.join()
             }
            return key
        }

The return string is good enough for local use:

BFx9PU
MkbRaE
FKvupt
gEwjby
Gk2kK6
uJmzLB
WRJGKL
RnSUQT
Abdelsalam Shahlol
  • 1,621
  • 1
  • 20
  • 31
  • So your example alphabet omits some characters because they might look similar in some fonts? lower case 'L' and the digit one. Along with upper case letter 'O' and the digit zero? Do I understand your reasoning? (I realize it's just an example.) – Wyck Oct 04 '18 at 02:52
  • And I don't understand what's the purpose of the `i=0;i<50;i++` loop? – Wyck Oct 04 '18 at 02:57
  • @Wyck The generated string contains a random number of uppercase, lowercase letters, and numbers. I've updated the answer and as you can see the output has a different set of upper, lower case letters and numbers. Looping statement is irrlevent to the answer. – Abdelsalam Shahlol Oct 04 '18 at 04:28
  • 2
    I had two problems getting this to work in Jenkins pipeline. First: I had to change `.join()` to `.join('')`. to avoid `hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.util.ArrayList.join() is applicable for argument types: () values: []`. And I had to rewrite without the `with` closure and just do `def rand = new Random()` and then use `rand.nextInt` to avoid `java.lang.NoSuchMethodError: No such DSL method 'nextInt' found among steps` – Wyck Oct 04 '18 at 15:19
1

Create a string with your alphabet, then do this 9 times:

  1. Create a random number
  2. Find the corresponding character in your alphabet.
  3. Append it to the result
Sjoerd
  • 74,049
  • 16
  • 131
  • 175