By Todd

2008-09-03 02:58:43 8 Comments

I've been looking for a simple Java algorithm to generate a pseudo-random alpha-numeric string. In my situation it would be used as a unique session/key identifier that would "likely" be unique over 500K+ generation (my needs don't really require anything much more sophisticated).

Ideally, I would be able to specify a length depending on my uniqueness needs. For example, a generated string of length 12 might look something like "AEYGF7K0DM1X".


@erickson 2008-09-03 04:04:24


To generate a random string, concatenate characters drawn randomly from the set of acceptable symbols until the string reaches the desired length.


Here's some fairly simple and very flexible code for generating random identifiers. Read the information that follows for important application notes.

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


Usage examples

Create an insecure generator for 8-character identifiers:

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

Create a secure generator for session identifiers:

RandomString session = new RandomString();

Create a generator with easy-to-read codes for printing. The strings are longer than full alphanumeric strings to compensate for using fewer symbols:

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

Use as session identifiers

Generating session identifiers that are likely to be unique is not good enough, or you could just use a simple counter. Attackers hijack sessions when predictable identifiers are used.

There is tension between length and security. Shorter identifiers are easier to guess, because there are fewer possibilities. But longer identifiers consume more storage and bandwidth. A larger set of symbols helps, but might cause encoding problems if identifiers are included in URLs or re-entered by hand.

The underlying source of randomness, or entropy, for session identifiers should come from a random number generator designed for cryptography. However, initializing these generators can sometimes be computationally expensive or slow, so effort should be made to re-use them when possible.

Use as object identifiers

Not every application requires security. Random assignment can be an efficient way for multiple entities to generate identifiers in a shared space without any coordination or partitioning. Coordination can be slow, especially in a clustered or distributed environment, and splitting up a space causes problems when entities end up with shares that are too small or too big.

Identifiers generated without taking measures to make them unpredictable should be protected by other means if an attacker might be able to view and manipulate them, as happens in most web applications. There should be a separate authorization system that protects objects whose identifier can be guessed by an attacker without access permission.

Care must be also be taken to use identifiers that are long enough to make collisions unlikely given the anticipated total number of identifiers. This is referred to as "the birthday paradox." The probability of a collision, p, is approximately n2/(2qx), where n is the number of identifiers actually generated, q is the number of distinct symbols in the alphabet, and x is the length of the identifiers. This should be a very small number, like 2‑50 or less.

Working this out shows that the chance of collision among 500k 15-character identifiers is about 2‑52, which is probably less likely than undetected errors from cosmic rays, etc.

Comparison with UUIDs

According to their specification, UUIDs are not designed to be unpredictable, and should not be used as session identifiers.

UUIDs in their standard format take a lot of space: 36 characters for only 122 bits of entropy. (Not all bits of a "random" UUID are selected randomly.) A randomly chosen alphanumeric string packs more entropy in just 21 characters.

UUIDs are not flexible; they have a standardized structure and layout. This is their chief virtue as well as their main weakness. When collaborating with an outside party, the standardization offered by UUIDs may be helpful. For purely internal use, they can be inefficient.

@ufk 2010-02-03 20:22:54

your expensive way does not work for me! i get cannot find symbol for method BigInteger(int,

@weisjohn 2011-10-07 15:00:05

If you need spaces in yours, you can tack on .replaceAll("\\d", " "); onto the end of the return new BigInteger(130, random).toString(32); line to do a regex swap. It replaces all digits with spaces. Works great for me: I'm using this as a substitute for a front-end Lorem Ipsum

@erickson 2011-10-07 16:02:33

@weisjohn That's a good idea. You can do something similar with the second method, by removing the digits from symbols and using a space instead; you can control the average "word" length by changing the number of spaces in symbols (more occurrences for shorter words). For a really over-the-top fake text solution, you can use a Markov chain!

@Daniel Szalay 2011-12-19 21:55:06

What is the easiest way to make the SecureRandom method produce strings of length 32?

@erickson 2011-12-19 22:26:14

@DanielSzalay Just change the 130 to 160.

@erickson 2011-12-20 00:15:42

These identifiers are randomly selected from space of a certain size. They could be 1 character long. If you want a fixed length, you can use the second solution, with a SecureRandom instance assigned to the random variable.

@ejain 2012-02-21 19:13:40

Why .toString(32) rather than .toString(36)?

@erickson 2012-02-21 21:38:01

@ejain because 32 = 2^5; each character will represent exactly 5 bits, and 130 bits can be evenly divided into characters.

@Thor84no 2012-08-29 15:51:50

@erickson BigInteger.toString(int) doesn't work that way, it's actually calling Long.toString(long, String) to determine the character values (which gives a better JavaDoc description of what it actually does). Essentially doing BigInteger.toString(32) just means you only get characters 0-9 + a-v rather than 0-9 + a-z.

@erickson 2012-08-29 16:25:16

@Thor84no And what did you think I was saying about how it works?

@Thor84no 2012-08-30 00:05:21

@erickson I don't know what you were saying about it, but it seemed to include bits coming in to it, which the BigInteger.toString(int) method never uses. It's using char[]s and I don't see how 130 bits is relevant in any respect. You also seem to be saying using 32 instead of 36 is of some benefit, which I can't see any evidence of either. That's not to say I couldn't be missing something, but your explanation doesn't make it obvious.

@erickson 2012-08-30 04:16:46

@Thor84no Saying that the method doesn't work "that way" implies you have a clear idea of what I was saying, and that what I was saying was wrong. Anyhow, at least 128 bits is preferred for strong security. 25 base-32 digits will only hold 125 bits, so you need 26 base-32 digits. But, 32^26 exactly equals 2^130, so you can squeeze a couple of extra bits in without any additional characters. If you use base 36 instead, you can fit 129 bits into 25 characters, but there is some wasted space (a quarter of a bit).

@sandy 2013-04-18 06:50:43

Which is more preferable first solution or UUID.randomUUID();

@tgkprog 2013-04-30 16:01:25

public String nextString(int lenOfStr) would there be any disadvantages to making a function that takes length as param and moving char[] buf inside that function?

@erickson 2013-04-30 18:23:45

@tgkprog You could definitely do that. You don't need to make buf a local variable though; just change the bounds on the loop and use new String(buf, 0, lenOfStr).

@tgkprog 2013-04-30 18:37:58

i read, long back, that local vars are faster. so i was thinking char[] buf = new char[lenOfStr]; as the first line of the function. that will be safer for multiple threads accessing it too.

@erickson 2013-04-30 20:01:49

A local variable can be faster under certain conditions, but allocating an new array with every call is very likely to erase any speed gains. This code isn't thread safe, but if you made it thread safe by putting the buffer on the stack, you could have contention for the Random instance. I don't know why you'd want to go to the trouble of sharing instances across threads.

@Robert Kang 2014-01-02 18:08:48

Excellent answer, but this only generates numeric values? The original question was about generating random alphanumeric values.

@erickson 2014-01-02 18:44:07

@RobertKang No, both methods produce alphanumeric results. The first, because Java's base-32 representation of numbers includes letters, and the second because the symbol set includes letters.

@Richard Fung 2014-05-01 00:03:25

Can we get an explanation as to why the secure way works?

@erickson 2014-05-01 17:38:40

@Synderesis I added a paragraph. Is that what you were asking?

@Richard Fung 2014-05-01 22:27:01

@erickson Yes thank you very much! Since we are using base 32, does that mean we won't get all the possible letters from a-z? I suppose it doesn't matter from a security perspective, but I just want to make sure my understanding is correct.

@erickson 2014-05-01 22:57:42

@Synderesis That's right, you won't see all the letters in the results. Compactness is a tradeoff: if you are okay with special characters, there's base-64 encoding, or even base-85 encoding that uses a lot of symbols. But if you are using them in URLs, that can be a pain to encode. The general principle is to round up the number of bits so that you use the full capacity of each "digit" in the encoding.

@PT_C 2014-09-12 18:49:13

@erickson I am using this to generate a password of length 11 with lowercase, caps and numbers. Does this ensure that the password will contain at least one of each? if not what are the odds that it doesn't? I'd imagine pretty slim.

@erickson 2014-09-12 19:24:04

@PT_C No, it doesn't ensure that. You'd want to fill sub arrays of the appropriate lengths with characters of each type, then the remainder with characters from all types. Then shuffle the whole array. For example, the first element would be randomly chosen from upper case, next from lower case, next from digit, and the last 8 from the whole set. Then shuffle the positions of the chosen characters with Fisher-Yates. I don't show that here because it's oriented more toward IDs than passwords. I like pass phrases.

@Rodrigo Quesada 2015-05-11 15:52:50

How is the string generated by this code more compact/efficient than another the same length but with all English alphabet letters? Do you understand how text is encoded into bytes and therefor how much space it takes to be stored/transferred? So unless you expect people to store/transfer the generated string using the most compact representation for them in bytes, the string generated by your code is actually wasting space.

@erickson 2015-05-11 16:01:40

@RodrigoQuesada The UUIDs to which my answer refers contain several characters that are not random, reducing their efficiency. As for your comment about "wasting space," relative to what? This question is specifically about alpha-numeric strings, not their encoded form.

@Rodrigo Quesada 2015-05-11 16:19:46

Well, if you are talking about bits, you are implying some form of encoding (hopefully into bytes?). Otherwise it makes no sense to talk about them. In any case, I think you should elaborate more on your answer about under which circumstances what you are stating holds true when implementing it using a programming language (oh yeah, this is a site for programmers btw, and we normally like to encode information into bytes). Also, I think you forgot to add that this question is also about Java.

@erickson 2015-05-11 16:22:29

@RodrigoQuesada No, I'm talking about bits of entropy. How much information does a given string contain? So, check your presumptions, and then see if you can provide a concrete example where another string can pack more entropy into a shorter string of the same alphabet.

@Rodrigo Quesada 2015-05-11 16:45:35

Splendid, I wonder how many people can guess you are completely ignoring real memory/storage usage on this answer, you should be clear about it when giving pure theoretical answers on a Stack Overflow thread (may I suggest an edit of you answer again?) otherwise people might misleadingly think the code you provide (which hopefully you always do for this kind of questions?) is the best option.

@erickson 2015-05-11 16:53:22

@RodrigoQuesada Which solution are you talking about? The first is noted as being "more expensive" because of its increased computation and storage requirements. The second is noted as being more efficient, but less secure. It's faster and it is maximally space efficient given any real-world encoding. Again, I am still looking for a counterexample from you.

@Rodrigo Quesada 2015-05-11 17:21:51

Cool, you probably wanna add what you just stated to your answer then, that might help improving it. As for the counterexample, if you are talking about providing an "example where another string can pack more entropy into a shorter string of the same alphabet", am I wrong in assuming that answer doesn't exist and therefor is stupid waiting for it? In any case, what I'm interested on (well, not so much maybe) is that you clarify this answer (not in the comments, though) so that other people can judge better when analyzing the options.

@Kristian Kraljic 2015-07-03 22:03:33

@DanielSzalay the other answers didn't meet your expectation, even with 160, strings of length 31 could be the result. I have created a small holder class. /* * 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) { String key; while((key=new BigInteger(length*5/*base 32,2^5*/, random).toString(32)).length()<length); return key; } }

@djule5 2015-10-06 23:27:07

@erickson Any specific reason for choosing 130 bits in base 32? Why not use 128 bits in base 16 (hex)? Wouldn't it be similar in terms of security?

@erickson 2015-10-07 04:39:35

@djule5 130 bits in Base32 gives 4x the security in 81% of the space, relative to 128 bits in hexadecimal. But you're right, 130 was rounded up from 128 because 128 bits is considered strong security.

@Iurii 2015-11-06 10:55:26

@erickson Could you please explain the second approach. I tested RandomString class with generation of 10 million strings few times. And every time I receive unique set of strings but as far as I understood correctly your class doesn't guarantee unique sets?

@erickson 2015-11-06 16:39:47

@Iurii Neither approach guarantees unique sets; if they did, they wouldn't be random. However, the second example uses a "linear congruential generator", and by studying successive outputs, one can predict all future outputs. Another problem is that eventually the output repeats. A cryptographic random number generator is designed to avoid these problems so that even if an attacker can observe all of the generated values, she wouldn't be able to predict any future values. Whether this level of security is necessary depends on your application.

@Christian Vielma 2015-11-24 10:57:49

I'm confused about why the number of characters that result from it is always varying. Based that we are generating 130 bits in base 32, shouldn't the resulting strings always have the same length? I'm getting 24-26 character strings.

@erickson 2015-11-24 16:38:55

@ChristianVielma If enough of the highest order bits are all zero, the identifier can be shorter. To force them all to be the same length, you can pad the beginning of the string with zeroes.

@Christian Vielma 2015-11-26 09:20:18

Thanks! @erickson so is it possible to the whole string to be empty if all bits are 0?

@erickson 2015-11-28 02:48:14

@ChristianVielma The string could be "0", but not empty.

@M-D 2016-04-18 15:55:23

I generated a few session ids using this, however, none of them has capital letters (all small letters). Is there a way to include capital letters ? By the way, I am using the first code using SecureRandom.

@iAhmed 2016-05-26 11:25:33

@RobMcZag 2016-12-10 11:11:24

@M-D NO, you cannot get uppercase letters from toString() as the maximum possible radix is 36, i.e. using numbers and lowercase letters. -- from java.lang.Character Javadoc: public static final int MAX_RADIX = 36 The maximum radix available for conversion to and from strings. The constant value of this field is the largest value permitted for the radix argument in radix-conversion methods such as the digit method, the forDigit method, and the toString method of class Integer.

@Michael Böckling 2017-01-05 15:21:34

@erickson you are right that an alphabet of 32 and 130 bits with a resulting string length of 26 is a perfect match and mathematically elegant, but if people simply want short URLs for their tokens maybe using 129 bit and and alphabet of 36 characters makes more sense, if you then get a max. string length of 25? Not that it matters at all, but I think people want the biggest bang (bits) for the buck (string length). Makes sense?

@erickson 2017-01-05 17:32:10

@MichaelBöckling Yes, the first method is written that way more as a consequence of the way BigInteger.toString() works, and it doesn't provide a consistent output length or maximum bits of entropy per character. If you want the best security and best efficiency, I would use the second method, but initialize random with a SecureRandom instance.

@Hack5 2017-07-07 07:41:44

In a one-liner: new BigInteger(130, new SecureRandom()).toString(36) (or change 36 to 62 to include capitals, I think)

@erickson 2017-07-08 03:05:45

@Penn I didn't write it that way originally because seeding a secure RNG has, in various versions Java, been a blocking operation that can lead to blocking for several minutes as the system entropy is depleted. In current versions, this should be okay unless someone has explicitly (and misguided-ly) selected the blocking RNG

@DaBlick 2017-09-21 18:36:09

One minor gripe about the code - making buf a field rather than a local variable makes this non-reentrant. Better, IMHO, to make buf a local variable within the nextString() method.

@erickson 2017-09-21 18:41:15

@DaBlick Of course. This is an illustration to be adapted to specific requirements. If you want to use it as is, recognize that it's written for efficient use by a single thread.

@Aekansh Dixit 2018-01-31 12:48:34

I want to store this unique value inside a string. I am calling RandomString session = new RandomString(); and then session.toString() is not giving me a string! How do I access the string?

@erickson 2018-01-31 14:22:49

@AekanshDixit String sessionId = session.nextString(); Keep the generator instance, and keep using it to generate new IDs whenever you need.

@Riley Jones 2019-12-07 06:23:33

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

I used a very primitive algorithm using Math.random(). To increase randomness, you can directly implement the util.Date class. Nevertheless, it works.

@patrickf 2017-05-28 12:06:11

This is easily achievable without any external libraries.

1. Cryptographic Pseudo Random Data Generation

First you need a cryptographic PRNG. Java has SecureRandom for that and typically uses the best entropy source on the machine (e.g. /dev/random) . Read more here.

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

Note: SecureRandom is the slowest, but most secure way in Java of generating random bytes. I do however recommend NOT considering performance here since it usually has no real impact on your application unless you have to generate millions of tokens per second.

2. Required Space of Possible Values

Next you have to decide "how unique" your token needs to be. The whole and only point of considering entropy is to make sure that the system can resist brute force attacks: the space of possible values must be so large that any attacker could only try a negligible proportion of the values in non-ludicrous time1. Unique identifiers such as random UUID have 122bit of entropy (ie. 2^122 = 5.3x10^36) - the chance of collision is "*(...) for there to be a one in a billion chance of duplication, 103 trillion version 4 UUIDs must be generated2". We will choose 128 bit since it fits exactly into 16 bytes and is seen as highly sufficient for being unique for basically every, but the most extreme, use cases and you don't have to think about duplicates. Here is a simple comparison table of entropy including simple analysis of the birthday problem.

comparison of token sizes

For simple requirements 8 or 12 byte length might suffice, but with 16 bytes you are on the "safe side".

And that's basically it. Last thing is to think about encoding so it can be represented as a printable text (read, a String).

3. Binary to Text Encoding

Typical encodings include:

  • Base64 every character encodes 6bit creating a 33% overhead. Fortunately there are standard implementations in Java 8+ and Android. With older Java you can use any of the numerous third party libraries. If you want your tokens to be url safe use the url-safe version of RFC4648 (which usually is supported by most implementations). Example encoding 16 bytes with padding: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32 every character encodes 5bit creating a 40% overhead. This will use A-Z and 2-7 making it reasonably space efficient while being case-insensitive alpha-numeric. There is no standard implementation in the JDK. Example encoding 16 bytes without padding: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16 (hex) every character encodes 4bit requiring 2 characters per byte (ie. 16 byte create a string of length 32). Therefore hex is less space efficient than Base32 but is safe to use in most cases (url) since it only uses 0-9 and A to F. Example encoding 16 bytes: 4fa3dd0f57cb3bf331441ed285b27735. See a SO discussion about converting to hex here.

Additional encodings like Base85 and the exotic Base122 exist with better/worse space efficiency. You can create your own encoding (which basically most answers in this thread do) but I would advise against it, if you don't have very specific requirements. See more encoding schemes in the Wikipedia article.

4. Summary and Example

  • Use SecureRandom
  • Use at least 16 bytes (2^128) of possible values
  • Encode according to your requirements (usually hex or base32 if you need it to be alpha-numeric)


  • ... use your home brew encoding: better maintainable and readable for others if they see what standard encoding you use instead of weird for loops creating chars at a time.
  • ... use UUID: it has no guarantees on randomness; you are wasting 6bits of entropy and have verbose string representation

Example: Hex Token Generator

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

//generateRandomHexToken(16) -> 2189df7475e96aa3982dbeab266497cd

Example: Base64 Token Generator (Url Safe)

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

//generateRandomBase64Token(16) -> EEcCCAYuUcQk7IuzdaPzrg

Example: Java CLI Tool

If you want a ready-to-use cli tool you may use dice:

Example: Related issue - Protect Your Current Ids

If you already have an id you can use (e.g. a synthetic long in your entity), but don't want to publish the internal value, you can use this library to encrypt it and obfuscate it:

IdMask<Long> idMask = IdMasks.forLongIds(Config.builder(key).build());
String maskedId = idMask.mask(id);
//example: NPSBolhMyabUBdTyanrbqT8
long originalId = idMask.unmask(maskedId);

@francoisr 2017-07-11 07:50:45

This answer is complete and works without adding any dependency. If you want to avoid possible minus signs in the output, you can prevent negative BigIntegers using a constructor parameter: BigInteger(1, token) instead of BigInteger(token).

@patrickf 2017-07-11 08:38:39

Tanks @francoisr for the hint, I edited the code example

@anothermh 2018-10-04 01:45:45

import; and import java.math.BigInteger; are needed to make the example work, but it works great!

@Prasad Parab 2018-08-17 13:05:11

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

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

        return randomStr;

@Incinerator 2019-08-29 13:19:51

Really nice! But it should be length instead of chars.length in the for loop: for (int i = 0; i < length; i++)

@SoBeRich 2019-03-27 12:14:17

Efficent and short.

 * 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) {
            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:
            int numberOfChars = charCount(codePoint);
            if (count == 0 && numberOfChars > 1) { count++; continue; }
            if (letters && isLetter(codePoint)
                || numbers && isDigit(codePoint)
                || !letters && !numbers) {
                if (numberOfChars == 2) count--;
            } else count++;
        return builder.toString();


@mike 2019-02-27 13:52:23

Here is a Java 8 solution based on streams.

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

        return sb.toString();

Use it like

String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int length = 12;
String generated = generateString(alphabet, length);

The function nextInt should accept an int bound and return a random number between 0 and bound - 1.

@user_3380739 2016-11-28 20:25:45

Here is the one line code by AbacusUtil

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

Random doesn't mean it must be unique. to get unique strings, using:

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

@FileInputStream 2018-11-26 18:31:13

I think this is the smallest solution here, or nearly one of the smallest:

 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;

The code works just fine. If you are using this method, i recommend you to use more than 10 characters. Collision happens at 5 characters / 30362 iterations. This took 9 seconds.

@Howard Lovatt 2014-11-25 07:23:10

An alternative in Java 8 is:

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)

@Dan 2015-06-23 14:08:13

That's great - but if you want to keep it to strictly alphanumeric (0-9, a-z, A-Z) see here…

@duggu 2012-12-24 12:41:23

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

@erickson 2013-10-04 05:36:49

That string concatenation is unnecessarily inefficient. And the crazy indentation makes your code nearly unreadable. This is the same as Jamie's idea, but poorly executed.

@user unknown 2012-04-17 10:08:46

A short and easy solution, but uses only lowercase and numerics:

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

The size is about 12 digits to base 36 and can't be improved further, that way. Of course you can append multiple instances.

@Ray Hulha 2013-01-27 02:12:03

Just keep in mind, that there is a 50 % chance of a minus sign infront of the result ! So wrapping r.nextLong() in a Math.abs() can be used, if you don't want the minus sign: Long.toString(Math.abs(r.nextLong()), 36);

@user unknown 2013-01-27 13:28:49

@RayHulha: If you don't want the minus sign, you should cut it off, because, surprisingly, Math.abs returns a negative value for Long.MIN_VALUE.

@Phil 2013-11-10 20:34:20

Interesting the Math.abs returning negative. More here:…

@Radiodef 2018-04-02 23:27:35

The issue with abs is solved by using a bitwise operator to clear the most significant bit. This will work for all values.

@shmosel 2018-04-02 23:35:00

@Radiodef That's essentially what @userunkown said. I suppose you could also do << 1 >>> 1.

@aaronvargas 2018-03-01 19:01:33

Here's a simple one-liner using UUIDs as the character base and being able to specify (almost) any length. (Yes, I know that using a UUID has been suggested before)

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

@Patrik Bego 2018-02-21 15:29:56

Don't really like any of this answers regarding "simple" solution :S

I would go for a simple ;), pure java, one liner (entropy is based on random string length and the given character set):

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

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

or (a bit more readable old way)

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

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

But on the other hand you could also go with UUID which has a pretty good entropy (

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

Hope that helps.

@cmsherratt 2008-09-04 11:14:46

If you're happy to use Apache classes, you could use org.apache.commons.text.RandomStringGenerator (commons-text).


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

Since commons-lang 3.6, RandomStringUtils is deprecated.

@Yuriy Nakonechnyy 2014-04-03 14:51:29

Has just looked through mentioned class of Apache Commons Lang 3.3.1 library - and it is using only java.util.Random to provide random sequences, so it is producing insecure sequences.

@Ruslans Uralovs 2015-03-03 13:28:02

Make sure you use SecureRandom when using RandomStringUtils: public static java.lang.String random(int count, int start, int end, boolean letters, boolean numbers, @Nullable char[] chars, java.util.Random random)

@patrickf 2019-04-04 13:03:27

DO NOT USE. This creates insecure sequences!

@Amar Nath Batta 2009-06-19 08:36:46

I have developed an application to develop an auto generated alphanumberic string for my project. In this string, the first three chars are alphabetical and the next seven are integers.

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;
                    if (i != 90) {
                        n = i * 10 + r.nextInt(10);
                        while (n < 65) {
                            n = i * 10 + r.nextInt(10);


            str= String.valueOf(c)+str;
        i = r.nextInt(10000000);


@Steve McLeod 2008-09-03 14:18:30

Java supplies a way of doing this directly. If you don't want the dashes, they are easy to strip out. Just use uuid.replace("-", "")

import java.util.UUID;

public class randomStringGenerator {
    public static void main(String[] args) {

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


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

@Dave 2011-05-05 09:28:17

Beware that this solution only generates a random string with hexadecimal characters. Which can be fine in some cases.

@erickson 2011-08-24 16:37:45

The UUID class is useful. However, they aren't as compact as the identifiers produced by my answers. This can be an issue, for example, in URLs. Depends on your needs.

@Ruggs 2011-09-06 00:13:44

If you're worried about the hexadecimal characters just run in through a cryptographic hash algorithm.

@erickson 2011-10-07 16:18:53

@Ruggs - The goal is alpha-numeric strings. How does broadening the output to any possible bytes fit with that?

@Somatik 2012-12-31 11:31:04

According to RFC4122 using UUID's as tokens is a bad idea: Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example. A predictable random number source will exacerbate the situation.

@Drew S 2013-11-14 17:04:56

@Somatik - So what should you use instead of UUIDs?

@Somatik 2013-11-15 08:22:46

@TheDrizzle I suppose one of the other high-scoring answers

@Numid 2014-01-22 09:58:08

UUID.randomUUID().toString().replaceAll("-", ""); makes the string alpha-numeric, as requested.

@Patrick Bergner 2014-02-11 14:33:19

@Numid I have never seen something between g and z in a UUID.

@Numid 2014-02-12 07:09:37

@PatrickBergner is right. The suggestion above only produces a sequence of hexadecimal digits.

@uriel 2015-05-02 19:46:22

What about MD5 on this output? It's should be more difficult to guess.

@ThePyroEagle 2015-12-24 11:24:19

Just use base 64 if you want it to be hashed and alpha-numeric.

@Micro 2016-02-08 01:10:21

@Somatik UUID.randomUUID() actually uses SecureRandom. Still might not be a good idea if you want 128bit encryption. You will only get 122bits of random:…

@Charles Follet 2017-01-03 13:44:53

This will generate a 36 characters string. (32 hex digits + 4 dashes), not more.

@deepakmodak 2014-02-06 13:15:18

  1. Change String characters as per as your requirements.

  2. String is immutable. Here StringBuilder.append is more efficient than string concatenation.

public static String getRandomString(int length) {
       final String characters = "[email protected]#$%^&*()_+";
       StringBuilder result = new StringBuilder();
       while(length > 0) {
           Random rand = new Random();
       return result.toString();

@erickson 2014-02-10 05:17:52

This adds nothing the dozens of answers given previously didn't cover. And creating a new Random instance in each iteration of the loop is inefficient.

@kyxap 2017-07-01 23:52:57

Also you can generate any lower or UPPER case Letters or even special chars thought data from ASCII table. For example, generate upper case letters from A (DEC 65) to 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;

Generated output for generateRandomStr(65, 90, 100));:


@user5138430 2016-08-04 20:28:17

Maybe this is helpful

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;

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

        for(int i=0; i<len;i++){
      return password;


@michaelok 2011-09-09 21:23:10

You mention "simple", but just in case anyone else is looking for something that meets more stringent security requirements, you might want to take a look at jpwgen. jpwgen is modeled after pwgen in Unix, and is very configurable.

@michaelok 2017-06-26 22:50:50

Thanks, fixed it. So it least there is source and the link is valid. On the downside, it doesn't look like it has been updated in a while, though I see pwgen has been updated fairly recently.

@Kristian Kraljic 2015-07-03 22:07:48

Using UUIDs is insecure, because parts of the UUID arn't random at all. The procedure of @erickson is very neat, but does not create strings of the same length. The following snippet should be sufficient:

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

Why choosing length*5. Let's assume the simple case of a random string of length 1, so one random character. To get a random character containing all digits 0-9 and characters a-z, we would need a random number between 0 and 35 to get one of each character. BigInteger provides a constructor to generate a random number, uniformly distributed over the range 0 to (2^numBits - 1). Unfortunately 35 is no number which can be received by 2^numBits - 1. So we have two options: Either go with 2^5-1=31 or 2^6-1=63. If we would choose 2^6 we would get a lot of "unnecesarry" / "longer" numbers. Therefore 2^5 is the better option, even if we loose 4 characters (w-z). To now generate a string of a certain length, we can simply use a 2^(length*numBits)-1 number. The last problem, if we want a string with a certain length, random could generate a small number, so the length is not met, so we have to pad the string to it's required length prepending zeros.

@Julian Suarez 2016-03-09 16:56:27

could you explain better the 5?

@maxp 2008-10-01 11:36:54

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

@Jonik 2012-04-20 15:49:23

+1, the simplest solution here for generating a random string of specified length (apart from using RandomStringUtils from Commons Lang).

@foens 2014-06-25 13:34:44

Consider using SecureRandom instead of the Random class. If passwords are generated on a server, it might be vulnerable to timing attacks.

@ACV 2015-09-07 20:56:11

I would add lowercase also: AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw‌​xyz"; and some other allowed chars.

@Robert Martin 2016-01-06 21:46:48

Thanks! I added the lowercase letters and some special characters as well.

@Micro 2016-02-08 01:25:50

Why not put static Random rnd = new Random(); inside the method?

@cassiomolin 2016-02-15 10:49:55

@MicroR Is there a good reason to create the Random object in each method invocation? I don't think so.

@iAhmed 2016-05-26 11:25:19

@dfa 2010-02-01 17:12:41

using Dollar should be simple as:

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

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

public void buildFiveRandomStrings() {
    for (int i : $(5)) {

it outputs something like that:


@iwein 2016-11-16 10:58:23

is it possible to use SecureRandom with shuffle?

@anonymous 2009-09-17 15:22:57

In one line:


@Moshe Revah 2011-01-11 09:45:12

But only 6 letters :(

@noquery 2011-09-05 05:31:46

It helped me too but only hexadecimal digits :(

@daniel.bavrin 2014-05-17 15:10:10

@Zippoxer, you could concat that several times =)

@hfontanez 2014-11-20 02:31:59

The OP's example showed the following String as an example AEYGF7K0DM1X which is not hexadecimal. It worries me how often people mistake alphanumeric with hexadecimal. They are not the same thing.

@jcesarmobile 2015-01-16 08:34:45

@daniel.bavrin, Zippoxer means hexadecimal string has only 6 letters (ABCDEF). He is not talking about the length, it doesn't matter how many times you concat

@maaartinus 2015-07-22 01:13:22

This is much less random than it should be given the string length as Math.random() produces a double between 0 and 1, so the exponent part is mostly unused. Use random.nextLong for a random long instead of this ugly hack.

@Prasobh.Kollattu 2012-11-01 05:43:49

You can use following code , if your password mandatory contains numbers alphabetic special characters:

private static final String NUMBERS = "0123456789";
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++) {
        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)));
        case 1:
            randomChar.append(UPPER_ALPHABETS.charAt(randomNum.nextInt(UPPER_ALPHABETS.length() - 1)));
        case 2:
            randomChar.append(SPECIALCHARACTERS.charAt(randomNum.nextInt(SPECIALCHARACTERS.length() - 1)));
        case 3:
            randomChar.append(LOWER_ALPHABETS.charAt(randomNum.nextInt(LOWER_ALPHABETS.length() - 1)));
    return randomChar.toString();


@Suganya 2011-06-30 05:34:20

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

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


    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++){
            System.out.println("  "+sb.toString());

@Jameskittu 2011-10-19 04:36:44

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

      String out = "";

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

@Todd 2008-09-03 14:22:23

I found this solution that generates a random hex encoded string. The provided unit test seems to hold up to my primary use case. Although, it is slightly more complex than some of the other answers provided.

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


    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));
            buffer.append((char) ('A' + (b1 - 10)));
        if (b2 < 10)
            buffer.append((char) ('0' + b2));
            buffer.append((char) ('A' + (b2 - 10)));
    return (buffer.toString());

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{

@Thom Wiggers 2012-06-02 15:22:33

I don't think it is fair to fail for duplicate tokens which is purely based on probability.

@manish_s 2012-07-20 10:23:18

You can use Apache library for this: RandomStringUtils


@kml_ckr 2012-09-24 11:31:04

Is this function guarantee to generate unique results if called at different times

@Inshallah 2012-09-26 10:14:26

@kamil, I looked at the source code for RandomStringUtils, and it uses an instance of java.util.Random instantiated without arguments. The documentation for java.util.Random says it uses current system time if no seed is provided. This means that it can not be used for session identifiers/keys since an attacker can easily predict what the generated session identifiers are at any given time.

@Ajeet Ganga 2013-10-13 23:36:41

@Inshallah : You are (unnecessarily) overengineering the system. While I agree that it uses time as seed, the attacker has to have the access to following data to to actually get what he wants 1. Time to the exact millisecond, when the code was seeded 2. Number of calls that have occurred so far 3. Atomicity for his own call (so that number of calls-so-far ramains same) If your attacker has all three of these things, then you have much bigger issue at hand...

@manish_s 2014-10-17 16:57:31

Just random. The probability of collision is very less.

@younes0 2015-01-19 14:35:30

gradle dependency: compile 'commons-lang:commons-lang:2.6'

@Thomas Grainger 2016-12-20 13:52:09

@Ajeet this isn't true. You can derive the state of the random number generator from its output. If an attacker can generate a few thousand calls to generate random API tokens the attacker will be able to predict all future API tokens.

@patrickf 2017-09-19 10:37:55

@AjeetGanga Nothing to do with over engineering. If you want to create session ids, you need a cryptographic pseudo random generator. Every prng using time as seed is predictable and very insecure for data that should be unpredictable. Just use SecureRandom and you are good.

@numéro6 2017-10-17 09:31:03

Since commons-lang 3.6, RandomStringUtils is deprecated in favor of RandomStringGenerator of commons-text

@Steven L 2014-12-08 01:41:10

Yet another solution..

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

Related Questions

Sponsored Content

58 Answered Questions

[SOLVED] How do I read / convert an InputStream into a String in Java?

85 Answered Questions

[SOLVED] How do I make the first letter of a string uppercase in JavaScript?

65 Answered Questions

[SOLVED] How do I generate random integers within a specific range in Java?

  • 2008-12-12 18:20:57
  • user42155
  • 3922989 View
  • 3383 Score
  • 65 Answer
  • Tags:   java random integer

42 Answered Questions

[SOLVED] How do I convert a String to an int in Java?

59 Answered Questions

[SOLVED] How to replace all occurrences of a string?

65 Answered Questions

[SOLVED] What is the difference between String and string in C#?

3 Answered Questions

32 Answered Questions

[SOLVED] How do I generate a random int number?

  • 2010-04-24 23:09:11
  • Rella
  • 2171859 View
  • 1803 Score
  • 32 Answer
  • Tags:   c# random

15 Answered Questions

[SOLVED] Why does this code using random strings print "hello world"?

  • 2013-03-03 04:38:06
  • 0x56794E
  • 194730 View
  • 1735 Score
  • 15 Answer
  • Tags:   java string random

65 Answered Questions

[SOLVED] Generate random string/characters in JavaScript

  • 2009-08-28 21:14:41
  • Tom Lehman
  • 1234717 View
  • 1613 Score
  • 65 Answer
  • Tags:   javascript random

Sponsored Content