0

I'm working on an application where I've to generate code like Google classroom. When a user creates a class I generate code using following functions

 private String codeGenerator(){
        StringBuilder stringBuilder=new StringBuilder();
        String chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        int characterLength=chars.length();
        for(int i=0;i<5;i++){
            stringBuilder.append(chars.charAt((int)Math.floor(Math.random()*characterLength)));
        }
        return stringBuilder.toString();
    }

As I have 62 different characters. I can generate total 5^62 code total which is quite large. I can generate this code in server or user device. So my question is which one is better approach? How likely a generated code will conflict with another code?

Shahrear Bin Amin
  • 1,075
  • 13
  • 31
  • 3
    Why not use UUID and convert to base64? – josejuan Sep 12 '19 at 06:37
  • Failing that, use UUID and "base62" encode it. – Elliott Frisch Sep 12 '19 at 06:42
  • 1
    Do the codes have to be restricted to a length of 5? How do you intend to use those codes? What would happen if you'd have a "conflict"? – Thomas Sep 12 '19 at 06:44
  • @josejuan but my string length must be 5. How can I do that? – Shahrear Bin Amin Sep 12 '19 at 09:11
  • @Thomas yeah length must be of 5. I'll use this code for joining a class, so they must be unique. If any conflict occurs I tried to generate another code. – Shahrear Bin Amin Sep 12 '19 at 09:23
  • Btw, note that it's not 5^62 but 62^5 possible codes, so you only have about 900 million codes available - still quite large, depending on how many you actually need. – Thomas Sep 12 '19 at 09:46
  • To clarify: Are the codes actually Google Classroom codes, or are they codes for an application similar to Google Classroom? If the latter, why 5 characters and not more (say, 8 or 12), especially if a goal seems to be to make those codes hard to guess? (Moreover, for the purposes of making hard-to-guess identifiers, `Math.random()` is far from suitable.) – Peter O. Sep 12 '19 at 09:58
  • @Thomas I have 5 places and 62 possible values. So 62P5 possible codes. As I can take same value twice so 5^62 possible code. – Shahrear Bin Amin Sep 12 '19 at 09:59
  • @PeterO. It's not google classroom code. My application has different groups, for joining a group you have to enter group code which is like google class joining process. Actually I tried to keep this joining code as small as possible. – Shahrear Bin Amin Sep 12 '19 at 10:03
  • 1
    No, you have a [permutation with repetition](https://en.wikipedia.org/wiki/Permutation) of length n=5 over a set of k=62 elements. Thus the number of possible variations is k^n or 62^5. - To make it easier to understand: a byte is a permutation of length n=8 over a set of k=2 elements so there are 2^8 = 256 possible values (and not 8^2 = 64). – Thomas Sep 12 '19 at 11:22

4 Answers4

2

From a comment, it seems that you are generating group codes for your own application.

For the purposes and scale of your app, 5-character codes may be appropriate. But there are several points you should know:

  • Random number generators are not designed to generate unique numbers. You can generate a random code as you're doing now, but you should check that code for uniqueness (e.g., check it against a table that stores group codes already generated) before you treat that code as unique.
  • If users are expected to type in a group code, you should include a way to check whether a group code is valid, to avoid users accidentally joining a different group than intended. This is often done by adding a so-called "checksum digit" to the end of the group code. See also this answer.
  • It seems that you're trying to generate codes that should be hard to guess. In that case, Math.random() is far from suitable (as is java.util.Random) — especially because the group codes are so short. Use a secure random generator instead, such as java.security.SecureRandom (fortunately for you, its security issues were addressed in Android 4.4, which, as I can tell from a comment of yours, is the minimum Android version your application supports; see also this question). Also, if possible, make group codes longer, such as 8 or 12 characters long.

For more information, see Unique Random Identifiers.


Also, there is another concern. There is a serious security issue if the 5-character group code is the only thing that grants access to that group. Ideally, there should be other forms of authorization, such as allowing only logged-in users or certain logged-in users—

  • to access the group via that group code, or
  • to accept invitations to join the group via that group code (e.g., in Google Classroom, the PERMISSION_DENIED error code can be raised when a user tries to accept an invitation to join a class).
Peter O.
  • 32,158
  • 14
  • 82
  • 96
1

The only way to avoid duplicates in your scheme is to keep a copy of the ones that you have already generated, and avoid "generating" anything that would result in a duplicate. Since 5^62 is a lot, you could simply store them on a table if using a database; or on a hashset if everything is in-memory and there is only one instance of the application (remember to save the list of generated IDs to disk every time you create a new one, and to re-read it at startup).

The chances of a collision are low: you would need to generate around 5^(62/2) = 5^31 ~= 4.6E21 really-random identifiers for a collision to be more likely than not (see birthday paradox) - and it would take a lot of space to store and check all those identifiers for duplicates to detect that this was the case. But such is the price of security.

tucuxi
  • 17,561
  • 2
  • 43
  • 74
0

Que: A sack contains a blue ball and a red ball. I draw one ball from the sack. What are the chances it is a red ball?

Ans: 1/2


Que: I have a collection of 5^62 unique codes. I choose one code from the collection. What are the chances that it is "ABCDE"?

Ans: 1/(5^62)

NOTE: Random number generators are not actually random.

kumarchandresh
  • 559
  • 2
  • 16
  • Thanks. But all different codes are not available to me like a sack of balls. So I think second probability calculation is not as simple as the first one. – Shahrear Bin Amin Sep 12 '19 at 09:31
0

Well, in case you need a unique generator, what about the following. This is definitely not a random, but it's definitely unique for one instance.

public final class UniqueCodeGenerator implements Supplier<String> {

    private int code;

    @Override
    public synchronized String get() {
        return String.format("%05d", code++);
    }

    public static void main(String... args) {
        Supplier<String> generator = new UniqueCodeGenerator();

        for (int i = 0; i < 10; i++)
            System.out.println(generator.get());
    }

}
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35