Méthode efficace pour générer la 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 trucs comme 44e128a5-ac7a-4c9a-be4c-224b6bf81b20 ce qui est bien aussi longtemps que vous n'avez pas besoin de le transmettre par HTTP, auquel cas les tirets doivent être supprimés.

je suis à la recherche d'un moyen efficace pour générer des chaînes aléatoires, uniquement à partir de caractères alphanumériques (pas de tiret ou tout autre symbole spécial).

100
demandé sur Greg Dubicki 2010-09-27 18:05:52

8 réponses

Ce n':

public static void main(String[] args) {
    final String uuid = UUID.randomUUID().toString().replace("-", "");
    System.out.println("uuid = " + uuid);
}
179
répondu 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 voulez 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 UUID string les tirets de représentation sont normaux.

26
répondu Donz 2010-09-27 14:28:56

j'ai utilisé JUG (Java UUID Generator) pour générer un ID unique. Il est unique parmi les JVM. Assez bon à utiliser. Voici le code de 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
répondu 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 suis ne générant pas un UUID , à la place 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

quelques-unes des entrées que j'ai testées pour m'assurer qu'elles fonctionnent:

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
répondu Maxim Veksler 2017-04-07 17:42:37

je suis étonné de voir tant de cordes remplacer les idées D'UUID. Que pensez-vous de ceci:

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

c'est la façon de jeûner car le toString() d'UUID est déjà plus cher sans parler de l'expression régulière qui doit être parsée et exécutée ou le remplacement par une chaîne vide.

6
répondu Stephan 2016-06-23 14:56:58

une solution simple est

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

(comme les solutions existantes, seulement qu'il évite la chaîne de caractères #replaceAll appel. Le remplacement de l'expression régulière n'est pas nécessaire ici, donc chaîne#replace semble plus naturel, bien que techniquement il soit encore mis en œuvre 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 entre les deux. Runtime.)

L'utilisation de la classe UUID est probablement assez rapide pour la plupart des scénarios, mais je m'attendrais à ce qu'une variante manuscrite spécialisée, qui n'a pas besoin du postprocessing, soit plus rapide. 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, il utilise SecureRandom .

Quel générateur de nombres aléatoires utiliser est également un compromis qui dépend de la application. Si elle 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 aléatoire , mais pas cryptographiquement sûr).

2
répondu Philipp Claßen 2016-09-07 23:55:58

- je utiliser org.Apache.commun.codec.binaire.Base64 pour convertir un UUID en une chaîne unique sécurisée qui a 22 caractères de longueur et la même unicité que L'UUID.

j'ai posté mon code sur stockant UUID comme chaîne de caractères

0
répondu stikkos 2017-05-23 10:31:10

je viens de copier la méthode UUID toString() et de la mettre à jour pour 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())

un Autre de mise en œuvre de l'aide de la réflexion

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
répondu Ravi Desai 2018-05-11 12:45:50