Méthode efficace pour générer une chaîne UUID en JAVA (UUID.randomUUID().toString () sans les tirets)


Je voudrais un utilitaire efficace pour générer des séquences uniques d'octets. UUID est un bon candidat mais UUID.randomUUID().toString() génère des choses comme 44e128a5-ac7a-4c9a-be4c-224b6bf81b20 ce qui est bon tant que vous n'avez pas besoin de le transmettre via HTTP, auquel cas les tirets doivent être supprimés.

Je cherche un moyen efficace de générer des chaînes aléatoires, uniquement à partir de caractères alphanumériques (pas de tirets ou d'autres symboles spéciaux).

Author: Greg Dubicki, 2010-09-27

8 answers

Cela le fait:

public static void main(String[] args) {
    final String uuid = UUID.randomUUID().toString().replace("-", "");
    System.out.println("uuid = " + uuid);
}
 179
Author: Steve McLeod, 2017-08-09 13:18:05

Les tirets n'ont pas besoin d'être supprimés de la requête HTTP comme vous pouvez le voir dans l'URL de ce thread. Mais si vous souhaitez préparer une URL bien formée sans dépendance aux données, vous devez utiliser URLEncoder.encoder (données de chaîne, encodage de chaîne ) au lieu de changer la forme standard de vos données. Pour les tirets de représentation de chaîne UUID est normal.

 26
Author: Donz, 2010-09-27 14:28:56

J'ai utilisé JUG (Java UUID Generator) pour générer un ID unique. Il est unique à travers les JVM. Assez bon à utiliser. Voici le code pour votre référence:

private static final SecureRandom secureRandom = new SecureRandom();
private static final UUIDGenerator generator = UUIDGenerator.getInstance();

public synchronized static String generateUniqueId() {
  UUID uuid = generator.generateRandomBasedUUID(secureRandom);

  return uuid.toString().replaceAll("-", "").toUpperCase();
}

Vous pouvez télécharger la bibliothèque à partir de: https://github.com/cowtowncoder/java-uuid-generator

 10
Author: Sheng Chien, 2012-09-20 22:19:34

A fini par écrire quelque chose de mon propre basé sur UUID.java mise en œuvre. Notez que je ne génère pas un UUID, mais juste une chaîne hexadécimale aléatoire de 32 octets de la manière la plus efficace à laquelle je pourrais penser.

Mise en œuvre

import java.security.SecureRandom;
import java.util.UUID;

public class RandomUtil {
    // Maxim: Copied from UUID implementation :)
    private static volatile SecureRandom numberGenerator = null;
    private static final long MSB = 0x8000000000000000L;

    public static String unique() {
        SecureRandom ng = numberGenerator;
        if (ng == null) {
            numberGenerator = ng = new SecureRandom();
        }

        return Long.toHexString(MSB | ng.nextLong()) + Long.toHexString(MSB | ng.nextLong());
    }       
}

Utilisation

RandomUtil.unique()

Essais

Certaines des entrées que j'ai testées pour m'assurer que cela fonctionne:

public static void main(String[] args) {
    System.out.println(UUID.randomUUID().toString());
    System.out.println(RandomUtil.unique());

    System.out.println();
    System.out.println(Long.toHexString(0x8000000000000000L |21));
    System.out.println(Long.toBinaryString(0x8000000000000000L |21));
    System.out.println(Long.toHexString(Long.MAX_VALUE + 1));
}
 10
Author: Maxim Veksler, 2017-04-07 17:42:37

Je suis étonné de voir autant de chaînes remplacer les idées d'UUID. Que diriez-vous de ceci:

UUID temp = UUID.randomUUID();
String uuidString = Long.toHexString(temp.getMostSignificantBits())
     + Long.toHexString(temp.getLeastSignificantBits());

C'est la façon la plus rapide de le faire puisque tout le toString() de UUID est déjà plus cher sans parler de l'expression régulière qui doit être analysée et exécutée ou du remplacement par une chaîne vide.

 6
Author: Stephan, 2016-06-23 14:56:58

, Une solution simple est

UUID.randomUUID().toString().replace("-", "")

(Comme les solutions existantes, seulement qu'il évite l'appel String#replaceAll. Le remplacement d'expression régulière n'est pas requis ici, donc String#replace semble plus naturel, bien que techniquement il soit toujours implémenté avec des expressions régulières. Étant donné que la génération de l'UUID est plus coûteuse que le remplacement, il ne devrait pas y avoir de différence significative dans l'exécution.)

L'utilisation de la classe UUID est probablement assez rapide pour la plupart des scénarios, bien que je m'attendrais à ce que certaines variantes spécialisées écrites à la main, qui n'ont pas besoin du post-traitement, soient plus rapides. Quoi qu'il en soit, le goulot d'étranglement du calcul global sera normalement le générateur de nombres aléatoires. Dans le cas de la classe UUID, elle utilise SecureRandom .

Quel générateur de nombres aléatoires utiliser est également un compromis qui dépend de l'application. S'il est sensible à la sécurité, SecureRandom est, en général, la recommandation. Autrement, ThreadLocalRandom est une alternative (plus rapide que SecureRandom ou l'ancien Random , mais pas cryptographiquement sécurisé).

 2
Author: Philipp Claßen, 2016-09-07 23:55:58

J'utilise org.Apache.commun.codec.binaire.Base64 pour convertir un UUID en une chaîne unique sûre pour URL de 22 caractères et ayant la même unicité que l'UUID.

J'ai posté mon code sur Stockant l'UUID sous forme de chaîne base64

 0
Author: stikkos, 2017-05-23 10:31:10

Je viens de copier la méthode UUID toString() et de la mettre à jour pour en supprimer" -". Il sera beaucoup plus rapide et simple que toute autre solution

public String generateUUIDString(UUID uuid) {
    return (digits(uuid.getMostSignificantBits() >> 32, 8) +
            digits(uuid.getMostSignificantBits() >> 16, 4) +
            digits(uuid.getMostSignificantBits(), 4) +
            digits(uuid.getLeastSignificantBits() >> 48, 4) +
            digits(uuid.getLeastSignificantBits(), 12));
}

/** Returns val represented by the specified number of hex digits. */
private String digits(long val, int digits) {
    long hi = 1L << (digits * 4);
    return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}

Utilisation:

generateUUIDString(UUID.randomUUID())

Une autre implémentation utilisant reflection

public String generateString(UUID uuid) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

    if (uuid == null) {
        return "";
    }

    Method digits = UUID.class.getDeclaredMethod("digits", long.class, int.class);
    digits.setAccessible(true);

    return ( (String) digits.invoke(uuid, uuid.getMostSignificantBits() >> 32, 8) +
            digits.invoke(uuid, uuid.getMostSignificantBits() >> 16, 4) +
            digits.invoke(uuid, uuid.getMostSignificantBits(), 4) +
            digits.invoke(uuid, uuid.getLeastSignificantBits() >> 48, 4) +
            digits.invoke(uuid, uuid.getLeastSignificantBits(), 12));

}
 0
Author: Ravi Desai, 2018-05-11 12:45:50