Эффективный метод для генерации строки UUID в JAVA (UUID.randomUUID().toString () без тире)


Я бы хотел, чтобы эффективная утилита генерировала уникальные последовательности байтов. UUID-хороший кандидат, но UUID.randomUUID().toString() создает такие вещи, как 44e128a5-ac7a-4c9a-be4c-224b6bf81b20 что хорошо, если вам не нужно передавать его по HTTP, и в этом случае тире должны быть удалены.

Я ищу эффективный способ генерации случайных строк, только из алфавитно-цифровых символов (без дефисов или других специальных символов).

8 100

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));

}