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 r开发者_JAVA百科andom integer and convert that integer's ascii code to a character?
To generate a random char in a-z:
Random r = new Random();
char c = (char)(r.nextInt(26) + 'a');
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
).
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);
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.
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char letter = abc.charAt(rd.nextInt(abc.length()));
This one works as well.
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.
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
}
}
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);
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.
Take a look at Java Randomizer class. I think you can randomize a character using the randomize(char[] array) method.
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
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;
}
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);
}
}
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
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();
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);
}
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.
精彩评论