Chris
Chris

Reputation: 22237

Is there functionality to generate a random character in Java?

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?

Upvotes: 88

Views: 367538

Answers (22)

steve
steve

Reputation: 1169

The accepted, highest voted and my other answers only generate a subset of the normal printable chars. Several support a user-defined set of chars which is nice. But I simply want any printable chars. My code answer is based on various answers here.

It does not include another lib. Doesn't seem worth it to do this rather simple task.

It picks chars in the range 0x20 (space) inclusive to del (0x7f) exclusive which covers upper&lower a-z, digits and symbols.

Generates a string of specified length.

Using char[] as Jon Skeet says. Always do as he suggests :)

Hopefully, no off by one errors :) ... IMO odd that nextInt is exclusive for the upper bound.

Not sure whether it matters, but declared random outside method. Yes, seeding would be good, but for my purposes pseudo-random is good enough. You can seed if you want.

Not generated by chatpgt ... maybe it can learn something from me :)

private final Random random = new Random();

private String getRandomString(int length) {
    final char startCode = 0x20; // space
    final char endCode =  0x7F; // del
    final char codeCount = endCode - startCode;
    var chars = new char[length];
    for (int i = 0; i < length; ++i) {
        final char codeOffset = (char) random.nextInt(codeCount + 1);
        final char code = (char) (codeOffset + startCode);
        chars[i] = code;
    }
    return new String(chars);
}

Upvotes: 0

Suresh
Suresh

Reputation: 1

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);

Upvotes: 0

schnatterer
schnatterer

Reputation: 7859

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;
}

Upvotes: 0

duggu
duggu

Reputation: 38409

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.

Upvotes: 3

Josema
Josema

Reputation: 1847

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);

Upvotes: 91

dfa
dfa

Reputation: 116304

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);

Upvotes: 1

NSV.
NSV.

Reputation: 61

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

Upvotes: -1

aurelius
aurelius

Reputation: 4076

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;
}

Upvotes: 0

Andrewsz82
Andrewsz82

Reputation: 1

I use this:

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

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

Upvotes: 0

ArsamP
ArsamP

Reputation: 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);
}

Upvotes: -1

Farshid Ahmadi
Farshid Ahmadi

Reputation: 513

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);
    }
}

Upvotes: 0

Gulbala Salamov
Gulbala Salamov

Reputation: 308

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.

Upvotes: 1

Abhishek Jha
Abhishek Jha

Reputation: 131

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

Upvotes: 0

Ricardo Vallejo
Ricardo Vallejo

Reputation: 161

String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

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

This one works as well.

Upvotes: 13

Marcin Programista
Marcin Programista

Reputation: 51

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();
}

Upvotes: 0

Andrei Ciobanu
Andrei Ciobanu

Reputation: 12840

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(); 

Upvotes: -1

Peter Walser
Peter Walser

Reputation: 15696

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.

Upvotes: 16

dogbane
dogbane

Reputation: 274522

To generate a random char in a-z:

Random r = new Random();
char c = (char)(r.nextInt(26) + 'a');

Upvotes: 153

Thomas Jung
Thomas Jung

Reputation: 33082

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

Upvotes: 1

ring bearer
ring bearer

Reputation: 20773

   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.

Upvotes: -2

polygenelubricants
polygenelubricants

Reputation: 383676

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

Upvotes: 103

manuel
manuel

Reputation: 184

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

Upvotes: 0

Related Questions