Probabilité de collision en utilisant les bits les plus significatifs d’un UUID en Java

Si j’utilise Long uuid = UUID.randomUUID().getMostSignificantBits() quelle est la probabilité d’obtenir une collision. Il coupe les bits les moins significatifs, il y a donc une possibilité de collision, n’est-ce pas?

Selon la documentation , la méthode statique UUID.randomUUID() génère un UUID de type 4.

Cela signifie que six bits sont utilisés pour certaines informations de type et que les 122 bits restants sont affectés de manière aléatoire.

Les six bits non aléatoires sont dissortingbués avec quatre dans la moitié la plus significative de l’UUID et deux dans la moitié la moins significative. Ainsi, la moitié la plus significative de votre UUID contient 60 bits de caractère aléatoire, ce qui signifie que vous devez en moyenne générer 2 ^ 30 UUID pour obtenir une collision (contre 2 ^ 61 pour l’UUID complet).

Je dirais donc que vous êtes plutôt en sécurité. Notez, cependant, que ce n’est absolument pas le cas pour d’autres types d’UUID, comme le mentionne Carl Seleborg.

Incidemment, vous seriez légèrement mieux en utilisant la moitié la moins significative de l’UUID (ou simplement en générant une longueur aléatoire en utilisant SecureRandom).

Raymond Chen a un blog vraiment excellent à ce sujet:

Les GUID sont globalement uniques, mais les sous-chaînes de GUID ne sont pas

Je pense que c’est le meilleur exemple d’utilisation de randomUUID:

http://www.javapractices.com/topic/TopicAction.do?Id=56

Il vaut mieux simplement générer une valeur longue aléatoire, alors tous les bits sont aléatoires. Dans Java 6, le nouveau Random () utilise le System.nanoTime () plus un compteur comme graine.

Il y a différents niveaux d’unicité.

Si vous avez besoin d’uniformité sur de nombreux ordinateurs, vous pouvez disposer d’une table de firebase database centrale pour allouer des identifiants uniques ou même des lots d’identifiants uniques.

Si vous avez juste besoin d’avoir un caractère unique dans une application, vous pouvez simplement avoir un compteur (ou un compteur qui commence à partir de currentTimeMillis () * 1000 ou nanoTime () selon vos besoins)

Utilisez Time YYYYDDDD (Année + Jour de l’An) comme préfixe. Cela réduit la fragmentation de la firebase database dans les tables et les index. Cette méthode renvoie un byte[40] . Je l’ai utilisé dans un environnement hybride où le SID Active Directory ( varbinary(85) ) est la clé pour les utilisateurs LDAP et un ID généré automatiquement par les applications est utilisé pour les utilisateurs non-LDAP. De plus, le grand nombre de transactions par jour dans les tables transactionnelles (secteur bancaire) ne peut pas utiliser les types Int standard pour les clés.

 private static final DecimalFormat timeFormat4 = new DecimalFormat("0000;0000"); public static byte[] getSidWithCalendar() { Calendar cal = Calendar.getInstance(); Ssortingng val = Ssortingng.valueOf(cal.get(Calendar.YEAR)); val += timeFormat4.format(cal.get(Calendar.DAY_OF_YEAR)); val += UUID.randomUUID().toSsortingng().replaceAll("-", ""); return val.getBytes(); }