76

I have an object called Student, and it has studentName, studentId, studentAddress, etc. For the studentId, I have to generate random string consist of seven numeric charaters, eg.

studentId = getRandomId();
studentId = "1234567" <-- from the random generator.

And I have to make sure that there is no duplicate id.

tshepang
  • 12,111
  • 21
  • 91
  • 136
chandra wibowo
  • 799
  • 1
  • 6
  • 5
  • 3
    If I read your question correctly, you want to generate a random number R such that 1,000,000 <= R <= 9,999,999, and then turn that into a string? – MSalters May 19 '10 at 09:29
  • 1
    would that be easier to generate a random number first then convert it to a string? – chandra wibowo May 19 '10 at 11:43
  • 1
    So, how did the homework assignment go? – james.garriss May 13 '15 at 18:52
  • 4
    These 3 single line codes are very much useful i guess.. `Long.toHexString(Double.doubleToLongBits(Math.random()));` `UUID.randomUUID().toString();` `RandomStringUtils.randomAlphanumeric(16);` – Manindar Jun 08 '16 at 07:33
  • how can you ensure uniqueness given limited dimension of data? If number of students exceeds 10^7, you'll have no way to assign a unique number to each. – Alex Salauyou Jul 27 '16 at 09:01

7 Answers7

132

Generating a random string of characters is easy - just use java.util.Random and a string containing all the characters you want to be available, e.g.

public static String generateString(Random rng, String characters, int length)
{
    char[] text = new char[length];
    for (int i = 0; i < length; i++)
    {
        text[i] = characters.charAt(rng.nextInt(characters.length()));
    }
    return new String(text);
}

Now, for uniqueness you'll need to store the generated strings somewhere. How you do that will really depend on the rest of your application.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • the method require String characters, how do i specify this characters? String characters = "123456789"; ??? – chandra wibowo May 20 '10 at 02:22
  • 3
    @chandra: Yes, exactly. Give it a string of the characters you want to select from. So if you only wanted digits you'd pass in "0123456789". If you wanted only capital letters you'd pass in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" etc. – Jon Skeet May 20 '10 at 06:08
  • 3
    Is this more correct that using `UUID.randomUUID().toString()`? If so, why? – Isaac Sep 05 '13 at 01:33
  • 3
    @Is7aq: Well it provides considerably more control over the output, both in terms of which characters are used and how long the string is. – Jon Skeet Sep 05 '13 at 05:52
  • 4
    Why did you pass Random as a parameter ? – RockOnGom Dec 08 '14 at 20:43
  • @RockOnGom First I too thought the same but then I realized mostly I will be using this method in generating random string to be added in a list, probably in a for loop. So by passing random I can avoid initialization in each call – SKT Nov 30 '15 at 06:34
  • 2
    @RockOnGom: Sorry, I'd missed this comment before. For things like this, I view the `Random` as effectively a dependency - accepting it here allows the caller to decide whether to use a preseeded `Random` to get repeatable results (e.g. for tests), a `SecureRandom` to make it suitable for security purposes, etc. – Jon Skeet Nov 30 '15 at 06:36
  • always same output – Rohit Mandiwal Apr 20 '16 at 23:44
  • @rohitmandiwal: I'm afraid I don't understand your comment... if you were asking for an explanation of some behaviour, you need to provide a *lot* more information. – Jon Skeet Apr 21 '16 at 05:37
56

This is very nice:

http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/RandomStringUtils.html - something like RandomStringUtils.randomNumeric(7).

There are 10^7 equiprobable (if java.util.Random is not broken) distinct values so uniqueness may be a concern.

David Soroko
  • 8,521
  • 2
  • 39
  • 51
  • [http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/RandomStringUtils.html](http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/RandomStringUtils.html) is broken!!! – Visruth Jun 28 '13 at 08:34
  • security hash is not for uniqueness, it is for hiding initial value – Alex Salauyou Jul 27 '16 at 09:04
18

You can also use UUID class from java.util package, which returns random uuid of 32bit characters String.

java.util.UUID.randomUUID().toString()

http://java.sun.com/j2se/1.5.0/docs/api/java/util/UUID.html

Jonathan
  • 6,741
  • 7
  • 52
  • 69
Parth
  • 1,281
  • 8
  • 17
5
Random ran = new Random();
int top = 3;
char data = ' ';
String dat = "";

for (int i=0; i<=top; i++) {
  data = (char)(ran.nextInt(25)+97);
  dat = data + dat;
}

System.out.println(dat);
j.w.r
  • 4,136
  • 2
  • 27
  • 29
karthik.j
  • 59
  • 1
  • 1
2

I think the following class code will help you. It supports multithreading but you can do some improvement like remove sync block and and sync to getRandomId() method.

public class RandomNumberGenerator {

private static final Set<String> generatedNumbers = new HashSet<String>();

public RandomNumberGenerator() {
}

public static void main(String[] args) {
    final int maxLength = 7;
    final int maxTry = 10;

    for (int i = 0; i < 10; i++) {
        System.out.println(i + ". studentId=" + RandomNumberGenerator.getRandomId(maxLength, maxTry));
    }
}

public static String getRandomId(final int maxLength, final int maxTry) {
    final Random random = new Random(System.nanoTime());
    final int max = (int) Math.pow(10, maxLength);
    final int maxMin = (int) Math.pow(10, maxLength-1);
    int i = 0;
    boolean unique = false;
    int randomId = -1;
    while (i < maxTry) {
        randomId = random.nextInt(max - maxMin - 1) + maxMin;

        synchronized (generatedNumbers) {
            if (generatedNumbers.contains(randomId) == false) {
                unique = true;
                break;
            }
        }
        i++;
    }
    if (unique == false) {
        throw new RuntimeException("Cannot generate unique id!");
    }

    synchronized (generatedNumbers) {
        generatedNumbers.add(String.valueOf(randomId));
    }

    return String.valueOf(randomId);
}

}
james.garriss
  • 12,959
  • 7
  • 83
  • 96
Erol Ozcan
  • 31
  • 3
1

The first question you need to ask is whether you really need the ID to be random. Sometime, sequential IDs are good enough.

Now, if you do need it to be random, we first note a generated sequence of numbers that contain no duplicates can not be called random. :p Now that we get that out of the way, the fastest way to do this is to have a Hashtable or HashMap containing all the IDs already generated. Whenever a new ID is generated, check it against the hashtable, re-generate if the ID already occurs. This will generally work well if the number of students is much less than the range of the IDs. If not, you're in deeper trouble as the probability of needing to regenerate an ID increases, P(generate new ID) = number_of_id_already_generated / number_of_all_possible_ids. In this case, check back the first paragraph (do you need the ID to be random?).

Hope this helps.

Chris Henry
  • 534
  • 2
  • 7
1

Many possibilities...

You know how to generate randomly an integer right? You can thus generate a char from it... (ex 65 -> A)

It depends what you need, the level of randomness, the security involved... but for a school project i guess getting UUID substring would fit :)

Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419