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?

319979 次浏览

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

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

   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.

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

To generate a random char in a-z:

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

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

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

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.

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;
}
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";


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

This one works as well.

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

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

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

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.

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

I use this:

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


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

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

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