Эффективный метод для генерации строки UUID в JAVA (UUID.randomUUID().toString () без тире)
Я бы хотел, чтобы эффективная утилита генерировала уникальные последовательности байтов. UUID-хороший кандидат, но UUID.randomUUID().toString()
создает такие вещи, как 44e128a5-ac7a-4c9a-be4c-224b6bf81b20
что хорошо, если вам не нужно передавать его по HTTP, и в этом случае тире должны быть удалены.
Я ищу эффективный способ генерации случайных строк, только из алфавитно-цифровых символов (без дефисов или других специальных символов).
8 ответов:
вот это:
public static void main(String[] args) { final String uuid = UUID.randomUUID().toString().replace("-", ""); System.out.println("uuid = " + uuid); }
тире не нужно удалять из HTTP-запроса, как вы можете видеть в URL этого потока. Но если вы хотите подготовить хорошо сформированный URL-адрес без зависимости от данных, вы должны использовать URLEncoder.кодирование (строковые данные, строковое кодирование) вместо изменения стандартной формы ваших данных. К сожалению строковое представление прочерки-это нормально.
я использовал JUG (Java UUID Generator) для создания уникального идентификатора. Он является уникальным в виртуальных машинах. Довольно хорошо использовать. Вот код для вашей справки:
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(); }
вы можете скачать библиотеку из: https://github.com/cowtowncoder/java-uuid-generator
В конечном итоге написал что-то свое, основанное на UUID.реализация Java. Обратите внимание, что я не генерируя UUID, вместо этого просто случайная 32-байтовая шестнадцатеричная строка самым эффективным способом, который я мог придумать.
реализация
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()); } }
использование
RandomUtil.unique()
тесты
некоторые из входов, которые я проверил, чтобы убедиться, что он работает:
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)); }
Я поражен, что так много строк заменяют идеи UUID. Как насчет этого:
UUID temp = UUID.randomUUID(); String uuidString = Long.toHexString(temp.getMostSignificantBits()) + Long.toHexString(temp.getLeastSignificantBits());
это быстрый способ сделать это, так как весь toString() UUID уже дороже, не говоря уже о регулярном выражении, которое должно быть проанализировано и выполнено или заменено пустой строкой.
простое решение
UUID.randomUUID().toString().replace("-", "")
(Как и существующие решения, только это позволяет избежать строка#replaceAll звонок. Замена регулярного выражения здесь не требуется, поэтому строка#replace кажется более естественным, хотя технически он все еще реализован с помощью регулярных выражений. Учитывая, что генерация UUID является более дорогостоящей, чем замена, не должно быть существенной разницы во времени выполнения.)
С помощью класса UUID вероятно, достаточно быстро для большинства сценариев, хотя я ожидал бы, что какой-то специализированный рукописный вариант, который не нуждается в постобработке, будет быстрее. Во всяком случае, узким местом общего вычисления обычно будет генератор случайных чисел. В случае класса UUID он использует SecureRandom.
что генератор случайных чисел использовать также компромисс, который зависит от приложения. Если это чувствительно к безопасности, SecureRandom-это, в общем, рекомендация. В противном случае, ThreadLocalRandom является альтернативой (быстрее, чем SecureRandom или старый Random, но не криптографически безопасный).
Я использую org.апаш.палата общин.кодек.двоичный.Base64 для преобразования UUID в url-безопасную уникальную строку длиной 22 символа и имеет ту же уникальность, что и UUID.
Я разместил свой код на хранение UUID в виде строки base64
Я только что скопировал метод UUID toString () и просто обновил его, чтобы удалить "-" из него. Это будет гораздо быстрее и прямо вперед, чем любое другое решение
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); }
использование:
generateUUIDString(UUID.randomUUID())
другая реализация с использованием отражения
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)); }