length generate generar java http uuid random

generate - Método eficiente para generar Cadena UUID en JAVA(UUID.randomUUID(). ToString() sin los guiones)



spring uuid (8)

Me gustaría una utilidad eficiente para generar secuencias únicas de bytes. UUID es un buen candidato pero UUID.randomUUID().toString() genera cosas como 44e128a5-ac7a-4c9a-be4c-224b6bf81b20 que es bueno siempre que no sea necesario transmitirlo a través de HTTP, en cuyo caso los guiones necesitan ser eliminado.

Estoy buscando una manera eficiente de generar cadenas aleatorias, solo a partir de caracteres alfanuméricos (sin guiones ni ningún otro símbolo especial).


Acabo de copiar el método UUID toString () y simplemente lo actualicé para eliminar "-" de él. Será mucho más rápido y directo que cualquier otra solución

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

Uso:

generateUUIDString(UUID.randomUUID())

Otra implementación usando la reflexión

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


Esto lo hace:

public static void main(String[] args) { final String uuid = UUID.randomUUID().toString().replace("-", ""); System.out.println("uuid = " + uuid); }


Los guiones no necesitan ser eliminados de la solicitud HTTP como se puede ver en la URL de este hilo. Pero si desea preparar una URL bien formada sin dependencia de los datos, debe usar URLEncoder.encode (datos de cadena, codificación de cadena) en lugar de cambiar la forma estándar de sus datos. Para guiones de representación de cadenas UUID es normal.


Me sorprende ver tantas ideas de reemplazo de cadenas de UUID. Qué tal esto:

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

Esta es la forma más rápida de hacerlo, ya que todo toString () de UUID ya es más costoso, por no mencionar la expresión regular que debe analizarse y ejecutarse o la sustitución por una cadena vacía.


Terminé escribiendo algo mío basado en la implementación de UUID.java. Tenga en cuenta que no estoy generando un UUID , sino solo una cadena hexadecimal aleatoria de 32 bytes de la manera más eficiente que se me ocurre.

Implementación

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

Uso

RandomUtil.unique()

Pruebas

Algunas de las entradas que he probado para asegurarme de que funcionan:

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


Una solución simple es

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

(Como las soluciones existentes, solo que evita la llamada String#replaceAll . Aquí no se requiere el reemplazo de expresiones regulares, por lo que String#replace siente más natural, aunque técnicamente aún se implementa con expresiones regulares. Dado que la generación del UUID es más costoso que el reemplazo, no debería haber una diferencia significativa en el tiempo de ejecución).

Usar la clase UUID probablemente sea lo suficientemente rápido para la mayoría de los escenarios, aunque esperaría que una variante especializada escrita a mano, que no necesita el postprocesamiento, sea más rápida. De todos modos, el cuello de botella del cálculo general normalmente será el generador de números aleatorios. En el caso de la clase UUID, usa SecureRandom .

Qué generador de números aleatorios usar es también una solución de compromiso que depende de la aplicación. Si es sensible a la seguridad, SecureRandom es, en general, la recomendación. De lo contrario, ThreadLocalRandom es una alternativa (más rápida que SecureRandom o la antigua Random , pero no criptográficamente segura).


Usé JUG (Java UUID Generator) para generar una identificación única. Es único en todas las JVM. Bastante bueno de usar. Aquí está el código para su referencia:

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

Puede descargar la biblioteca desde: https://github.com/cowtowncoder/java-uuid-generator


Utilizo org.apache.commons.codec.binary.Base64 para convertir un UUID en una cadena única segura para url que tiene 22 caracteres de longitud y tiene la misma singularidad que el UUID.

Publiqué mi código en Almacenamiento de UUID como base64 String