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).
8 réponses
Ce n':
public static void main(String[] args) {
final String uuid = UUID.randomUUID().toString().replace("-", "");
System.out.println("uuid = " + uuid);
}
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.
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
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));
}
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.
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).
- 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
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));
}