有在Java中生成随机字符的功能吗?


69

Java是否具有生成随机字符或字符串的功能?还是必须简单地选择一个随机整数并将该整数的ASCII码转换为字符?

Answers:


94

有很多方法可以做到这一点,但是可以,它涉及到生成一个随机数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


谢谢,如果您要生成一组定义的字符,那实际上是一个简洁的解决方案。对于整个字母,狗狗的答案要短一些。通过使用数组,可以稍微提高效率和可读性。参见我的十六进制示例
schnatterer

139

要在az中生成随机字符:

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

8
您甚至可以走得更远,(char)(r.nextInt('z' - 'a') + 'a')如果不确定字母中有多少个字母。
阿米尔·埃尔多

4
@AmirEldor永远不会产生AZ,因为'z' - 'a' == 25,没有26
Klitos Kyriacou

75

您还可以使用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);

1
<dependency> <groupId> org.apache.commons </ groupId> <artifactId> commons-lang3 </ artifactId> <version> 3.8.1 </ version> </ dependency>
bitfishxyz

14
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范围内的值。


1
(char) (base + rnd % 26)工作原理如何?是否因为在int中添加char将char转换为其ASCII码?
冒犯君主

2
@Lèsemajesté-是的,这就是为什么。每个char都还可以隐式转换为int,因此可以将“ a”视为整数值(97),然后将其偏移3,将得出100,当转换回a时,它char为“ d”。
马特·米切尔

9
String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

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

这个也很好。


事先设置可能的字符的好主意。
Andreas L.

4

在下面的97中,ascii值小“ a”。

public static char randomSeriesForThreeCharacter() {
Random r = new Random();
char random_3_Char = (char) (97 + r.nextInt(3));
return random_3_Char;
}

在上面的3个数字中,将a,b,c或d替换为数字,如果您希望将所有字符(如a到z)替换为25。


1

您可以使用基于Quickcheck规范的测试框架中的生成器

要创建随机字符串,请使用anyString方法。

String x = anyString();

您可以使用一组更受限制的字符或具有最小/最大大小限制的字符串来创建字符串。

通常,您将使用多个值运行测试:

@Test
public void myTest() {
  for (List<Integer> any : someLists(integers())) {
    //A test executed with integer lists
  }
}

1

使用美元

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

1
这将在随机字符串中最多使用一次每个字符。这可能不是OP所需要的。
Steve McLeod

@Steve:谢谢,我已经解决了我的问题,并扩展了库bitbucket.org/dfa/dollar/changeset/4c26ccf9464e
dfa 2010年

1

这是一个简单但有用的发现。它定义了一个名为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版》,在其中我引用了这些知识并在我的项目中使用了这些知识。

注意:如果您不熟悉重载的方法,简而言之,方法重载是一项功能,如果一个类的参数列表不同,则它允许一个类拥有多个具有相同名称的方法。


0

看一下Java Randomizer类。我认为您可以使用randomize(char [] array)方法将字符随机化。


@manuel,我想我们需要安装Liefra jar文件,它没有默认的jar文件
gmhk 2010年

0

我的建议是生成带有混合大小写的随机字符串,例如:“ 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)和从AZ(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();
}

2
请您添加更多信息以进一步了解和清楚说明。stackoverflow.com/help/how-to-answer
Prags

@PragatiSingh,是的,我编辑了评论并添加了一些描述。
Marcin Programista

@PragatiSingh Nuix8s 8m58On7
Andrei Ciobanu

0

这是生成随机字母数字代码的代码。首先,必须声明一串允许包含在随机数中的字符,并定义最大字符串长度

 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获取字符串


0

如果只想生成十六进制值,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;
}

0

实际上,提到的方法不会生成真正的随机字符。要生成真正的随机字符,您应该给它一个随机种子!例如时间(以毫秒为单位)。此代码生成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);
    }
}

0

我用这个:

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

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

0

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

-1

如果您不介意在代码中添加新库,则可以使用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(); 

3
整个库来简单地获取随机字符?
拉斐尔·利马

@RafaelLima图书馆的成就远不止于此。
安德烈·乔巴努

1
库“也许”可以做得更多,但是您建议一个人在他的项目中添加一个新的依赖项,只是为了获得一个随机的字符……出于一千个原因,这没有任何意义。
拉斐尔·利马

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

1
尽管此代码可以解决问题,但是好的答案还应该说明它的作用以及如何帮助您?
Suraj Kumar

字符A的字母ascii代码为25并继续使用,代码的第一行生成一个介于25到90之间的随机数,第二行将其转换为char例如,如果它生成第二行则将其转换为char。
ArsamP '20

-2
   Random randomGenerator = new Random();

   int i = randomGenerator.nextInt(256);
   System.out.println((char)i);

假设您将'0,'1','2'..视为字符,应该照顾好自己想要的东西。


1
这很可能不是预期的,因为在此范围内,您将包含很多不太可能出现的控制字符。
Joachim Sauer'4
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.