85

Does Java have any functionality to generate random characters or strings? Or must one simply pick a random integer and convert that integer's ASCII code to a character?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris
  • 21,549
  • 25
  • 71
  • 99

21 Answers21

150

To generate a random char in a-z:

Random r = new Random();
char c = (char)(r.nextInt(26) + 'a');
dogbane
  • 266,786
  • 75
  • 396
  • 414
101

There are many ways to do this, but yes, it involves generating a random int (using e.g. java.util.Random.nextInt) and then using that to map to a char. If you have a specific alphabet, then something like this is nifty:

    import java.util.Random;

    //...

    Random r = new Random();

    String alphabet = "123xyz";
    for (int i = 0; i < 50; i++) {
        System.out.println(alphabet.charAt(r.nextInt(alphabet.length())));
    } // prints 50 random characters from alphabet

Do note that java.util.Random is actually a pseudo-random number generator based on the rather weak linear congruence formula. You mentioned the need for cryptography; you may want to investigate the use of a much stronger cryptographically secure pseudorandom number generator in that case (e.g. java.security.SecureRandom).

polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
  • Thanks, that actually is a concise solution if you want generate a defined set of characters. For the whole alphabet [dogbane's answer](http://stackoverflow.com/a/2627801/1845976) is a bit shorter. You could increase efficiency and readability a bit by using arrays. See my [hex example](http://stackoverflow.com/a/20345686/1845976). – schnatterer Dec 03 '13 at 08:08
87

You could also use the RandomStringUtils from the Apache Commons project:

Dependency:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.8.1</version>
</dependency>

Usages:

RandomStringUtils.randomAlphabetic(stringLength);
RandomStringUtils.randomAlphanumeric(stringLength);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Josema
  • 1,807
  • 1
  • 17
  • 15
16
private static char rndChar () {
    int rnd = (int) (Math.random() * 52); // or use Random or whatever
    char base = (rnd < 26) ? 'A' : 'a';
    return (char) (base + rnd % 26);

}

Generates values in the ranges a-z, A-Z.

Peter Walser
  • 15,208
  • 4
  • 51
  • 78
  • 2
    How exactly does `(char) (base + rnd % 26)` work? Is it because adding a char to an int converts the char into its ASCII number? – Lèse majesté Apr 17 '13 at 11:12
  • 3
    @Lèsemajesté - Yep that's why. Each `char` is also implicitly convertible to an int, so 'a' can be treated as an integer value (97), and then offsetting by say 3 will yield 100 which when converted back to a `char` is 'd'. – Matt Mitchell May 27 '13 at 02:31
13
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

char letter = abc.charAt(rd.nextInt(abc.length()));

This one works as well.

Ricardo Vallejo
  • 161
  • 1
  • 4
4

In the following 97 is the ASCII value of small "a".

public static char randomSeriesForThreeCharacter() {
    Random r = new Random();
    char random_3_Char = (char) (97 + r.nextInt(3));
    return random_3_Char;
}

In the above, 3 is the number for a, b, c or d and if you want all characters, like a to z, then you replace 3 number to 25.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
duggu
  • 37,851
  • 12
  • 116
  • 113
  • This is close to incomprehensible. Can you [fix it](https://stackoverflow.com/posts/14021385/edit)? (But *** *** *** *** *** ***[without](https://meta.stackexchange.com/a/131011)*** *** *** *** *** *** "Edit:", "Update:", or similar - the answer should appear as if it was written today) – Peter Mortensen Jun 11 '23 at 17:16
1

You could use generators from the Quickcheck specification-based test framework.

To create a random string use anyString method.

String x = anyString();

You could create strings from a more restricted set of characters or with min/max size restrictions.

Normally you would run tests with multiple values:

@Test
public void myTest() {
  for (List<Integer> any : someLists(integers())) {
    //A test executed with integer lists
  }
}
Thomas Jung
  • 32,428
  • 9
  • 84
  • 114
1

Using dollar:

Iterable<Character> chars = $('a', 'z'); // 'a', 'b', c, d .. z

Given chars, you can build a "shuffled" range of characters:

Iterable<Character> shuffledChars = $('a', 'z').shuffle();

Then taking the first n characters, you get a random string of length n. The final code is simply:

public String randomString(int n) {
    return $('a', 'z').shuffle().slice(n).toString();
}

NB: the condition n > 0 is checked by slice.

As Steve correctly pointed out, randomString uses at most once each letter. As workaround, you can repeat the alphabet m times before call shuffle:

public String randomStringWithRepetitions(int n) {
    return $('a', 'z').repeat(10).shuffle().slice(n).toString();
}

Or just provide your alphabet as String:

public String randomStringFromAlphabet(String alphabet, int n) {
    return $(alphabet).shuffle().slice(n).toString();
}

String s = randomStringFromAlphabet("00001111", 4);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dfa
  • 114,442
  • 31
  • 189
  • 228
  • 1
    This will use each character at most once in the random string. This may not be what the OP needs. – Steve McLeod Apr 13 '10 at 08:08
  • @Steve: thanks, I've fixed my answer and extended the library http://bitbucket.org/dfa/dollar/changeset/4c26ccf9464e/ – dfa Apr 13 '10 at 09:30
1

This is a simple but useful discovery. It defines a class named RandomCharacter with 5 overloaded methods to get a certain type of character randomly. You can use these methods in your future projects.

    public class RandomCharacter {
    /** Generate a random character between ch1 and ch2 */
    public static char getRandomCharacter(char ch1, char ch2) {
        return (char) (ch1 + Math.random() * (ch2 - ch1 + 1));
    }

    /** Generate a random lowercase letter */
    public static char getRandomLowerCaseLetter() {
        return getRandomCharacter('a', 'z');
    }

    /** Generate a random uppercase letter */
    public static char getRandomUpperCaseLetter() {
        return getRandomCharacter('A', 'Z');
    }

    /** Generate a random digit character */
    public static char getRandomDigitCharacter() {
        return getRandomCharacter('0', '9');
    }

    /** Generate a random character */
    public static char getRandomCharacter() {
        return getRandomCharacter('\u0000', '\uFFFF');
    }
}

To demonstrate how it works let's have a look at the following test program displaying 175 random lowercase letters.

public class TestRandomCharacter {
    /** Main method */
    public static void main(String[] args) {
        final int NUMBER_OF_CHARS = 175;
        final int CHARS_PER_LINE = 25;
        // Print random characters between 'a' and 'z', 25 chars per line
        for (int i = 0; i < NUMBER_OF_CHARS; i++) {
            char ch = RandomCharacter.getRandomLowerCaseLetter();
            if ((i + 1) % CHARS_PER_LINE == 0)
                System.out.println(ch);
            else
                System.out.print(ch);
        }
    }
}

and the output is:

enter image description here

if you run one more time again:

enter image description here

I am giving credit to Y.Daniel Liang for his book Introduction to Java Programming, Comprehensive Version, 10th Edition, where I cited this knowledge from and use in my projects.

Note: If you are unfamiliar with overloaded methhods, in a nutshell Method Overloading is a feature that allows a class to have more than one method having the same name, if their argument lists are different.

Gulbala Salamov
  • 198
  • 3
  • 9
0

polygenelubricants' answer is also a good solution if you only want to generate hexadecimal values:

/** A list of all valid hexadecimal characters. */
private static char[] HEX_VALUES = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F' };

/** Random number generator to be used to create random chars. */
private static Random RANDOM = new SecureRandom();

/**
 * Creates a number of random hexadecimal characters.
 *
 * @param nValues the amount of characters to generate
 *
 * @return an array containing <code>nValues</code> hex chars
 */
public static char[] createRandomHexValues(int nValues) {
    char[] ret = new char[nValues];
    for (int i = 0; i < nValues; i++) {
        ret[i] = HEX_VALUES[RANDOM.nextInt(HEX_VALUES.length)];
    }
    return ret;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
schnatterer
  • 7,525
  • 7
  • 61
  • 80
0

Take a look at Java Randomizer class. I think you can randomize a character using the randomize(char[] array) method.

manuel
  • 184
  • 1
  • 2
  • 15
  • @manuel, I think then we need to install the Liefra jar file, it doesnot come with the default one – gmhk Apr 13 '10 at 04:18
0

My propose for generating random string with mixed case like: "DthJwMvsTyu".
This algorithm based on ASCII codes of letters when its codes a-z (97 to 122) and A-Z (65 to 90) differs in 5th bit (2^5 or 1 << 5 or 32).

random.nextInt(2): result is 0 or 1.

random.nextInt(2) << 5: result is 0 or 32.

Upper A is 65 and lower a is 97. Difference is only on 5th bit (32) so for generating random char we do binary OR '|' random charCaseBit (0 or 32) and random code from A to Z (65 to 90).

public String fastestRandomStringWithMixedCase(int length) {
    Random random = new Random();
    final int alphabetLength = 'Z' - 'A' + 1;
    StringBuilder result = new StringBuilder(length);
    while (result.length() < length) {
        final char charCaseBit = (char) (random.nextInt(2) << 5);
        result.append((char) (charCaseBit | ('A' + random.nextInt(alphabetLength))));
    }
    return result.toString();
}
Prags
  • 2,457
  • 2
  • 21
  • 38
0

Here is the code to generate random alphanumeric code. First you have to declare a string of allowed characters what you want to include in random number.and also define max length of string

 SecureRandom secureRandom = new SecureRandom();
 String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
    StringBuilder generatedString= new StringBuilder();
    for (int i = 0; i < MAXIMUM_LENGTH; i++) {
        int randonSequence = secureRandom .nextInt(CHARACTERS.length());
        generatedString.append(CHARACTERS.charAt(randonSequence));
    }

Use toString() method to get String from StringBuilder

Abhishek Jha
  • 111
  • 1
  • 3
0

In fact mentioned methods don't generate real random char. To generate real random char you should give it a random seed! in example time in millisecond. this code generate 10 random char and then Convert it to String:

import java.util.Random;
public class MyClass {
    public static void main() {

     String randomKey;

    char[] tempArray={0,0,0,0,0,0,0,0,0,0};  //ten characters

    long seed=System.currentTimeMillis();
    Random random=new Random(seed);
    for (int aux=0; aux<10;aux++){

        tempArray[aux]=(char) random.nextInt(255);
        System.out.println(tempArray[aux]);
    }

    randomKey=String.copyValueOf(tempArray);  


      System.out.println(randomKey);
    }
}
Farshid Ahmadi
  • 437
  • 6
  • 23
0

I use this:

char uppercaseChar = (char) ((int)(Math.random()*100)%26+65);

char lowercaseChar = (char) ((int)(Math.random()*1000)%26+97);
0

java.util.Random is the more effective one I have tried out so far, having a precision of 98.65% uniqueness. I have provided bellow some tests which generate 10000 batches of a hundred 2 alphanumeric chars strings and calculates the average.

Other random tools were RandomStringUtils from commons.lang3 and java.util.Math.

public static void main(String[] args) {
    int unitPrintMarksTotal = 0;
    for (int i = 0; i < 10000; i++) {
        unitPrintMarksTotal += generateBatchOfUniquePrintMarks(i);
    }

    System.out.println("The precision across 10000 runs with 100 item batches is: " + (float) unitPrintMarksTotal / 10000);
}

private static int generateBatchOfUniquePrintMarks(int batch) {
    Set<String> printMarks = new HashSet<>();
    for (int i = 0; i < 100; i++) {
        printMarks.add(generatePrintMarkWithJavaUtil());
    }

    System.out.println("Batch " + batch + " Unique number of elements is " + printMarks.size());

    return printMarks.size();
}

// the best so far => 98.65
// with 3 chars => 99.98
// with 4 chars => 99.9997
private static String generatePrintMarkWithJavaUtil() {
    int leftLimit = 48; // numeral '0'
    int rightLimit = 122; // letter 'z'
    int targetStringLength = 2;
    String printMark;
    do {
        printMark = new Random().ints(leftLimit, rightLimit + 1)
                .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
                .limit(targetStringLength)
                .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
                .toString();
    } while (!isValid(printMark));

    return printMark;
}

// 95.46
private static String generatePrintMarkWithCommonsLang3() {
    String printMark;
    do {
        printMark = RandomStringUtils.randomAlphanumeric(2).toUpperCase();
    } while (!isValid(printMark));

    return printMark;
}

// 95.92
private static String generatePrintMarkWithMathRandom() {
    final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    StringBuilder printMark;
    do {
        printMark = new StringBuilder();
        int i = (int) (Math.random() * ALPHA_NUMERIC_STRING.length());
        printMark.append(ALPHA_NUMERIC_STRING.charAt(i));
        int j = (int) (Math.random() * ALPHA_NUMERIC_STRING.length());
        printMark.append(ALPHA_NUMERIC_STRING.charAt(j));
    } while (!isValid(printMark.toString()));

    return printMark.toString();
}

private static boolean isValid(final String printMark) {
    return true;
}
aurelius
  • 3,946
  • 7
  • 40
  • 73
0

I simply want to tell you to use UUID.randomUUID() and toString() as its simplest way i also used

NSV.
  • 65
  • 10
0
public static String getRandomNumberOfString(int number) {
        Random r = new Random();
        String randomString = "";
        String randomValue = "123456789 $#^&*()!~ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        for (int i = 0; i < number; i++) {
            randomString = randomString + randomValue.charAt(r.nextInt(randomValue.length()));
        }
        System.out.println("Length"+  randomString.length());
        System.out.println("String "+  randomString);
        return randomString;
}


getRandomNumberOfString(2000);
Suresh
  • 1
  • 2
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – LinFelix Jun 20 '23 at 09:30
-1

If you don't mind adding a new library in your code you can generate characters with MockNeat (disclaimer: I am one of the authors).

MockNeat mock = MockNeat.threadLocal();

Character chr = mock.chars().val();
Character lowerLetter = mock.chars().lowerLetters().val();
Character upperLetter = mock.chars().upperLetters().val();
Character digit = mock.chars().digits().val();
Character hex = mock.chars().hex().val(); 
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Andrei Ciobanu
  • 12,500
  • 24
  • 85
  • 118
-1
public static void  main(String[] args) {

  //  System.out.println("Enter a number to changeit at char  ");
    Random random = new Random();

    int x = random.nextInt(26)+65;    //0  to 25
    System.out.println((char)x);
}
foucdeg
  • 815
  • 1
  • 7
  • 24
ArsamP
  • 1
  • 1
    Although this code might solve the problem, a good answer should also explain what it does and how it helps? – Suraj Kumar Mar 26 '20 at 12:42
  • an alphabet ascii code for Char A is 25 and go ahed , first line of the code generate a random number between 25 and 90 and second line gona cast that number to char for example if it generate 25 second line convert it to A . – ArsamP Mar 27 '20 at 11:27
-2
   Random randomGenerator = new Random();

   int i = randomGenerator.nextInt(256);
   System.out.println((char)i);

Should take care of what you want, assuming you consider '0,'1','2'.. as characters.

ring bearer
  • 20,383
  • 7
  • 59
  • 72
  • 1
    This is most likely not what was intended, because in that range you include a whole number of control characters which are very unlikely to be expected. – Joachim Sauer Apr 13 '10 at 07:20