Home > Enterprise >  java, how to generate a good random int
java, how to generate a good random int

Time:10-16

android app, it needs to generate a random int key for different use cases. it has a function for the random int, which is fine in most time, but in the case if it is called frequently it may return a same number.

    int nextRandomId() {
        return (int) SystemClock.uptimeMillis();
    }

one of the case when build the notification action buttons, there will be multiple action button each will have its own pendingIntent with requestid from nextRandomId().


Intent broadcastIntent_one = Intent(this, NotificationReceiver.class);
broadcastIntent_one.putExtra("action", ACTION_ONE);  //ACTION_TWO, ACTION_THREE
broadcastIntent_one.putExtra(EXTRA_NOTIFICATION_ID, notificationId)

// adding action for broadcast
   PendingIntent broadcastPendingIntent_one =
      PendingIntent.getBroadcast(application, nextRandomId(), broadcastIntent_one, PendingIntent.FLAG_UPDATE_CURRENT);

... ...
 builder.addAction(null, "action one", broadcastPendingIntent_one);
 builder.addAction(null, "action two", broadcastPendingIntent_two);
 builder.addAction(null, "action three", broadcastPendingIntent_three);


in case of building three action buttons, the log shows some of the random numbers are same:

16:00:55.003  nextRandomId(): 400267105
16:00:55.003  nextRandomId(): 400267106
16:00:55.003  nextRandomId(): 400267106

so in the NotificationReceiver the last two action buttons are all having the ACTION_THREEin the extra.

what is a better way to generate a number not duplicate (no clash, efficient)?

CodePudding user response:

does it need to be random, or just be unique?

I would recommend against using uptimeMillis() because you risk collisions every time that the system is restarted. Use the actual time instead of the uptime to reduce the chance of a collision.

Alternatively, you could use java.util.UUID.randomUUID();. It's theoretically possible to generate a duplicate, but I wouldn't count on it.

CodePudding user response:

If you cannot have duplicates, there is nothing efficient that any random number generator can do other than saving all the numbers you've already generated and checking.

You can generate bigger and bigger random numbers to reduce the probability of duplicates -- which is what e.g. UUID does, reducing it to extremely unlikely.

Using a Random or SecureRandom will probably have to be good enough, possibly combined with explicit testing to see if you already have generated a given value.

That said, if all you need is to generate IDs that do not have any duplicates on this JVM, the solution is very easy:

static final AtomicInteger counter = new AtomicInteger();
public static int getNewId() { return counter.getAndIncrement(); }

CodePudding user response:

For you application, you can consider hashing using SHA256 and then taking the last N elements. If your input is a fix string of numbers then you can expect your output to be computed in constant time as well.

See: How to hash some string with sha256 in Java?

If you're looking to assign random IDs to objects I suggest you use a GUID library. This generates a string rather than a number but you can be certain that no two will be alike.

see: https://kodejava.org/how-do-i-generate-uuid-guid-in-java/

  • Related