Reputation: 22237
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
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
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
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
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
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
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
Reputation: 61
I simply want to tell you to use UUID.randomUUID() and toString() as its simplest way i also used
Upvotes: -1
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
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
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
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
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:
if you run one more time again:
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
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
Reputation: 161
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char letter = abc.charAt(rd.nextInt(abc.length()));
This one works as well.
Upvotes: 13
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
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
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
Reputation: 274522
To generate a random char in a-z:
Random r = new Random();
char c = (char)(r.nextInt(26) + 'a');
Upvotes: 153
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
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
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
Reputation: 184
Take a look at Java Randomizer class. I think you can randomize a character using the randomize(char[] array) method.
Upvotes: 0