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

StackOverflow https://stackoverflow.com/questions/325443

  •  11-07-2019
  •  | 
  •  

Question

Si j'utilise Long uuid = UUID.randomUUID (). getMostSignificantBits () quelle est la probabilité d'obtenir une collision. Il supprime les bits les moins significatifs, il est donc possible que vous vous heurtiez à une collision, non?

Était-ce utile?

La solution

Selon la documentation , le 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 attribués de manière aléatoire.

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

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

Incidemment, vous auriez un peu avantage en utilisant la moitié la moins significative de l’UUID (ou en générant simplement une valeur longue de manière aléatoire avec SecureRandom).

Autres conseils

Raymond Chen a un très bon billet de blog à ce sujet:

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

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

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

Vous feriez mieux de générer une valeur longue aléatoire, alors tous les bits sont aléatoires. Dans Java 6, new Random () utilise System.nanoTime () plus un compteur en tant que graine.

Il existe différents niveaux d'unicité.

Si vous avez besoin d'unicité sur plusieurs machines, vous pouvez disposer d'une table de base de données centrale permettant d'allouer des identifiants uniques, voire de lots d'identifiants uniques.

Si vous avez simplement besoin d'unicité dans une application, vous pouvez simplement avoir un compteur (ou un compteur commençant par currentTimeMillis () * 1000 ou nanoTime () en fonction de vos besoins)

Utilisez l'heure YYYYDDDD (année + jour de l'année) comme préfixe. Cela réduit la fragmentation de la base de données dans les tables et les index. Cette méthode retourne octet [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 l'application 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();
    String val = String.valueOf(cal.get(Calendar.YEAR));
    val += timeFormat4.format(cal.get(Calendar.DAY_OF_YEAR));
    val += UUID.randomUUID().toString().replaceAll("-", "");
    return val.getBytes();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top