78

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?

Chris
  • 20,959
  • 25
  • 70
  • 96

19 Answers19

145

To generate a random char in a-z:

Random r = new Random();
char c = (char)(r.nextInt(26) + 'a');
dogbane
  • 254,755
  • 72
  • 386
  • 405
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
  • 364,035
  • 124
  • 554
  • 617
  • 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
82

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);
Sahil Chhabra
  • 9,711
  • 4
  • 62
  • 62
Josema
  • 1,747
  • 1
  • 16
  • 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
  • 14,278
  • 4
  • 52
  • 73
  • 1
    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
10
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

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

This one works as well.

Ricardo Vallejo
  • 131
  • 1
  • 4
4

In following 97 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 above 3 number for a , b , c or d and if u want all character like a to z then you replace 3 number to 25.

duggu
  • 37,191
  • 12
  • 114
  • 111
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
  • 31,574
  • 9
  • 80
  • 113
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 chars, 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 cheched by slice

EDIT

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);
dfa
  • 111,277
  • 30
  • 187
  • 226
  • 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
  • 168
  • 3
  • 9
0

polygenelubricants' answer is also a good solution if you only want to generate Hex 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;
}
Jolta
  • 2,578
  • 1
  • 29
  • 41
schnatterer
  • 6,979
  • 7
  • 57
  • 76
0

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

manuel
  • 174
  • 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,401
  • 2
  • 19
  • 37
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
  • 101
  • 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
  • 350
  • 3
  • 19
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,701
  • 6
  • 36
  • 67
-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
  • 125,519
  • 44
  • 317
  • 399
Andrei Ciobanu
  • 12,164
  • 22
  • 80
  • 116
-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
  • 753
  • 1
  • 6
  • 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
  • 19,685
  • 7
  • 57
  • 70
  • 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