Generate an alpha-numeric string randomly

0 votes

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"

Apr 18, 2018 in Java by parth295
• 4,600 points
132 views

2 answers to this question.

0 votes

Algorithm

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

Implementation

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

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

}

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.

answered Apr 18, 2018 by Rishabh
• 3,540 points
0 votes
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) {
        System.out.println(generateString());
    }

    public static String generateString() {
        String uuid = UUID.randomUUID().toString();
        return "uuid = " + uuid;
    }
}
answered Jul 18, 2018 by Daisy
• 8,040 points

Related Questions In Java

0 votes
1 answer

How can I convert an 'ArrayList<String> to 'String[]' in Java

List<String> list = new ArrayList<String>(); String[] array = ...READ MORE

answered Apr 20, 2018 in Java by Daisy
• 8,040 points
115 views
0 votes
1 answer

what is the best way to convert an ArrayList to a String

String lString = String.join(", ", list); In case ...READ MORE

answered Apr 26, 2018 in Java by developer_1
• 3,280 points
38 views
0 votes
1 answer

How to convert an int array to string using tostring method in java?

you want to use the Arrays.toString(int[]) method: import java.util.Arrays; int[] array ...READ MORE

answered Jun 7, 2018 in Java by Akrati
• 3,150 points
161 views
0 votes
2 answers

How an object array can be converted to string array in java?

System.arraycopy is the most efficient way, but ...READ MORE

answered Aug 8, 2018 in Java by Sushmita
• 6,840 points
77 views
0 votes
3 answers

Check if a String is numeric in Java

Java 8 Lambda Expression is used: String someString ...READ MORE

answered Sep 3, 2018 in Java by Daisy
• 8,040 points
564 views
0 votes
1 answer

How do I create a Java string from the contents of a file?

If you're looking for an alternative that ...READ MORE

answered Apr 19, 2018 in Java by Rishabh
• 3,540 points
73 views
0 votes
2 answers

Counting no of Occurrence of a particular character inside a string in Java

We can find out the no. of ...READ MORE

answered Sep 7, 2018 in Java by Sushmita
• 6,840 points
190 views
0 votes
2 answers

What is the use of toString method in Java and how can I use it ?

Whenever you require to explore the constructor ...READ MORE

answered Aug 23, 2018 in Java by Daisy
• 8,040 points
310 views
0 votes
2 answers

How do I read and convert an InputStream object to string type?

You can also use Java Standard Library ...READ MORE

answered Jul 17, 2018 in Java by Sushmita
• 6,840 points
2,359 views
0 votes
2 answers

What's the best way to check if a String represents an integer in Java?

You can also use regular expression. str.matches("-?\\d+"); It will ...READ MORE

answered Aug 9, 2018 in Java by Daisy
• 8,040 points
106 views