如何生成随机字母数字字符串?

时间:2008-09-03 02:58:43

标签: java string random alphanumeric

我一直在寻找简单 Java算法来生成伪随机字母数字字符串。在我的情况下,它将被用作一个唯一的会话/密钥标识符,在500K+代之前“可能”是唯一的(我的需求实际上并不需要更复杂的东西)。

理想情况下,我可以根据我的唯一性需求指定长度。例如,生成的长度为12的字符串可能类似于"AEYGF7K0DM1X"

49 个答案:

答案 0 :(得分:1485)

算法

要生成随机字符串,请连接从可接受符号集中随机绘制的字符,直到字符串达到所需长度。

实施

这是一些用于生成随机标识符的相当简单且非常灵活的代码。 阅读以下信息以获取重要的应用说明。

import java.security.SecureRandom;
import java.util.Locale;
import java.util.Objects;
import java.util.Random;

public class RandomString {

    /**
     * Generate a random string.
     */
    public String nextString() {
        for (int idx = 0; idx < buf.length; ++idx)
            buf[idx] = symbols[random.nextInt(symbols.length)];
        return new String(buf);
    }

    public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public static final String lower = upper.toLowerCase(Locale.ROOT);

    public static final String digits = "0123456789";

    public static final String alphanum = upper + lower + digits;

    private final Random random;

    private final char[] symbols;

    private final char[] buf;

    public RandomString(int length, Random random, String symbols) {
        if (length < 1) throw new IllegalArgumentException();
        if (symbols.length() < 2) throw new IllegalArgumentException();
        this.random = Objects.requireNonNull(random);
        this.symbols = symbols.toCharArray();
        this.buf = new char[length];
    }

    /**
     * Create an alphanumeric string generator.
     */
    public RandomString(int length, Random random) {
        this(length, random, alphanum);
    }

    /**
     * Create an alphanumeric strings from a secure generator.
     */
    public RandomString(int length) {
        this(length, new SecureRandom());
    }

    /**
     * Create session identifiers.
     */
    public RandomString() {
        this(21);
    }

}

用法示例

为8个字符的标识符创建一个不安全的生成器:

RandomString gen = new RandomString(8, ThreadLocalRandom.current());

为会话标识符创建安全的生成器:

RandomString session = new RandomString();

创建一个带有易于阅读的打印代码的生成器。字符串比完整的字母数字字符串长,以补偿使用更少的符号:

String easy = RandomString.digits + "ACEFGHJKLMNPQRUVWXYabcdefhijkprstuvwx";
RandomString tickets = new RandomString(23, new SecureRandom(), easy);

用作会话标识符

生成可能唯一的会话标识符不够好,或者您只能使用简单的计数器。当使用可预测的标识符时,攻击者会劫持会话。

长度和安全之间存在紧张关系。较短的标识符更容易猜测,因为可能性较小。但是较长的标识符会消耗更多的存储空间较大的符号集会有所帮助,但如果标识符包含在URL中或手动重新输入,则可能会导致编码问题。

会话标识符的随机性或熵的基础来源应来自为加密而设计的随机数生成器。但是,初始化这些生成器有时可能计算成本高或速度慢,因此应尽可能重新使用它们。

用作对象标识符

并非每个应用程序都需要安全性。随机分配可以是多个实体在没有任何协调或分区的情况下在共享空间中生成标识符的有效方式。协调可能很慢,特别是在集群或分布式环境中,当实体最终使用太小或太大的共享时,拆分空间会导致问题。

如果攻击者可能能够查看和操作它们,那么在不采取措施使其不可预测的情况下生成的标识符应该受到其他方式的保护,就像在大多数Web应用程序中一样。应该有一个单独的授权系统来保护攻击者可以在没有访问权限的情况下猜到其标识符的对象。

还必须注意使用足够长的标识符,以便根据预期的标识符总数进行冲突。这被称为“生日悖论”。 The probability of a collision, p ,大约是n 2 /(2q x ),其中 n 是数字实际生成的标识符, q 是字母表中不同符号的数量, x 是标识符的长度。这应该是一个非常小的数字,例如2 -50 或更少。

解决这个问题表明,500k 15个字符标识符之间碰撞的可能性大约为2 -52 ,这可能不如宇宙射线未检测到的错误等。

与UUID的比较

根据他们的规范,UUID并非设计为不可预测,不应用作会话标识符。

标准格式的UUID需要占用大量空间:36个字符仅需122位熵。 (并非随机选择“随机”UUID的所有位。)随机选择的字母数字字符串仅包含21个字符的更多熵。

UUID不灵活;他们有一个标准化的结构和布局。这是他们的主要优点,也是他们的主要弱点。与外部团队合作时,UUID提供的标准化可能会有所帮助。对于纯粹的内部使用,它们可能效率低下。

答案 1 :(得分:782)

Java提供了一种直接执行此操作的方法。如果你不想要破折号,它们很容易被剥离。只需使用uuid.replace("-", "")

即可
import java.util.UUID;

public class randomStringGenerator {
    public static void main(String[] args) {
        System.out.println(generateString());
    }

    public static String generateString() {
        String uuid = UUID.randomUUID().toString();
        return "uuid = " + uuid;
    }
}

<强>输出:

uuid = 2d7428a6-b58c-4008-8575-f05549f16316

答案 2 :(得分:515)

static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static SecureRandom rnd = new SecureRandom();

String randomString( int len ){
   StringBuilder sb = new StringBuilder( len );
   for( int i = 0; i < len; i++ ) 
      sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
   return sb.toString();
}

答案 3 :(得分:471)

如果您乐意使用Apache类,可以使用org.apache.commons.text.RandomStringGenerator(commons-text)。

示例:

RandomStringGenerator randomStringGenerator =
        new RandomStringGenerator.Builder()
                .withinRange('0', 'z')
                .filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
                .build();
randomStringGenerator.generate(12); // toUpperCase() if you want

由于commons-lang 3.6,RandomStringUtils已被弃用。

答案 4 :(得分:103)

在一行中:

Long.toHexString(Double.doubleToLongBits(Math.random()));
  

http://mynotes.wordpress.com/2009/07/23/java-generating-random-string/

答案 5 :(得分:98)

您可以使用Apache库:RandomStringUtils

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

答案 6 :(得分:54)

没有任何外部库,这很容易实现。

1。加密伪随机数据生成

首先,您需要加密PRNG。 Java有SecureRandom,因为它通常使用机器上的最佳熵源(例如/dev/random)。 Read more here.

SecureRandom rnd = new SecureRandom();
byte[] token = new byte[byteLength];
rnd.nextBytes(token);

注意: SecureRandom是Java中生成随机字节的最慢但最安全的方式。但是我建议不考虑这里的性能,因为它通常对你的应用程序没有实际影响,除非你必须每秒产生数百万个令牌。

2。可能值的所需空间

接下来,您必须确定您的令牌需要“多么独特”。考虑熵的唯一要点是确保系统能够抵抗暴力攻击:可能值的空间必须非常大,以至于任何攻击者只能在非荒谬的时间内尝试可忽略不计的值。 1 。诸如随机UUID之类的唯一标识符具有122bit的熵(即,2 ^ 122 = 5.3x10 ^ 36) - 碰撞的机会是“*(...),因为有十亿分之一的机会重复,必须生成103万亿版本4 UUID 2 “。 我们将选择128位,因为它完全符合16个字节,并且被视为highly sufficient,因为它基本上是唯一的,但是最极端的用例,你不需要思考关于重复。这是一个简单的熵比较表,包括birthday problem的简单分析。

comparison of token sizes

对于简单的要求,8或12字节的长度可能就足够了,但是有16个字节,你就处于“安全的一面”。

基本上就是这样。最后一件事是考虑编码,以便它可以表示为可打印的文本(阅读,String)。

3。二进制到文本编码

典型编码包括:

  • Base64每个字符编码6位,产生33%的开销。幸运的是,Java 8+Android中有标准实现。使用较旧的Java,您可以使用numerous third party libraries中的任何一个。如果您希望您的令牌安全,请使用RFC4648的url-safe版本(大多数实现通常都支持这种版本)。使用填充编码16个字节的示例:XfJhfv3C0P6ag7y9VQxSbw==

  • Base32每个字符编码5bit,产生40%的开销。这将使用A-Z2-7,使其具有合理的空间效率,同时不区分大小写的字母数字。没有standard implementation in the JDK。示例编码16个字节而不填充:WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16(hex)每个字符编码4bit,每个字节需要2个字符(即16个字节创建一个长度为32的字符串)。因此,hex的空间效率低于Base32,但在大多数情况下(url)可以安全使用,因为它只使用0-9AF。编码16个字节的示例:4fa3dd0f57cb3bf331441ed285b27735See a SO discussion about converting to hex here.

其他编码如Base85和异域Base122存在,空间效率更好/更差。你可以创建自己的编码(基本上这个线程中的大多数答案都可以),但如果你没有非常具体的要求,我会反对它。见more encoding schemes in the Wikipedia article.

4。摘要和示例

  • 使用SecureRandom
  • 使用至少16个字节(2 ^ 128)的可能值
  • 根据您的要求进行编码(如果您需要使用字母数字,通常为hexbase32

<强>不

  • ...使用你的家庭酿造编码:对于其他人来说,如果他们看到你使用的标准编码而不是奇怪的循环创建字符,那么其他人可以更好地维护和阅读。
  • ...使用UUID:它无法保证随机性;你浪费了6比特的熵并且有详细的字符串表示

示例:十六进制令牌生成器

public static String generateRandomHexToken(int byteLength) {
    SecureRandom secureRandom = new SecureRandom();
    byte[] token = new byte[byteLength];
    secureRandom.nextBytes(token);
    return new BigInteger(1, token).toString(16); //hex encoding
}

//generateRandomHexToken(16) -> 2189df7475e96aa3982dbeab266497cd

示例:Base64令牌生成器(Url安全)

public static String generateRandomBase64Token(int byteLength) {
    SecureRandom secureRandom = new SecureRandom();
    byte[] token = new byte[byteLength];
    secureRandom.nextBytes(token);
    return Base64.getUrlEncoder().withoutPadding().encodeToString(token); //base64 encoding
}

//generateRandomBase64Token(16) -> EEcCCAYuUcQk7IuzdaPzrg

示例:Java CLI工具

如果你想要一个随时可用的cli工具,你可以使用骰子:https://github.com/patrickfav/dice

答案 7 :(得分:41)

使用Dollar应该很简单:

// "0123456789" + "ABCDE...Z"
String validCharacters = $('0', '9').join() + $('A', 'Z').join();

String randomString(int length) {
    return $(validCharacters).shuffle().slice(length).toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int i : $(5)) {
        System.out.println(randomString(12));
    }
}

它会输出类似的内容:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7

答案 8 :(得分:31)

这是Java:

import static java.lang.Math.round;
import static java.lang.Math.random;
import static java.lang.Math.pow;
import static java.lang.Math.abs;
import static java.lang.Math.min;
import static org.apache.commons.lang.StringUtils.leftPad

public class RandomAlphaNum {
  public static String gen(int length) {
    StringBuffer sb = new StringBuffer();
    for (int i = length; i > 0; i -= 12) {
      int n = min(12, abs(i));
      sb.append(leftPad(Long.toString(round(random() * pow(36, n)), 36), n, '0'));
    }
    return sb.toString();
  }
}

这是一个示例运行:

scala> RandomAlphaNum.gen(42)
res3: java.lang.String = uja6snx21bswf9t89s00bxssu8g6qlu16ffzqaxxoy

答案 9 :(得分:31)

令人惊讶的是,没有人建议,但是:

import java.util.UUID

UUID.randomUUID().toString();

易。

这样做的好处是UUID很好而且很长并且几乎不可能发生碰撞。

维基百科对此有一个很好的解释:

  

“......在未来100年内每秒产生10亿UUID之后,创建一个副本的可能性大约为50%。”

http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates

前4位是版本类型,2是变体,所以你得到122位随机。因此,如果你想要,你可以从最后截断以减少UUID的大小。这不是推荐的,但你仍然有很多随机性,足以让你的500k记录容易。

答案 10 :(得分:26)

简单易用的解决方案,但只使用小写和数字:

Random r = new java.util.Random ();
String s = Long.toString (r.nextLong () & Long.MAX_VALUE, 36);

大小约为12位数到36位,并且无法进一步改善。当然,您可以附加多个实例。

答案 11 :(得分:13)

Java 8中的替代方案是:

static final Random random = new Random(); // Or SecureRandom
static final int startChar = (int) '!';
static final int endChar = (int) '~';

static String randomString(final int maxLength) {
  final int length = random.nextInt(maxLength + 1);
  return random.ints(length, startChar, endChar + 1)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}

答案 12 :(得分:10)

使用UUID是不安全的,因为部分UUID根本不是随机的。 @erickson的过程非常简洁,但不会创建相同长度的字符串。以下代码段就足够了:

/*
 * The random generator used by this class to create random keys.
 * In a holder class to defer initialization until needed.
 */
private static class RandomHolder {
    static final Random random = new SecureRandom();
    public static String randomKey(int length) {
        return String.format("%"+length+"s", new BigInteger(length*5/*base 32,2^5*/, random)
            .toString(32)).replace('\u0020', '0');
    }
}

为什么选择length*5。让我们假设一个长度为1的随机字符串的简单情况,因此是一个随机字符。要获得包含所有数字0-9和字符a-z的随机字符,我们需要一个0到35之间的随机数来获取每个字符中的一个。 BigInteger提供了一个构造函数来生成随机数,均匀分布在0 to (2^numBits - 1)范围内。不幸的是35不是2 ^ numBits可以接收的数字 - 1.所以我们有两个选择:可以选择2^5-1=312^6-1=63。如果我们选择2^6,我们会得到很多“不必要的”/“更长”的数字。因此2^5是更好的选择,即使我们松散4个字符(w-z)。要生成一定长度的字符串,我们只需使用2^(length*numBits)-1个数字即可。最后一个问题,如果我们想要一个具有一定长度的字符串,随机可以生成一个小数字,所以不满足长度,所以我们必须将字符串填充到它所需的长度前置零。

答案 13 :(得分:10)

public static String generateSessionKey(int length){
String alphabet = 
        new String("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); //9
int n = alphabet.length(); //10

String result = new String(); 
Random r = new Random(); //11

for (int i=0; i<length; i++) //12
    result = result + alphabet.charAt(r.nextInt(n)); //13

return result;
}

答案 14 :(得分:9)

import java.util.Random;

public class passGen{
    //Verison 1.0
    private static final String dCase = "abcdefghijklmnopqrstuvwxyz";
    private static final String uCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String sChar = "!@#$%^&*";
    private static final String intChar = "0123456789";
    private static Random r = new Random();
    private static String pass = "";

    public static void main (String[] args) {
        System.out.println ("Generating pass...");
        while (pass.length () != 16){
            int rPick = r.nextInt(4);
            if (rPick == 0){
                int spot = r.nextInt(25);
                pass += dCase.charAt(spot);
            } else if (rPick == 1) {
                int spot = r.nextInt (25);
                pass += uCase.charAt(spot);
            } else if (rPick == 2) {
                int spot = r.nextInt (7);
                pass += sChar.charAt(spot);
            } else if (rPick == 3){
                int spot = r.nextInt (9);
                pass += intChar.charAt (spot);
            }
        }
        System.out.println ("Generated Pass: " + pass);
    }
}

所以这样做只是将密码添加到字符串中......并且工作得很好看看...非常简单。我写了

答案 15 :(得分:8)

我正在使用Apache Commons中的库来生成字母数字字符串:

import org.apache.commons.lang3.RandomStringUtils;

String keyLength = 20;
RandomStringUtils.randomAlphanumeric(keylength);

快速而简单!

答案 16 :(得分:7)

import java.util.Date;
import java.util.Random;

public class RandomGenerator {

  private static Random random = new Random((new Date()).getTime());

    public static String generateRandomString(int length) {
      char[] values = {'a','b','c','d','e','f','g','h','i','j',
               'k','l','m','n','o','p','q','r','s','t',
               'u','v','w','x','y','z','0','1','2','3',
               '4','5','6','7','8','9'};

      String out = "";

      for (int i=0;i<length;i++) {
          int idx=random.nextInt(values.length);
          out += values[idx];
      }
      return out;
    }
}

答案 17 :(得分:7)

我发现这个解决方案生成一个随机的十六进制编码字符串。提供的单元测试似乎符合我的主要用例。虽然,它比其他一些答案稍微复杂一些。

/**
 * Generate a random hex encoded string token of the specified length
 *  
 * @param length
 * @return random hex string
 */
public static synchronized String generateUniqueToken(Integer length){ 
    byte random[] = new byte[length];
    Random randomGenerator = new Random();
    StringBuffer buffer = new StringBuffer();

    randomGenerator.nextBytes(random);

    for (int j = 0; j < random.length; j++) {
        byte b1 = (byte) ((random[j] & 0xf0) >> 4);
        byte b2 = (byte) (random[j] & 0x0f);
        if (b1 < 10)
            buffer.append((char) ('0' + b1));
        else
            buffer.append((char) ('A' + (b1 - 10)));
        if (b2 < 10)
            buffer.append((char) ('0' + b2));
        else
            buffer.append((char) ('A' + (b2 - 10)));
    }
    return (buffer.toString());
}

@Test
public void testGenerateUniqueToken(){
    Set set = new HashSet();
    String token = null;
    int size = 16;

    /* Seems like we should be able to generate 500K tokens 
     * without a duplicate 
     */
    for (int i=0; i<500000; i++){
        token = Utility.generateUniqueToken(size);

        if (token.length() != size * 2){
            fail("Incorrect length");
        } else if (set.contains(token)) {
            fail("Duplicate token generated");
        } else{
            set.add(token);
        }
    }
}

答案 18 :(得分:6)

  1. 根据您的要求更改字符串字符。

  2. 字符串是不可变的。这里StringBuilder.append比字符串连接更有效。


  3. public static String getRandomString(int length) {
           final String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+";
           StringBuilder result = new StringBuilder();
           while(length > 0) {
               Random rand = new Random();
               result.append(characters.charAt(rand.nextInt(characters.length())));
               length--;
           }
           return result.toString();
        }
    

答案 19 :(得分:6)

对于“简单”的解决方案,我真的不喜欢这个答案:S

我会选择一个简单的;),纯java,一个班轮(熵基于随机字符串长度和给定的字符集):

'plotNameOfTheClass'

或(稍微可读的旧方式)

public String randomString(int length, String characterSet) {
    return IntStream.range(0, length).map(i -> new SecureRandom().nextInt(characterSet.length())).mapToObj(randomInt -> characterSet.substring(randomInt, randomInt + 1)).collect(Collectors.joining());
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));//charachterSet can basically be anything
    }
}

但另一方面你也可以使用具有相当好的熵的UUID(https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions):

public String randomString(int length, String characterSet) {
    StringBuilder sb = new StringBuilder(); //consider using StringBuffer if needed
    for (int i = 0; i < length; i++) {
        int randomInt = new SecureRandom().nextInt(characterSet.length());
        sb.append(characterSet.substring(randomInt, randomInt + 1));
    }
    return sb.toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); //charachterSet can basically be anything
    }
}

希望有所帮助。

答案 20 :(得分:6)

import java.util.*;
import javax.swing.*;
public class alphanumeric{
    public static void main(String args[]){
        String nval,lenval;
        int n,len;

        nval=JOptionPane.showInputDialog("Enter number of codes you require : ");
        n=Integer.parseInt(nval);

        lenval=JOptionPane.showInputDialog("Enter code length you require : ");
        len=Integer.parseInt(lenval);

        find(n,len);

    }
    public static void find(int n,int length) {
        String str1="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder sb=new StringBuilder(length);
        Random r = new Random();

        System.out.println("\n\t Unique codes are \n\n");
        for(int i=0;i<n;i++){
            for(int j=0;j<length;j++){
                sb.append(str1.charAt(r.nextInt(str1.length())));
            }
            System.out.println("  "+sb.toString());
            sb.delete(0,length);
        }
    }
}

答案 21 :(得分:5)

你提到“简单”,但是如果其他人正在寻找满足更严格的安全要求的东西,你可能想看看jpwgen。 jpwgen在Unix中以pwgen为模型,并且非常易于配置。

答案 22 :(得分:4)

您可以将UUID类及其getLeastSignificantBits()消息用于获取64位随机数据​​,然后将其转换为基数为36的数字(即包含0-9,A-Z的字符串):

Long.toString(Math.abs( UUID.randomUUID().getLeastSignificantBits(), 36));

这会产生一个长达13个字符的字符串。我们使用Math.abs()来确保没有潜入的减号。

答案 23 :(得分:4)

以下是AbacusUtil

的一行代码
String.valueOf(CharStream.random('0', 'z').filter(c -> N.isLetterOrDigit(c)).limit(12).toArray())

随机并不意味着它必须是唯一的。使用以下方法获取唯一字符串:

N.uuid() // e.g.: "e812e749-cf4c-4959-8ee1-57829a69a80f". length is 36.
N.guid() // e.g.: "0678ce04e18945559ba82ddeccaabfcd". length is 32 without '-'

答案 24 :(得分:4)

如果您的密码必须包含数字字母特殊字符,则可以使用以下代码:

private static final String NUMBERS = "0123456789";
private static final String UPPER_ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWER_ALPHABETS = "abcdefghijklmnopqrstuvwxyz";
private static final String SPECIALCHARACTERS = "@#$%&*";
private static final int MINLENGTHOFPASSWORD = 8;

public static String getRandomPassword() {
    StringBuilder password = new StringBuilder();
    int j = 0;
    for (int i = 0; i < MINLENGTHOFPASSWORD; i++) {
        password.append(getRandomPasswordCharacters(j));
        j++;
        if (j == 3) {
            j = 0;
        }
    }
    return password.toString();
}

private static String getRandomPasswordCharacters(int pos) {
    Random randomNum = new Random();
    StringBuilder randomChar = new StringBuilder();
    switch (pos) {
        case 0:
            randomChar.append(NUMBERS.charAt(randomNum.nextInt(NUMBERS.length() - 1)));
            break;
        case 1:
            randomChar.append(UPPER_ALPHABETS.charAt(randomNum.nextInt(UPPER_ALPHABETS.length() - 1)));
            break;
        case 2:
            randomChar.append(SPECIALCHARACTERS.charAt(randomNum.nextInt(SPECIALCHARACTERS.length() - 1)));
            break;
        case 3:
            randomChar.append(LOWER_ALPHABETS.charAt(randomNum.nextInt(LOWER_ALPHABETS.length() - 1)));
            break;
    }
    return randomChar.toString();

}

答案 25 :(得分:4)

这是一个Scala解决方案:

(for (i <- 0 until rnd.nextInt(64)) yield { 
  ('0' + rnd.nextInt(64)).asInstanceOf[Char] 
}) mkString("")

答案 26 :(得分:3)

我认为这是最小的解决方案,或者几乎是最小的解决方案之一:

 public String generateRandomString(int length) {
    String randomString = "";

    final char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890".toCharArray();
    final SecureRandom random = new SecureRandom();
    for (int i = 0; i < length; i++) {
        randomString = randomString + chars[random.nextInt(chars.length)];
    }

    return randomString;
}

代码工作正常。如果使用这种方法,我建议您使用10个以上的字符。碰撞发生在5个字符/ 30362次迭代中。这花了9秒。

答案 27 :(得分:3)

public static String randomSeriesForThreeCharacter() {
    Random r = new Random();
    String value="";
    char random_Char ;
    for(int i=0; i<10;i++)
    { 
        random_Char = (char) (48 + r.nextInt(74));
        value=value+random_char;
    }
    return value;
}

答案 28 :(得分:3)

使用apache库可以在一行中完成

import org.apache.commons.lang.RandomStringUtils;
RandomStringUtils.randomAlphanumeric(64);

这里是doc http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/RandomStringUtils.html

答案 29 :(得分:2)

也许这很有用

package password.generater;

import java.util.Random;

/**
 *
 * @author dell
 */
public class PasswordGenerater {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int length= 11;
        System.out.println(generatePswd(length));

        // TODO code application logic here
    }
    static char[] generatePswd(int len){
        System.out.println("Your Password ");
        String charsCaps="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
        String Chars="abcdefghijklmnopqrstuvwxyz";
        String nums="0123456789";
        String symbols="!@#$%^&*()_+-=.,/';:?><~*/-+";
        String passSymbols=charsCaps + Chars + nums +symbols;
        Random rnd=new Random();
        char[] password=new char[len];

        for(int i=0; i<len;i++){
            password[i]=passSymbols.charAt(rnd.nextInt(passSymbols.length()));
        }
      return password;

    }
}

答案 30 :(得分:2)

public static String getRandomString(int length) 
{
   String randomStr = UUID.randomUUID().toString();
   while(randomStr.length() < length) {
       randomStr += UUID.randomUUID().toString();
   }
   return randomStr.substring(0, length);
}

答案 31 :(得分:2)

public static String getRandomString(int length) {
        char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST".toCharArray();

        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[random.nextInt(chars.length)];
            sb.append(c);
        }
        String randomStr = sb.toString();

        return randomStr;
    }

答案 32 :(得分:1)

public class Utils {
    private final Random RANDOM = new SecureRandom();
    private final String ALPHABET = "0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";

    private String generateRandomString(int length) {
        StringBuffer buffer = new StringBuffer(length);
        for (int i = 0; i < length; i++) {
            buffer.append(ALPHABET.charAt(RANDOM.nextInt(ALPHABET.length())));
        }
        return new String(buffer);
    } 
}

答案 33 :(得分:1)

我开发了一个应用程序来为我的项目开发一个自动生成的字母数字字符串。在这个字符串中,前三个字符是按字母顺序排列的,接下来的七个字符是整数。

public class AlphaNumericGenerator {

    public static void main(String[] args) {
        java.util.Random r = new java.util.Random();
        int i = 1, n = 0;
        char c;
        String str="";
        for (int t = 0; t < 3; t++) {
            while (true) {
                i = r.nextInt(10);
                if (i > 5 && i < 10) {

                    if (i == 9) {
                        i = 90;
                        n = 90;
                        break;
                    }
                    if (i != 90) {
                        n = i * 10 + r.nextInt(10);
                        while (n < 65) {
                            n = i * 10 + r.nextInt(10);
                        }
                    }

                    break;
                }
            }
            c=(char)n;

            str= String.valueOf(c)+str;
        }
        while(true){
        i = r.nextInt(10000000);
        if(i>999999)
            break;
        }
        str=str+i;
        System.out.println(str);

    }
}

答案 34 :(得分:1)

您可以创建一个包含所有字母和数字的字符数组,然后您可以从此字符数组中随机选择并创建自己的字符串密码。

char[] chars = new char[62]; // sum of letters and numbers

int i = 0;

    for(char c = 'a'; c <= 'z';c++) { // for letters
        chars[i++] = c;
    }

    for(char c = '0'; c <= '9';c++) { // for numbers
        chars[i++] = c;
    }

    for(char c = 'A'; c <= 'Z';c++) { // for capital letters
        chars[i++] = c;
    }

    int numberOfCodes = 0;
    String code = "";
    while (numberOfCodes < 1) {//enter how much you want to generate at one time
        int numChars = 8; //Enter how many digits you want in your password

        for(i = 0; i < numChars; i++) {
            char c = chars[(int)(Math.random() * chars.length)];
            code = code + c;
        }
        System.out.println("Code is :" + code);
    }

答案 35 :(得分:1)

上面有很多StringBuilder的使用。我想这很简单,但每个字符需要一个函数调用,增长一个数组等... 如果使用stringbuilder,建议是指定字符串所需的容量,即。,

new StringBuilder(int capacity);

这是一个不使用StringBuilder或String附加的版本,也没有字典。

public static String randomString(int length)
{
    SecureRandom random = new SecureRandom();
    char[] chars = new char[length];
    for(int i=0;i<chars.length;i++)
    {
        int v = random.nextInt(10 + 26 + 26);
        char c;
        if (v < 10)
        {
            c = (char)('0' + v);
        }
        else if (v < 36)
        {
            c = (char)('a' - 10 + v);
        }
        else
        {
            c = (char)('A' - 36 + v);
        }
        chars[i] = c;
    }
    return new String(chars);
}

答案 36 :(得分:1)

这是一个基于流的Java 8解决方案。

    public String generateString(String alphabet, int length) {
        return generateString(alphabet, length, new SecureRandom()::nextInt);
    }

    // nextInt = bound -> n in [0, bound)
    public String generateString(String source, int length, IntFunction<Integer> nextInt) {
        StringBuilder sb = new StringBuilder();
        IntStream.generate(source::length)
                .boxed()
                .limit(length)
                .map(nextInt::apply)
                .map(source::charAt)
                .forEach(sb::append);

        return sb.toString();
    }

一样使用
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int length = 12;
String generated = generateString(alphabet, length);
System.out.println(generated);

函数nextInt应该接受一个整数bound,并返回一个介于0bound - 1之间的随机数。

答案 37 :(得分:1)

最佳随机字符串生成器方法

public class RandomStringGenerator{

    private static int randomStringLength = 25 ;
    private static boolean allowSpecialCharacters = true ;
    private static String specialCharacters = "!@$%*-_+:";
    private static boolean allowDuplicates = false ;

    private static boolean isAlphanum = false;
    private static boolean isNumeric = false;
    private static boolean isAlpha = false;
    private static final String alphabet = "abcdefghijklmnopqrstuvwxyz";
    private static boolean mixCase = false;
    private static final String capAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String num = "0123456789";

    public static String getRandomString() {
        String returnVal = "";
        int specialCharactersCount = 0;
        int maxspecialCharacters = randomStringLength/4;

        try {
            StringBuffer values = buildList();
            for (int inx = 0; inx < randomStringLength; inx++) {
                int selChar = (int) (Math.random() * (values.length() - 1));
                if (allowSpecialCharacters)
                {
                    if (specialCharacters.indexOf("" + values.charAt(selChar)) > -1)
                    {
                        specialCharactersCount ++;
                        if (specialCharactersCount > maxspecialCharacters)
                        {
                            while (specialCharacters.indexOf("" + values.charAt(selChar)) != -1)
                            {
                                selChar = (int) (Math.random() * (values.length() - 1));
                            }
                        }
                    }
                }
                returnVal += values.charAt(selChar);
                if (!allowDuplicates) {
                    values.deleteCharAt(selChar);
                }
            }
        } catch (Exception e) {
            returnVal = "Error While Processing Values";
        }
        return returnVal;
    }

    private static StringBuffer buildList() {
        StringBuffer list = new StringBuffer(0);
        if (isNumeric || isAlphanum) {
            list.append(num);
        }
        if (isAlpha || isAlphanum) {
            list.append(alphabet);
            if (mixCase) {
                list.append(capAlpha);
            }
        }
        if (allowSpecialCharacters)
        {
            list.append(specialCharacters);
        }
        int currLen = list.length();
        String returnVal = "";
        for (int inx = 0; inx < currLen; inx++) {
            int selChar = (int) (Math.random() * (list.length() - 1));
            returnVal += list.charAt(selChar);
            list.deleteCharAt(selChar);
        }
        list = new StringBuffer(returnVal);
        return list;
    }   

}

答案 38 :(得分:0)

此外,您可以生成任何较低或UPPER案例字母甚至特殊字符来自ASCII表的数据。例如,从A(DEC 65)到Z(DEC 90)生成大写字母:

String generateRandomStr(int min, int max, int size) {
    String result = "";
    for (int i = 0; i < size; i++) {
        result += String.valueOf((char)(new Random().nextInt((max - min) + 1) + min));
    }
    return result;
}

generateRandomStr(65,90,100)的生成输出;:

TVLPFQJCYFXQDCQSLKUKKILKKHAUFYEXLUQFHDWNMRBIRRRWNXNNZQTINZPCTKLHGHVYWRKEOYNSOFPZBGEECFMCOKWHLHCEWLDZ

答案 39 :(得分:0)

public static String RandomAlphanum(int length)
    {
        String charstring = "abcdefghijklmnopqrstuvwxyz0123456789";
        String randalphanum = "";
        double randroll;
        String randchar;
        for
        (double i = 0; i < length; i++)
        {
            randroll = Math.random();
            randchar = "";
            for
            (int j = 1; j <= 35; j++)
            {
                if
                (randroll <= (1.0 / 36.0 * j))
                {
                    randchar = Character.toString(charstring.charAt(j - 1));
                    break;
                }
            }
            randalphanum += randchar;
        }
        return randalphanum;
    }

我使用了一个非常原始的算法,即Math.random()。要增加随机性,您可以直接实现util.Date类。尽管如此,它仍然有效。

答案 40 :(得分:0)

有效而简短。

/**
 * Utility class for generating random Strings.
 */
public interface RandomUtil {

    int    DEF_COUNT = 20;
    Random RANDOM    = new SecureRandom();

    /**
     * Generate a password.
     *
     * @return the generated password
     */
    static String generatePassword() {
        return generate(true, true);
    }

    /**
     * Generate an activation key.
     *
     * @return the generated activation key
     */
    static String generateActivationKey() {
        return generate(false, true);
    }

    /**
     * Generate a reset key.
     *
     * @return the generated reset key
     */
    static String generateResetKey() {
        return generate(false, true);
    }

    static String generate(boolean letters, boolean numbers) {
        int
            start = ' ',
            end   = 'z' + 1,
            count = DEF_COUNT,
            gap   = end - start;
        StringBuilder builder = new StringBuilder(count);
        while (count-- != 0) {
            int codePoint = RANDOM.nextInt(gap) + start;
            switch (getType(codePoint)) {
                case UNASSIGNED:
                case PRIVATE_USE:
                case SURROGATE:
                    count++;
                    continue;
            }
            int numberOfChars = charCount(codePoint);
            if (count == 0 && numberOfChars > 1) { count++; continue; }
            if (letters && isLetter(codePoint)
                || numbers && isDigit(codePoint)
                || !letters && !numbers) {
                builder.appendCodePoint(codePoint);
                if (numberOfChars == 2) count--;
            } else count++;
        }
        return builder.toString();
    }

}

答案 41 :(得分:0)

这是一个简单的单行程序,使用UUID作为字符库,并且能够指定(几乎)任何长度。 (是的,我知道之前曾建议使用UUID)

public static String randString(int length) {
    return UUID.randomUUID().toString().replace("-", "").substring(0, Math.min(length, 32)) + (length > 32 ? randString(length - 32) : "");
}

答案 42 :(得分:0)

又一个解决方案......

public static String generatePassword(int passwordLength) {
    int asciiFirst = 33;
    int asciiLast = 126;
    Integer[] exceptions = { 34, 39, 96 };

    List<Integer> exceptionsList = Arrays.asList(exceptions);
    SecureRandom random = new SecureRandom();
    StringBuilder builder = new StringBuilder();
    for (int i=0; i<passwordLength; i++) {
        int charIndex;
        do {
            charIndex = random.nextInt(asciiLast - asciiFirst + 1) + asciiFirst;
        }
        while (exceptionsList.contains(charIndex));

        builder.append((char) charIndex);
    }

    return builder.toString();
}

答案 43 :(得分:-1)

大写和小写之间随机10个字母的字符串

StringBuilder randomString = new StringBuilder();   
Random random = new Random();
boolean alphaType = true;
int j;

for(int i = 0; i <= 9; ++i)
{
    j = (random.nextInt(25) + (alphaType == true ? 65 : 97));
    randomString.append((char)j);
    alphaType = !alphaType;
}
return randomString.toString();

答案 44 :(得分:-1)

/**
    Generate a random String with maxlength random
    characters found in the ASCII table between 33
    and 122 (so it contains every lowercase / uppercase
    letters, numbers and some others characters
*/
public static String GetRandomString(int maxlength)
{
    String result = "";
    int i = 0, n = 0, min = 33, max = 122;
    while(i < maxlength)
    {
        n = (int)(Math.random() * (max - min) + min);
        if(n >= 33 && n < 123)
        {
            result += (char)n;
            ++i;
        }
    }
    return(result);
}

答案 45 :(得分:-1)

我使用的是一个使用 Java 8 的非常简单的解决方案。只需根据您的需要对其进行自定义即可。

...
import java.security.SecureRandom;
...

//Generate a random String of length between 10 to 20.
//Length is also randomly generated here.
SecureRandom random = new SecureRandom();

String sampleSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";

int stringLength = random.ints(1, 10, 21).mapToObj(x -> x).reduce((a, b) -> a).get();

String randomString = random.ints(stringLength, 0, sampleSet.length() - 1)
        .mapToObj(x -> sampleSet.charAt(x))
        .collect(Collector
            .of(StringBuilder::new, StringBuilder::append,
                StringBuilder::append, StringBuilder::toString));

我们可以使用它来生成这样的字母数字随机字符串(返回的字符串将强制包含一些非数字字符以及一些数字字符):

public String generateRandomString() {
            
    String sampleSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
    String sampleSetNumeric = "0123456789";
    
    String randomString = getRandomString(sampleSet, 10, 21);
    String randomStringNumeric = getRandomString(sampleSetNumeric, 10, 21);
    
    randomString = randomString + randomStringNumeric;
    
    //Convert String to List<Character>
    List<Character> list = randomString.chars()
            .mapToObj(x -> (char)x)
            .collect(Collectors.toList());
    
    Collections.shuffle(list);
    
    //This is needed to force a non-numeric character as the first String
    //Skip this for() if you don't need this logic

    for(;;) {
        if(Character.isDigit(list.get(0))) Collections.shuffle(list);
        else break;
    }
    
    //Convert List<Character> to String
    randomString = list.stream()
            .map(String::valueOf)
            .collect(Collectors.joining());
    
    return randomString;
    
}

//Generate a random number between the lower bound (inclusive) and upper bound (exclusive)
private int getRandomLength(int min, int max) {
    SecureRandom random = new SecureRandom();
    return random.ints(1, min, max).mapToObj(x -> x).reduce((a, b) -> a).get();
}

//Generate a random String from the given sample string, having a random length between the lower bound (inclusive) and upper bound (exclusive)
private String getRandomString(String sampleSet, int min, int max) {
    SecureRandom random = new SecureRandom();
    return random.ints(getRandomLength(min, max), 0, sampleSet.length() - 1)
    .mapToObj(x -> sampleSet.charAt(x))
    .collect(Collector
        .of(StringBuilder::new, StringBuilder::append,
            StringBuilder::append, StringBuilder::toString));
}

答案 46 :(得分:-2)

public class RandomGenerator {
          private static SecureRandom prng;
          private static final Logger LOG = LoggerFactory
                    .getLogger(AuthTokenGenerator.class);
            static {
                try {
                    // Initialize SecureRandom
                    prng = SecureRandom.getInstance("SHA1PRNG");
                } catch (NoSuchAlgorithmException e) {
                    LOG.info("ERROR while intantiating Secure Random:   " + prng);
            }
        }
        /**
         * @return
         */
        public static String getToken() {
            try {
                LOG.info("About to Generate Token in getToken()");
                String token;
                // generate a random number
                String randomNum = Integer.toString(prng.nextInt());
                // get its digest
                MessageDigest sha = MessageDigest.getInstance("SHA-1");
                byte[] result = sha.digest(randomNum.getBytes());
                token = hexEncode(result);
                LOG.info("Token in getToken():   " + token);
                return token;
            } catch (NoSuchAlgorithmException ex) {
                return null;
            }
        }
        /**
         * @param aInput
         * @return
         */
        private static String hexEncode(byte[] aInput) {
            StringBuilder result = new StringBuilder();
            char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
                    'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
            for (byte b : aInput) {
                result.append(digits[(b & 0xf0) >> 4]);
                result.append(digits[b & 0x0f]);
            }
            return result.toString();
        }
}

答案 47 :(得分:-3)

您可以使用这个简单的java函数:

 public class GenerateRandomString {
   private static final String ALPHA_NUM =
           "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   public static void main(String[] args) {
      GenerateRandomString grs = new GenerateRandomString();
      System.out.println(grs.getAlphaNumeric(10));
      System.out.println(grs.getAlphaNumeric(20));
   }
   public String getAlphaNumeric(int len) {
      StringBuffer sb = new StringBuffer(len);
      for (int i=0;  i<len;  i++) {
         int ndx = (int)(Math.random()*ALPHA_NUM.length());
         sb.append(ALPHA_NUM.charAt(ndx));
      }
      return sb.toString();
   }
}

答案 48 :(得分:-7)

你可以这么做:

package gaming;

import java.util.Random;

public class game2 {

public static char c;
public static Random r = new Random();
public static int i = r.nextInt(25);
public static int i2 = r.nextInt(25);
public static int i3 = r.nextInt(25);
public static int i4= r.nextInt(25);
public static int i5 = r.nextInt(25);
public static int num2 = r.nextInt(9);
public static int num3= r.nextInt(9);
public static String s1 = String.valueOf(num2);
public static String s2 = String.valueOf(num3);

public static void main(String[] args){


    System.out.print("The pin is: ");
    changeToString(i);
    System.out.print(c);
    changeToString(i2);
    System.out.print(c);
    changeToString(i3);
    System.out.print(c);
    changeToString(i4);
    System.out.print(c);
    changeToString(i5);
    System.out.print(c);
    System.out.print(s1);
    System.out.print(s2);

}

public static void changeToString(int rand){

    switch (rand){

    case 0:

        c = 'A';
        break;
    case 1:

        c = 'B';
        break;
    case 2:

        c = 'C';
        break;
    case 3:

        c = 'D';
        break;
    case 4:

        c = 'E';
        break;
    case 5:

        c = 'F';
        break;
    case 6:

        c = 'G';
        break;
    case 7:

        c = 'H';
        break;
    case 8:

        c = 'I';
        break;
    case 9:

        c = 'J';
        break;
    case 10:

        c = 'K';
        break;
    case 11:

        c = 'L';
        break;
    case 12:

        c = 'M';
        break;
    case 13:

        c = 'N';
        break;
    case 14:

        c = 'O';
        break;
    case 15:

        c = 'P';
        break;
    case 16:

        c = 'Q';
        break;
    case 17:

        c = 'R';
        break;
    case 18:

        c = 'S';
        break;
    case 19:

        c = 'T';
        break;
    case 20:

        c = 'U';
        break;
    case 21:

        c = 'V';
        break;
    case 22:

        c = 'W';
        break;
    case 23:

        c = 'X';
        break;
    case 24:

        c = 'Y';
        break;
    case 25:

        c = 'Z';
        break;

    }

}
}