Este foro usa cookies
Este foro utiliza cookies para almacenar su información de inicio de sesión si está registrado y su última visita si no lo está. Las cookies son pequeños documentos de texto almacenados en su computadora; las cookies establecidas por este foro solo se pueden usar en este sitio web y no representan ningún riesgo de seguridad. Las cookies en este foro también rastrean los temas específicos que ha leído y la última vez que los leyó. Si Ud. continúa navegando, entenderemos que acepta todas las cookies.

Se almacenará una cookie en su navegador, independientemente de la elección, para evitar que se le vuelva a hacer esta pregunta. Podrá cambiar la configuración de sus cookies en cualquier momento utilizando el enlace en el pie de página.

El foro antiguo se encuentra accesible desde https://foro.gambas-es.org en modo de solo lectura.

Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5

Identificador único universal
#11

La palabra "universal" implica otros planetas lejanos?

Yo diria que solo es necesario chequear en el entorno donde se usara la informacion puesto que es imposible saber si es unico habiando multiples dispositivos generandolos. En todo caso, suponiendo que estamos desarrollando software multi-PC o multi-Servidor y que cada servidor tiene asignado un nombre o numero se podrian generar codigos del tipo:

123e4567-e89b-12d3-a456-426655440000 

donde cada parte es, por ejemplo 

timestamp - maquina - usuario - sub proceso - incremental 

entonces cada PC/servidor podria generar un numero que seria unico en todo el sistema que aloja o usa el software porque cada maquina es unica, y la velocidad no importa porque el INCREMENTAL se va agrandando a medida que se generan items en la lista, en un ejemplo practico:

La MAQUINA 1 genera a las 12:00 del 01/01/2024 una operacion X, siendo la primera del dia:

0101241200-0001-0000-000000000001

La MAQUINA 2 genera a las 12:00 del 01/01/2024 una operacion X, siendo la primera del dia:

0101241200-0002-0000-000000000001

y ambos son unicos en el todo sistema

"Es mejor saber todo de muy poco que muy poco de todo" - anonimo
    ¡Gracias!
#12

Cita:timestamp - maquina - usuario - sub proceso - incremental 

entonces cada PC/servidor podria generar un numero que seria unico en todo el sistema que aloja o usa el software porque cada maquina es unica, y la velocidad no importa porque el INCREMENTAL se va agrandando a medida que se generan items en la lista, en un ejemplo practico:

La MAQUINA 1 genera a las 12:00 del 01/01/2024 una operacion X, siendo la primera del dia:

0101241200-0001-0000-000000000001

La MAQUINA 2 genera a las 12:00 del 01/01/2024 una operacion X, siendo la primera del dia:

0101241200-0002-0000-000000000001

y ambos son unicos en el todo sistema
Eso es lo mismo, más o menos, que sugería yo más arriba, pero lo veo excesivamente complejo.
Usando el timestamp sin más ya tienes hecho la mitad del camino. Añade símplemente el nombre de la máquina o el ID del disco duro y ya está.
Lo del incremental no lo tengo claro porque ¿Cómo sabe el sistema emisor qué día es si el 1 o el 2?
Para ello el sistema receptor es quien debiera signar el código único... y en tal caso con el TimeStamp es suficiente porque no hay posibilidad de duplicidad.

En el caso que plantea Tincho, que el código sea irrepetible "per se", creo que el problema es irresoluble de por sí habiendo distintas máquinas generando los códigos. Hay que basarse en algo más.

Saludos

No podemos regresar
    ¡Gracias!
#13

Si tienen un momento estudien este código que les paso, donde en un bucle le pido 1 millón de claves irrepetibles y solo cumple el el método que usa el archivo del sistema "/proc/sys/kernel/random/uuid"

Algo mas de información sobre lo que es un UUID
https://digitalbunker.dev/understanding-...generated/


Archivos adjuntos
.gz sample-uuid-contest-0.0.1.tar.gz Tamaño: 12.51 KB  Descargas: 1

1 Saludo.
    ¡Gracias!
#14

Se acerca a lo que intentas... pero aunque la ratio de claves únicas conseguidas fuese del 100%, eso sólo indica que en una máquina se puede hacer única... pero no dice nada de que las claves generadas en las demás máquinas que generen los ID no vayan a ser iguales nunca.

Te adjunto una propuesta con TimeStamp que sí genera claves únicas sin recurrir a nada externo a Gambas. Le he puesto dos tests, por tiempo o por número de veces. T2 te daba siempre 0 porque no le dabas tiempo suficiente dado que se generan, más o menos 20.000 claves por segundo.

Saludos


Archivos adjuntos
.gz sample-uuid-contest-0.0.2.tar.gz Tamaño: 13.29 KB  Descargas: 2

No podemos regresar
[-] Los siguientes 1 usuarios dice gracias a Shordi por este post:
  • tincho
    ¡Gracias!
#15

(11-05-2023, 18:20)Shordi escribió:  Lo del incremental no lo tengo claro porque

Eso es para resolver el problema de la velocidad de generacion. Si solo se logran 20k/seg de claves sera insuficiente. AutoDesk en los archivos CAD usa un indice incremental que empieza en 0 y se incremente en cada generacion de un nuevo objeto: 
Código:
Public lIndex as Long = 0


Public Function NewID() as String
   Inc lIndex
   Return Hex(lIndex)
End Function

"Es mejor saber todo de muy poco que muy poco de todo" - anonimo
    ¡Gracias!
#16

Cita:Eso es para resolver el problema de la velocidad de generacion. Si solo se logran 20k/seg de claves sera insuficiente.
¿Insuficiente para qué? Creo que no he entendido el problema aún...

No podemos regresar
    ¡Gracias!
#17

Claro, Tincho necesita un UUID de algun tipo para asociarlo a algun dato, que puede ser cualquier cosa. Pero para poder responder a su inquietud es necesario saber para que lo necesita. Mi aproximacion a la solucion del problema esta pensada para un programa CAD donde puede ser necesario duplicar las entidades de un plano (textos, lineas, circulos, etc) y puede haber 20.000.000 de esas entidades. Por lo tanto es inaceptable esperar 1.000 segundos para generar UUID para cada una de ellas, entonces ¿que tan unicas tienen que ser las claves UUID? ¿en que contexto tienen que ser unicas? ¿para el documento grafico en cuestion? ¿para la PC en cuestion? ¿para el entorno de trabajo, PCs, Users, etc? 
En el ejemplo que planteo solo es necesario que sean unicas en el grafico. Suponiendo que copio parte de un grafico y lo pego en otro grafico, entonces puede haber conflicto de UUID, pero en el proceso de copiado el software debe generar nuevas UUID para los datos copiados en el otro contexto (el segundo grafico). 

Por ejemplo, Voutt se cansa de Italia y se va a vivir a China. Su numero de pasaporte ITALIANO puede ser igual al de un chino, pero es otro contexto entonces no importa. Cuando VOUTT pida nacionalidad CHINA le asignaran otro numero de pasaporte, y sera unico.

"Es mejor saber todo de muy poco que muy poco de todo" - anonimo
    ¡Gracias!
#18

tincho,
en Mailing List preguntaste si alguien sabe como usar Extern con libuuid.

He encontrado un ejemplo en lenguaje C que funciona, pero cuando lo traduzco a Gambas:
GAMBAS
  1. Library "libuuid:1.3.0"
  2.  
  3. Private Const UUID_STR_LEN As Integer = 37
  4.  
  5. ' void uuid_generate(uuid_t out)
  6. Private Extern uuid_generate(out As Integer)
  7.  
  8. ' void uuid_unparse_lower(const uuid_t uu, char *out)
  9. Private Extern uuid_unparse_lower(uu As Integer, out As Byte[]) As Integer
  10.  
  11.  
  12. Public Sub Main()
  13.  
  14.   Dim uuid As New Byte[UUID_STR_LEN]
  15.   
  16.   uuid_generate(i)
  17.   
  18.   uuid_unparse_lower(i, uuid)
  19.   
  20.   Print uuid.ToString(0, 36)
  21.  


me da un Sad error en la primera función externa de la librería 'libuuid'.
Lamentablemente también encuentro este problema Sad con otros códigos similares con la librería 'libuuid'.

 
Para resolver el problema y presentarte un código que siga utilizando las funciones externas de la librería 'libuuid', escribí una librería .so compartida externa especial, que implementa precisamente dos funciones externas de la librería 'libuuid'.
Dejo aquí el código de trabajo adecuado para el uso de mi librería externa, que he llamado "libcreauuid.so".

GAMBAS
  1. ' char * creauuid()
  2. Private Extern creauuid() As Pointer In "/tmp/libcreauuid"
  3.  
  4. Public Sub Main()
  5.  
  6.   
  7.   Creaso()
  8.   
  9.   p = creauuid()
  10.   
  11.   Print String@(p)
  12.  
  13.  
  14.  
  15.   
  16.   File.Save("/tmp/libcreauuid.c", "#include <stdlib.h>\n#include <stdio.h>\n#include <uuid/uuid.h>\n\n" &
  17.             "char out[UUID_STR_LEN]={0};\n\n"
  18.             "char * creauuid() {\n\n" &
  19.             "uuid_t i;\n\n" &
  20.             "   uuid_generate(i);\n\n" &
  21.             "   uuid_unparse_lower(i, out);\n\n" &
  22.             " return out;\n\n}")
  23.   
  24.   Shell "gcc -o /tmp/libcreauuid.so /tmp/libcreauuid.c -luuid -shared -fPIC" Wait
  25.   



"Los horizontes perdidos nunca regresan. " (F. Battiato, La stagione dell'amore, 1983)

"Las ondas nunca regresan. " (Genesis: Ripples - A trick of the tail, 1976)
[-] Los siguientes 2 usuarios dicen gracias a vuott por este post:
  • Shordi, tincho
    ¡Gracias!
#19

(12-05-2023, 14:16)vuott escribió:  He encontrado un ejemplo en lenguaje C que funciona, pero cuando lo traduzco a Gambas:

Si, vi ese código también pero no supe convertirlo a gambas, te felicito por hacerlo.
(12-05-2023, 14:16)vuott escribió:  me da un Sad error en la primera función externa de la librería 'libuuid'.

Estoy probando tu código y también me da error.
(12-05-2023, 13:32)Shordi escribió:  ¿Insuficiente para qué? Creo que no he entendido el problema aún...

El objetivo es lograr un UUID (como el definido en el estándar RFC 4122) en gambas si recurrir a uuidgen (el programa de la terminal de Linux) ni tomarlo del archivo "/proc/sys/kernel/random/uuid"

Para mas información sobre que las características técnicas de un UUID vean el siguiente articulo de wikipedia:
https://es.wikipedia.org/wiki/Identifica..._universal
Cita:Una muestra de 3,26*10¹⁶ UUID tiene un 99,99% de posibilidades de no tener duplicados. Generar tantos UUID, a razón de uno por segundo, llevaría mil millones de años. Así que, aunque los UUID no son realmente únicos, sí lo son lo suficiente a efectos prácticos, teniendo en cuenta las limitaciones naturales de la vida humana y la separación de los sistemas.

(12-05-2023, 13:58)tercoide escribió:  Claro, Tincho necesita un UUID de algun tipo para asociarlo a algun dato, que puede ser cualquier cosa. Pero para poder responder a su inquietud es necesario saber para que lo necesita.

Para que lo necesito en este caso es para asignar una clave única a cada ítem de una lista de una colección. Para lo que valdría la ultima versión del código de Shordi, que ademas tiene la ventaja de permitir ordenar la lista por dichas claves. Pero este post apunta a otro sitio.

Mi pregunta es mas general y no esta sujeta a un entorno en concreto, sino que (si leen la definición del UUID de wikipedia) se trata de obtener el identificador con recursos de gambas o tal vez con Extern y la librería libuuid, que cumpla con el estándar RFC 4122.

(11-05-2023, 18:01)tercoide escribió:  La palabra "universal" implica otros planetas lejanos?

La respuesta a esto, aunque parezca un chiste, es si. Smile

1 Saludo.
    ¡Gracias!
#20

Bueno lo que compartió Vuott funciono perfectamente, les dejo aquí el código adaptado a trabajar como una función (uuid.class):
GAMBAS
  1. ' Gambas class file
  2.  
  3.  
  4. Library "libuuid"
  5.  
  6. Private Const UUID_STR_LEN As Integer = 37
  7.  
  8. ' void uuid_generate(uuid_t out)
  9. Private Extern uuid_generate(out As Integer)
  10.  
  11. ' void uuid_unparse_lower(const uuid_t uu, char *out)
  12. Private Extern uuid_unparse_lower(uu As Integer, out As Byte[]) As Integer
  13.  
  14. Private Extern creauuid() As Pointer In "/tmp/libcreauuid"
  15.  
  16.  
  17.  
  18.   If Not Exist("/tmp/libcreauuid.so") Then
  19.     File.Save("/tmp/libcreauuid.c", "#include <stdlib.h>\n#include <stdio.h>\n#include <uuid/uuid.h>\n\n" &
  20.       "char out[UUID_STR_LEN]={0};\n\n"
  21.     "char * creauuid() {\n\n" &
  22.       "uuid_t i;\n\n" &
  23.       "   uuid_generate(i);\n\n" &
  24.       "   uuid_unparse_lower(i, out);\n\n" &
  25.       "   return out;\n\n}")
  26.  
  27.     Shell "gcc -o /tmp/libcreauuid.so /tmp/libcreauuid.c -luuid -shared -fPIC" Wait
  28.  
  29.   p = creauuid()
  30.  
  31.   Return String@(p)
  32.  



El código de Shordi es el mas rápido de todos y si bien no genera un uuid estándar, funcionaria muy bien entornos locales incluso puede incorporarse algún prefijo para diferenciar una computadora de otra. Pero no en el infinito y mas allá !! Big Grin
Lo usare para generar las claves del control de listas.
Dejo el código toqueteado:
GAMBAS
  1.  
  2.   Static nkey As Integer
  3.   Static sLastKey As String
  4.   Dim sOffset As String
  5.   Static sCurrKeytKey As String
  6.   Dim sMark As String
  7.   ' Utilizo la forma ISO 2023-05-12 22:48:01.235
  8.   sCurrKeytKey = Format(Now(), "yyyymmddhhnnssuu")
  9.   If sCurrKeytKey <> sLastKey Then
  10.     sLastKey = sCurrKeytKey
  11.     nkey = 0
  12.     ' Pongo una marca para saber donde se resetea el contador, luego en produccion hay que comentar est alinea
  13.     sMark = "---"
  14.  
  15.   sOffset = Right("00000" & Str(nkey), 5) & sMark
  16.   sMark = ""
  17.   Inc nkey
  18.   Return sCurrKeytKey & sOffset
  19.  



La velocidad de cada método es la siguiente:
 
Cita:Algorithm Kernel works, for 100000 attempts it took 0.743848797999817 milliseconds.
Algorithm Timestamp works, for 100000 attempts it took 0.14394091000031 milliseconds.
The algorithm Randomize is risky as out of a rate of 100000 attempts only 99999 were unique.
Algorithm C-Library works, for 100000 attempts it took 0.985727743000098 milliseconds.

Las conclusiones que saco son las siguientes:
  • Si hay que registrar los datos, utilizo el UUID del Kernel(Tincho) como ID del registro y el Timestamp(Shordi) es decir como te llamas y cuando viniste, son dos conceptos distintos, dos campos distintos.
  • Si NO hay que registrar los datos, o por lo menos no hay que usar el UUID para ello con un simple numero vale, en el caso de las colecciones con un String HEX valdría.
TercoIDE tiene que enviar la función de como lo hacia en GambasCAD para las entidades. Big Grin

[Imagen: 0n8qctn.png]

1 Saludo.
    ¡Gracias!


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)