Java是否具有生成随机字符或字符串的功能?还是必须简单地选择一个随机整数并将该整数的ASCII码转换为字符?
Answers:
有很多方法可以做到这一点,但是可以,它涉及到生成一个随机数int
(使用例如java.util.Random.nextInt
),然后使用它来映射到char
。如果您有一个特定的字母,那么类似这样的东西很不错:
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
请注意,这java.util.Random
实际上是基于相当弱的线性同余公式的伪随机数生成器。您提到了加密的需求;您可能想研究在这种情况下使用功能更强大的加密安全伪随机数生成器(例如)。java.security.SecureRandom
要在az中生成随机字符:
Random r = new Random();
char c = (char)(r.nextInt(26) + 'a');
(char)(r.nextInt('z' - 'a') + 'a')
如果不确定字母中有多少个字母。
'z' - 'a' == 25
,没有26
您还可以使用Apache Commons项目中的RandomStringUtils:
依赖关系:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
用途:
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);
}
生成az,AZ范围内的值。
(char) (base + rnd % 26)
工作原理如何?是否因为在int中添加char将char转换为其ASCII码?
char
都还可以隐式转换为int,因此可以将“ a”视为整数值(97),然后将其偏移3,将得出100,当转换回a时,它char
为“ d”。
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char letter = abc.charAt(rd.nextInt(abc.length()));
这个也很好。
您可以使用基于Quickcheck规范的测试框架中的生成器。
要创建随机字符串,请使用anyString方法。
String x = anyString();
您可以使用一组更受限制的字符或具有最小/最大大小限制的字符串来创建字符串。
通常,您将使用多个值运行测试:
@Test
public void myTest() {
for (List<Integer> any : someLists(integers())) {
//A test executed with integer lists
}
}
使用美元:
Iterable<Character> chars = $('a', 'z'); // 'a', 'b', c, d .. z
给定chars
您可以构建“改组”的字符范围:
Iterable<Character> shuffledChars = $('a', 'z').shuffle();
然后取第一个n
字符,您将获得一个随机的length字符串n
。最终的代码很简单:
public String randomString(int n) {
return $('a', 'z').shuffle().slice(n).toString();
}
注意:病情n > 0
恶化slice
编辑
正如史蒂夫正确指出的那样,randomString
每个字母最多使用一次。解决方法是,您可以m
在致电之前重复输入字母时间shuffle
:
public String randomStringWithRepetitions(int n) {
return $('a', 'z').repeat(10).shuffle().slice(n).toString();
}
或只提供您的字母为String
:
public String randomStringFromAlphabet(String alphabet, int n) {
return $(alphabet).shuffle().slice(n).toString();
}
String s = randomStringFromAlphabet("00001111", 4);
这是一个简单但有用的发现。它定义了一个名为RandomCharacter的类,该类具有5个重载方法以随机获取某种类型的字符。您可以在以后的项目中使用这些方法。
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');
}
}
为了演示其工作原理,让我们看下面的测试程序,该程序显示175个随机的小写字母。
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);
}
}
}
输出为:
如果您再次运行一次:
我要感谢Y.Daniel Liang的书《 Java编程简介,综合版,第10版》,在其中我引用了这些知识并在我的项目中使用了这些知识。
注意:如果您不熟悉重载的方法,简而言之,方法重载是一项功能,如果一个类的参数列表不同,则它允许一个类拥有多个具有相同名称的方法。
看一下Java Randomizer类。我认为您可以使用randomize(char [] array)方法将字符随机化。
我的建议是生成带有混合大小写的随机字符串,例如:“ DthJwMvsTyu”。
当其代码a-z
(97至122)和A-Z
(65至90)的第5位(2 ^ 5或1 << 5或32)不同时,该算法基于字母的ASCII码。
random.nextInt(2)
:结果为0或1。
random.nextInt(2) << 5
:结果为0或32。
高位A
是65,低位a
是97。差异仅在第5位(32)上,因此为了生成随机字符,我们执行二进制OR'|' 随机charCaseBit
(0或32)和从A
到Z
(65到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();
}
这是生成随机字母数字代码的代码。首先,必须声明一串允许包含在随机数中的字符,并定义最大字符串长度
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));
}
使用toString()方法从StringBuilder获取字符串
如果只想生成十六进制值,polygenelubricants的答案也是一个很好的解决方案:
/** 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;
}
实际上,提到的方法不会生成真正的随机字符。要生成真正的随机字符,您应该给它一个随机种子!例如时间(以毫秒为单位)。此代码生成10个随机char,然后将其转换为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);
}
}
java.util.Random
是迄今为止我尝试过的更有效的方法,具有98.65%的唯一性精度。我在下面提供了一些测试,这些测试生成10000个批次的一百个2个字母数字字符字符串并计算平均值。
其他随机工具RandomStringUtils
来自commons.lang3和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;
}
如果您不介意在代码中添加新库,则可以使用MockNeat生成字符(免责声明:我是作者之一)。
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);
假设您将'0,'1','2'..视为字符,应该照顾好自己想要的东西。