当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何生成随机字母数字字符串?》经验,为你挑选了21个好方法。

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

理想情况下,我可以根据我的唯一性需求指定长度.例如,生成的长度为12的字符串可能看起来像"AEYGF7K0DM1X".



1> erickson..:

算法

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

履行

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

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或更少.

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

与UUID的比较

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

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

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


@ejain因为32 = 2 ^ 5; 每个字符恰好代表5位,130位可以均匀分成字符.
为什么.toString(32)而不是.toString(36)?
我试过了,但有时它只有31长.
如果你需要空格,你可以将`.replaceAll("\\ d","");`放到`return new BigInteger(130,random).toString(32);`line to do的末尾.正则表达式交换.它用空格替换所有数字.对我来说很有用:我用这个作为前端Lorem Ipsum的替代品
@weisjohn那是个好主意.您可以使用第二种方法执行类似操作,方法是删除`symbols`中的数字并使用空格; 您可以通过更改符号中的空格数来控制平均"单词"长度(更短的单词出现次数).对于一个非常过分的假文本解决方案,您可以使用马尔可夫链!
这些标识符是从特定大小的空间中随机选择的.它们可能是1个字符长.如果你想要一个固定长度,你可以使用第二个解决方案,将`SecureRandom`实例分配给`random`变量.
@erickson`BigInteger.toString(int)`不起作用,它实际上调用`Long.toString(long,String)`来确定字符值(它给出了一个更好的JavaDoc描述它实际上做了什么).基本上做`BigInteger.toString(32)`只是意味着你只能获得字符`0-9` +`av`而不是'0-9` +`az`.
@DanielSzalay只需将130更改为160.

2> Steve McLeod..:

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


根据RFC4122使用UUID作为令牌是一个坏主意:不要认为UUID难以猜测; 例如,它们不应被用作安全功能(仅仅拥有访问权限的标识符).可预测的随机数源将加剧这种情况.http://www.ietf.org/rfc/rfc4122.txt
`UUID.randomUUID().toString().replaceAll(" - ","");`根据请求使字符串为字母数字.
请注意,此解决方案仅生成具有十六进制字符的随机字符串.在某些情况下可以没问题.
@Ruggs - 目标是*字母数字字符串.*如何将输出扩展到任何可能的字节?
UUID类很有用.但是,它们不像我的答案所产生的标识符那么紧凑.这可能是一个问题,例如,在URL中.取决于您的需求.
@Numid我从未在UUID中看到g和z之间的某些内容.
如果你想要它是哈希和字母数字,只需使用base 64.

3> maxp..:
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();
}


+1,这里用于生成指定长度*的随机字符串*的最简单的解决方案(除了使用Commons Lang的RandomStringUtils).
考虑使用`SecureRandom`而不是`Random`类.如果在服务器上生成密码,则可能容易受到计时攻击.
我还要添加小写:`AB ="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";`和其他一些允许的字符.
@MicroR是否有充分的理由在每个方法调用中创建`Random`对象?我不这么认为.

4> cmsherratt..:

如果您乐意使用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不推荐使用.


刚看过**提到的'Apache Commons Lang 3.3.1`库的类** - 它只使用`java.util.Random`来提供随机序列,因此它产生**不安全的序列**.
确保在使用RandomStringUtils时使用SecureRandom:`public static java.lang.String random(int count,int start,int end,boolean letters,boolean numbers,@ Nullable char [] chars,java.util.Random random)`

5> 小智..:

在一行中:

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

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


但只有6个字母:(
OP的示例显示以下字符串作为示例"AEYGF7K0DM1X",它不是十六进制的.它让我担心人们常常误用十六进制的字母数字.它们不是同一件事.
由于`Math.random()`在0和1之间产生一个"double",因此它的随机性远小于它应该给出的字符串长度,所以指数部分大部分都是未使用的.使用`random.nextLong`作为随机的`long`而不是这个丑陋的黑客.
它也帮了我,但只有十六进制数字:(

6> manish_s..:

您可以使用Apache库:RandomStringUtils

RandomStringUtils.randomAlphanumeric(20).toUpperCase();


@Inshallah:你(不必要地)过度使用系统.虽然我同意它使用时间作为种子,但攻击者必须能够访问以下数据才能真正得到他想要的内容1.时间到精确毫秒,代码播种时2.到目前为止发生的调用次数3.他自己的电话的原子性(所以电话的数量 - 到目前为止仍然相同)如果你的攻击者拥有所有这三件事,那么你手头有更大的问题......
@kamil,我查看了RandomStringUtils的源代码,它使用了一个没有参数实例化的java.util.Random实例.java.util.Random的文档说如果没有提供种子,它会使用当前系统时间.这意味着它不能用于会话标识符/密钥,因为攻击者可以在任何给定时间轻松预测生成的会话标识符是什么.
@Ajeet这不是真的.您可以从其输出中导出随机数生成器的状态.如果攻击者可以生成几千个调用来生成随机API令牌,则攻击者将能够预测所有未来的API令牌.
gradle依赖:`compile'c​​ommons-lang:commons-lang:2.6'`
@AjeetGanga与工程无关。如果要创建会话ID,则需要一个加密的伪随机生成器。每个使用时间作为种子的项目都是可预测的,并且对于应该不可预测的数据非常不安全。只需使用`SecureRandom`就可以了。

7> patrickf..:

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

1.加密伪随机数据生成

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

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个字节,并且被认为非常适合于基本上每个但是最极端的用例都是唯一的,并且您不必考虑重复.这是一个简单的熵比较表,包括对生日问题的简单分析.

令牌大小的比较

对于简单的要求,8或12字节长度可能就足够了,但是对于16字节,您处于"安全方".

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

3.二进制到文本编码

典型编码包括:

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

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

Base32(十六进制)每个字符编码4bit,每字节需要2个字符(即16字节创建一个长度为32的字符串).因此十六进制的空间小于有效的0-9,但安全的,因为它在大多数情况下(URL)仅使用用途AF4fa3dd0f57cb3bf331441ed285b27735.编码16字节的示例:SecureRandom.请参阅此处有关转换为十六进制的SO讨论.

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

4.总结和例子

使用 hex

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

根据您的要求进行编码(通常base32或者long如果您需要它是字母数字)

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

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


这个答案是完整的,并且无需添加任何依赖即可使用。如果要避免在输出中出现负号,可以使用构造函数参数BigInteger(1,token)而不是BigInteger(token)来防止使用负数BigInteger。

8> dfa..:

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



9> Apocalisp..:

在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


所有这些双重感染的随机int生成都被设计破坏,缓慢且不可读.使用`Random#nextInt`或`nextLong`.如果需要,切换到`SecureRandom`.
这将产生**不安全的序列**即可以容易猜到的序列.

10> Michael Alle..:

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

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记录容易.


[有人提出建议,](http://stackoverflow.com/a/41762/3474)大约一年前.

11> user unknown..:

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

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

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


请记住,结果前面有一个减号的可能性为50%!因此,如果你不想要减号,可以使用在Math.abs()中包装r.nextLong():`Long.toString(Math.abs(r.nextLong()),36);`
@RayHulha:如果你不想要减号,你应该把它剪掉,因为,令人惊讶的是,Math.abs为Long.MIN_VALUE返回一个负值.

12> Howard Lovat..:

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


这很好 - 但是如果你想把它保持在严格的字母数字(0-9,az,AZ),请参见http://www.rationaljava.com/2015/06/java8-generate-random-string-in-one- line.html

13> 小智..:
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



14> Kristian Kra..:

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



15> 小智..:
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);
    }
}

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



16> Todd..:

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

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



17> Jameskittu..:
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



18> deepakmodak..:

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

    字符串是不可变的.这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();
    }


这没有增加先前未提及的数十个答案.并且在循环的每次迭代中创建新的"Random"实例是低效的.

19> 小智..:
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



20> Patrik Bego..:

对于"简单"的解决方案,我真的不喜欢这些答案: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):

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

希望有所帮助.



21> michaelok..:

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

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有