1
\$\begingroup\$

I am needing to generate unique id's for users. The 'unique' part is the problem for me.

The 13 character id's which have a format of the following:

0 + random int with range of 1-9 + random letter + random 3 digit number + string 98XX001 For example: 04X90398XX001 --> (0) (4) (X) (903) (98XX001)

This is the code I currently have for generating the ID's:

package generation;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class id {
private static List<String> generatedIDs = new ArrayList<String>();
public static void main(String[] args) {
    generateIDs(1200);
}

public static void generateIDs(int numOfUsers) {
    for (int i = 0; i < numOfUsers; i++) {
        Random r = new Random();
        int first = r.nextInt((9 - 1) + 1) + 1;
        char second = (char) (r.nextInt(26) + 'A');
        int third = r.nextInt((899 - 100) + 100) + 100;

        String id = "0" + first + second + third + "98XX001";
        generatedIDs.add(id);
        System.out.println(id);

    }
  }
}

Like I said, I am pretty clueless on how to make sure that they are unique.

\$\endgroup\$
1
\$\begingroup\$

A large part of your id (8 of 13 characters) is actually static.

That leaves you with 260.000 variations (10 (0-9) x 26 (A-Z) x 1000 (0-999)) of ids to assign to your users. After that, you run out of ids. Will that be enough?

In your current code there is not much you can do besides checking wether the id you generated is already in the generatedIDs list and if it is, try again.

Is there a purpose behind generating the ids randomly? Because if they are only used to identify users, it would make more sense to increment them one number at a time and just remember the last id you gave to a user.

User 1:      (0)(0)(A)(000)98XX001
User 2:      (0)(0)(A)(001)98XX001
User 5000:   (0)(0)(E)(999)98XX001
User 80543:  (0)(3)(B)(542)98XX001
User 260000: (0)(9)(Z)(999)98XX001

Here would be the code for that. You hand the function the id you would like to start from and how many ids from that start-id it should generate.

import java.util.ArrayList;
import java.util.List;

public class MainClass
{
  public static void main(String[] args)
  {
    TestClass gen = new TestClass();
    gen.generateIDs("04X99798XX001", 10);
  }
}

public class TestClass
{
  public static Integer letterToInt(char letter) {
    return letter - 'A' + 1;
  }

  public static char intToLetter(int number) {
    return (char) (90 - (26 - number));
  }

  private static List<String> generatedIDs = new ArrayList<String>();

  public static void generateIDs(String lastID, Integer numOfUsers) {
    String first = lastID.substring(1, 2);
    char second = lastID.substring(2, 3).charAt(0);
    String third = lastID.substring(3, 6);

    Integer firstNum = Integer.parseInt(first);
    Integer secondNum = letterToInt(second);
    Integer thirdNum = Integer.parseInt(third);

    for (Integer i = new Integer(0); i < numOfUsers; i++) {
      thirdNum = new Integer(thirdNum.intValue() + 1);

      if (thirdNum > 999) {
        thirdNum = new Integer(0);
        secondNum = new Integer(secondNum.intValue() + 1);
      }

      if (secondNum > 26) {
        secondNum = new Integer(1);
        firstNum = new Integer(firstNum.intValue() + 1);
      }

      if (firstNum > 9) {
        // Ran out of IDs, do something.
        return;
      }

      first = String.valueOf(firstNum);
      second = intToLetter(secondNum);
      third = String.valueOf(thirdNum);

      while (third.length() < 3) {
        third = "0" + third;
      }

      String nextID = "0" + first + intToLetter(secondNum) + String.valueOf(third) + "98XX001";
      generatedIDs.add(nextID);

      System.out.println(nextID);
    }
  }
}

The result looks like this.

04X99898XX001
04X99998XX001
04Y00098XX001
04Y00198XX001
04Y00298XX001
04Y00398XX001
04Y00498XX001
04Y00598XX001
04Y00698XX001
04Y00798XX001
\$\endgroup\$
  • \$\begingroup\$ there are better options for translating letters from/to numbers then switch with 26 cases (like math operation on char) \$\endgroup\$ – Sharon Ben Asher Jun 21 '18 at 13:08
  • \$\begingroup\$ @SharonBenAsher I'm sure there are and I think he even did that in his original question. I'm not much of a Java guy, but feel free to edit the answer. \$\endgroup\$ – Endauriel Jun 21 '18 at 13:13
  • \$\begingroup\$ I will. and if you are not much of a Java guy, I suggest you write the solution as an abstract description. the starting text is clear enough without the need for explicit code \$\endgroup\$ – Sharon Ben Asher Jun 21 '18 at 13:19
  • \$\begingroup\$ @SharonBenAsher Sorry, just trying to help. I've read into it and edited the code. \$\endgroup\$ – Endauriel Jun 21 '18 at 13:31
1
\$\begingroup\$

Review

  • There is no added value in creating a new Random for every cycle in the loop. Create and reuse a single instance.
  • You have a convoluted way of generating the next random value. Why do r.nextInt((9 - 1) + 1) + 1 when r.nextInt(9) + 1 would yield the same? If it's a readability thing, the latter is better.
  • I agree with other answer that if you want unique numbers, you should not naively generate random segments. Instead, use incrementing sequences or encode parts of the key fields of a user in the id.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.