Saltar al contenido

Creación de un UUID a partir de un string sin guiones

Mantén la atención ya que en esta división encontrarás el hallazgo que buscas.Este artículo ha sido evaluado por nuestros expertos para garantizar la calidad y veracidad de nuestro post.

Solución:

tl; dr

java.util.UUID.fromString(
    "5231b533ba17478798a3f2df37de2aD7"
    .replaceFirst( 
        "(\pXDigit8)(\pXDigit4)(\pXDigit4)(\pXDigit4)(\pXDigit+)", "$1-$2-$3-$4-$5" 
    )
).toString()

5231b533-ba17-4787-98a3-f2df37de2ad7

O analizar cada mitad del hexadecimal string como long números enteros, y pasar al constructor de UUID.

UUID uuid = new UUID ( long1 , long2 ) ; 

Bits, no texto

Un UUID es un valor de 128 bits. Un UUID es no en realidad compuesto de letras y dígitos, está compuesto de bits. Puedes pensar que describe un número muy, muy grande.

Podríamos mostrar esos bits como ciento veintiocho 0 & 1 caracteres.

0111 0100 1101 0010 0101 0001 0101 0110 0110 0000 1110 0110 0100 0100 0100 0111 1010 1001 0110 1110 0110 0111 1110 1111 1111 1100 0101 1111 1111 1100 0101 1111 1111 1111

Los seres humanos no leen fácilmente los bits, por lo que, por comodidad, generalmente representamos el valor de 128 bits como un valor hexadecimal. string formado por letras y dígitos.

74d25156-60e6-444c-a177-a96e67ecfc5f

tal maleficio string no es el UUID en sí mismo, solo una representación humana. Los guiones se agregan según la especificación UUID como formato canónico, pero son opcionales.

74d2515660e6444ca177a96e67ecfc5f

Por cierto, la especificación UUID establece claramente que minúsculas se deben usar letras al generar el hexadecimal string mientras que las mayúsculas deben tolerarse como entrada. Desafortunadamente, muchas implementaciones violan esa regla de generación de minúsculas, incluidas las de Apple, Microsoft y otros. Ver mi publicación de blog.


Lo siguiente se refiere a Java, no a Clojure.

En Java 7 (y versiones anteriores), puede usar la clase java.util.UUID para instanciar un UUID basado en un hex. string con guiones como entrada. Ejemplo:

java.util.UUID uuidFromHyphens = java.util.UUID.fromString("6f34f25e-0b0d-4426-8ece-a8b3f27f4b63");
System.out.println( "UUID from string with hyphens: " + uuidFromHyphens );

Sin embargo, esa clase de UUID falla al ingresar un hexadecimal string sin guiones Esta falla es desafortunada como lo hace la especificación UUID no requieren los guiones en un hexadecimal string representación. Esto falla:

java.util.UUID uuidFromNoHyphens = java.util.UUID.fromString("6f34f25e0b0d44268ecea8b3f27f4b63");

expresión regular

Una solución es formatear el hexadecimal string para agregar los guiones canónicos. Aquí está mi intento de usar expresiones regulares para formatear el hexadecimal string. Cuidado… Este código funciona, pero no soy un experto en expresiones regulares. Debería hacer que este código sea más sólido, por ejemplo, comprobar que la longitud del string tiene 32 caracteres antes del formateo y 36 después.

    // -----|  With Hyphens  |----------------------
java.util.UUID uuidFromHyphens = java.util.UUID.fromString( "6f34f25e-0b0d-4426-8ece-a8b3f27f4b63" );
System.out.println( "UUID from string with hyphens: " + uuidFromHyphens );
System.out.println();

// -----|  Without Hyphens  |----------------------
String hexStringWithoutHyphens = "6f34f25e0b0d44268ecea8b3f27f4b63";
// Use regex to format the hex string by inserting hyphens in the canonical format: 8-4-4-4-12
String hexStringWithInsertedHyphens =  hexStringWithoutHyphens.replaceFirst( "([0-9a-fA-F]8)([0-9a-fA-F]4)([0-9a-fA-F]4)([0-9a-fA-F]4)([0-9a-fA-F]+)", "$1-$2-$3-$4-$5" );
System.out.println( "hexStringWithInsertedHyphens: " + hexStringWithInsertedHyphens );
java.util.UUID myUuid = java.util.UUID.fromString( hexStringWithInsertedHyphens );
System.out.println( "myUuid: " + myUuid );

Notación posix

Puede encontrar esta sintaxis alternativa más legible, usando la notación Posix dentro de la expresión regular donde \pXDigit toma el lugar de [0-9a-fA-F] (ver documento Patrón):

String hexStringWithInsertedHyphens =  hexStringWithoutHyphens.replaceFirst( "(\pXDigit8)(\pXDigit4)(\pXDigit4)(\pXDigit4)(\pXDigit+)", "$1-$2-$3-$4-$5" );

Ejemplo completo.

java.util.UUID uuid =
        java.util.UUID.fromString (
                "5231b533ba17478798a3f2df37de2aD7"
                        .replaceFirst (
                                "(\pXDigit8)(\pXDigit4)(\pXDigit4)(\pXDigit4)(\pXDigit+)",
                                "$1-$2-$3-$4-$5"
                        )
        );

System.out.println ( "uuid.toString(): " + uuid );

uuid.toString(): 5231b533-ba17-4787-98a3-f2df37de2ad7

Clojure’s #uuid literal etiquetado es un paso a través de java.util.UUID/fromString. Y, fromString lo divide por el “-” y lo convierte en dos Long valores. (El formato para UUID está estandarizado a 8-4-4-4-12 dígitos hexadecimales, pero los “-” en realidad solo están ahí para validación e identificación visual).

La solución directa es reinsertar el “-” y usar java.util.UUID/fromString.

(defn uuid-from-string [data]
  (java.util.UUID/fromString
   (clojure.string/replace data
                           #"(w8)(w4)(w4)(w4)(w12)"
                           "$1-$2-$3-$4-$5")))

Si quieres algo sin expresiones regulares, puedes usar un ByteBuffer y DatatypeConverter.

(defn uuid-from-string [data]
  (let [buffer (java.nio.ByteBuffer/wrap 
                 (javax.xml.bind.DatatypeConverter/parseHexBinary data))]
    (java.util.UUID. (.getLong buffer) (.getLong buffer))))

Podrías hacer un tonto reemplazo de expresión regular:

String digits = "5231b533ba17478798a3f2df37de2aD7";                         
String uuid = digits.replaceAll(                                            
    "(\w8)(\w4)(\w4)(\w4)(\w12)",                            
    "$1-$2-$3-$4-$5");                                                      
System.out.println(uuid); // => 5231b533-ba17-4787-98a3-f2df37de2aD7

Si te ha resultado de provecho nuestro post, te agradeceríamos que lo compartas con el resto entusiastas de la programación de esta forma nos ayudas a difundir nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *