提问



我一直在寻找一个简单的 Java算法来生成一个伪随机字母数字字符串。在我的情况下,它将被用作一个唯一的会话/密钥标识符,它可能是唯一的500K +代(我的需求并不需要更复杂的东西)。理想情况下,我可以根据我的唯一性需求指定长度。例如,生成的长度为12的字符串可能类似于"AEYGF7K0DM1X"

最佳参考


算法



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


实施



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


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应用程序中一样。应该有一个单独的授权系统来保护攻击者可以在没有访问权限的情况下猜出其标识符的对象。


还必须注意使用足够长的标识符,以便在给定预期的标识符总数的情况下不太可能发生冲突。这被称为生日悖论。碰撞的概率 p 大约是n 2 /(2q x ),其中 n 是实际生成的标识符数量, q 是字母表中不同符号的数量, x 是标识符的长度。这应该是一个非常小的数字,如2 -50 或更少。[74]


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


与UUID的比较



根据他们的规范,UUID不是不可预测的,不应该用作会话标识符。


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


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

其它参考1


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


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


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


例:


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


在一行中:


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



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


其它参考5


您可以使用Apache库:RandomStringUtils [77]


RandomStringUtils.randomAlphanumeric(20).toUpperCase();

其它参考6


使用Dollar应该很简单:[78]


// "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

其它参考7


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


1。加密伪随机数据生成



首先,您需要加密PRNG。 Java SecureRandom通常使用机器上的最佳熵源(例如/dev/random)。在这里阅读更多。[79] [80]


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


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


2。可能值的所需空间



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


[86]


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


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


3。二进制到文本编码



典型编码包括:



  • Base64每个字符编码6bit,产生33%的开销。遗憾的是,JDK中没有标准实现( 7及以下 - 有Android和Java 8+)。但是存在许多添加此功能的库。缺点是,标准Base64对于例如不安全。 urls和作为大多数文件系统中的文件名需要额外的编码(例如url编码)或使用URL安全版本的Base64。使用填充编码16个字节的示例:XfJhfv3C0P6ag7y9VQxSbw== [87] [88] [89] [92]

  • Base32每个字符编码5bit,产生40%的开销。这将使用A-Z2-7使其合理地节省空间,同时不区分大小写的字母数字。 JDK中没有标准实现。示例编码16个字节而不填充:WUPIL5DQTZGMF4D3NX5L7LNFOY [93]

  • Base16(hex)每个字符编码4bit,每个字节需要2个字符(即16字节创建一个长度为32的字符串)。因此,hex比Base32的空间效率低,但在大多数情况下(url)使用是安全的,因为它只使用0-9AF。编码16字节的示例:4fa3dd0f57cb3bf331441ed285b27735。请参阅这里有关转换为十六进制的SO讨论。[95]



其他编码如Base85和异国情调的Base122存在更好/更差的空间效率。你可以创建自己的编码(基本上这个线程中的大多数答案都可以),但如果你没有非常具体的要求,我会反对它。请参阅维基百科文章中的更多编码方案。[97] [98] [99]


4。摘要和示例




  • 使用SecureRandom

  • 使用至少16个字节(2 ^ 128)的可能值

  • 根据您的要求进行编码(如果您需要字母数字,通常为hexbase32



唐T [100]



  • ...使用你的家庭酿造编码:对于其他人来说,如果他们看到你使用的标准编码而不是奇怪的循环创建字符,那么其他人可以更好地维护和阅读。

  • ...使用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


示例:工具



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

其它参考8


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


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[102]


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

其它参考9


在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

其它参考10


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


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


大小约为12位数到36位,并且不能进一步改进。当然,你可以附加多个实例。

其它参考11


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)
        .mapToObj((i) -> (char) i)
        .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
        .toString();
}

其它参考12


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

其它参考13


使用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和字符az的随机字符,我们需要一个0到35之间的随机数来获得每个字符之一character BigInteger提供了一个构造函数来生成一个随机数,均匀分布在0 to (2^numBits - 1)范围内。不幸的是35不是2 ^ numBits可以接收的数字 - 1.所以我们有两个选择:选择2^5-1=312^6-1=63。如果我们选择2^6,我们会得到很多不必要的/更长的数字。因此2^5是更好的选择,甚至如果我们松开4个字符(wz)。现在生成一定长度的字符串,我们可以简单地使用2^(length*numBits)-1数字。最后一个问题,如果我们想要一个具有一定长度的字符串,随机可以生成一个小的数字,所以长度不符合,所以我们必须将字符串填充到它所需的长度前置零。

其它参考14


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


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


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

其它参考16


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



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

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



点击


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

其它参考18


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

其它参考19


不要对简单解决方案的任何答案感到满意:S


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


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


或者(有点可读的旧方式)


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


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


UUID.randomUUID().toString().replace("-", "")


希望有所帮助。

其它参考20


这是一个Scala解决方案:


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

其它参考21


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


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

}

其它参考22


这是AbacusUtil [104]的一行代码


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 '-'

其它参考23


你提到简单,但为了防止其他人正在寻找满足更严格的安全要求的东西,你可能想看看jpwgen。 jpwgen在Unix中以pwgen为模型,并且非常可配置。[105] [106]

其它参考24


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

其它参考25


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


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


这里是文档http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/RandomStringUtils.html [107]

其它参考26


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


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


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

其它参考27


也许这很有帮助


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;

    }
}

其它参考28


最佳随机串生成器方法


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

}

其它参考29


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