Comunidad Gambas-es

Versión completa: Identificador único universal
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Páginas: 1 2 3
Hola amigos.

¿Hay alguna otra forma mas eficiente, en gambas, de obtener un UUID [1] que la propuesta mas abajo?

GAMBAS
  1.  
  2.   Return RTrim(File.Load("/proc/sys/kernel/random/uuid"))
  3.  


[1] https://es.wikipedia.org/wiki/Identifica..._universal
[1] https://en.wikipedia.org/wiki/Universall...identifier
Ni idea, oiga
Confused Confused
Sólo puedo decirte que:

*  /etc/machine-id  = devuelve un uuid estático (siempre el mismo) durante la sesión.

/proc/sys/kernel/random/uuid  = devuelve un uuid dinámico (varía cada vez que se invoca el archivo que lo contiene).


Como alternativa, para identificar de forma única un ordenador, puedes adoptar el código de identificación del disco duro (HDD). De hecho, los ID de los discos duros dentro del PC son únicos, por lo que no es posible encontrar dos ID idénticos.
GAMBAS
  1. Public Sub Main()
  2.  
  3.  Dim listaID as String[]
  4.  
  5.  listaID = Dir("/dev/disk/by-id").Sort(gb.Ascent)
  6.  
  7. ' Una vez obtenida la lista de discos duros de forma ordenada, se elige el primero que esté presente:
  8.  Print listaID[0]
  9.  


(10-05-2023, 14:01)vuott escribió: [ -> ]/proc/sys/kernel/random/uuid  = devuelve un uuid dinámico

Gracias Vuott, me quedo con este porque necesito varias decenas de estos uuid cada vez que cargo una lista y no es para identificar una computadora.
Confused  Quizás... podrías usar este código:

GAMBAS
  1. Public Sub Main()
  2.  
  3.   Print Hex(Rand32(), 8); "-"; Hex(Rand32() And &ffff&, 4); "-"; Hex((Rand32() And &0fff) Or &4000, 4); "-"; Hex((Rand32() And &3fff) + &8000, 4); "-"; Hex(Rand32() And &ffff&, 4); Hex(Rand32(), 8)
  4.     
  5. End 
  6.  
  7.     
  8.   Dim dd As Integer = DateDiff("01/01/1970", Now, gb.Second)
  9.     
  10.   Return (Lsl(Rand(dd) And &03, 30)) Or (Lsl(Rand(dd) And &7fff, 15)) Or (Rand(dd) And &7fff)
  11.  


(11-05-2023, 01:13)vuott escribió: [ -> ]Quizás... podrías usar este código:

Pues si, es bastante mas rápido que el de proc...
sobre 200000 ejecuciones:
proc... = 2403.589ms
rand32 = 856.945ms

Así que lo incluiré en la clase de funciones y sera el nuevo generador de UUID

GAMBAS
  1.  
  2.   Dim dd As Integer = DateDiff("01/01/1970", Now, gb.Second)
  3.   Dim ra As Integer
  4.  
  5.   ra = (Lsl(Rand(dd) And &03, 30)) Or (Lsl(Rand(dd) And &7fff, 15)) Or (Rand(dd) And &7fff)
  6.   s = Hex(ra, 8) & "-" & Hex(ra And &ffff&, 4) & "-" & Hex((ra And &0fff) Or &4000, 4) & "-" & Hex((ra And &3fff) + &8000, 4) & "-" & Hex(ra And &ffff&, 4) & Hex(ra, 8)
  7.  
  8.   Return s
  9.  



Gracias Vuott.
¿No te vale símplemente un

GAMBAS
  1. format(now(),"ddmmyyyhhnnssuu")



, por ejemplo?

Es un valor que no se va a volver a repetir nunca.
(11-05-2023, 10:26)Shordi escribió: [ -> ]Es un valor que no se va a volver a repetir nunca.

Digamos que la idea de un identificador único es que nunca se repita en ninguna parte.

Si para el muestreo tomas una única maquina y la unidad mínima de tiempo es el micro segundo podría darse que dentro de este ámbito el ID [1] nunca se repetirá, pero si tomas un conjunto mayor, por ejemplo todas maquinas que envían un informe al un servidor central ahí si que existe riesgo de que el mismo ID sea enviado por dos o más maquinas diferentes.
[1] No se cuanto tarda el bucle de gambas pero supongo que sera mayor a 1 micro segundo.

Propongo este código como ejercicio para ver el efecto, en este se podrá apreciar que el método "Format" no funciona incluso en la misma maquina, tal ves si se pudiera usar el micro segundo...
Y ya que estamos ¿Como demomios puedo contar los milisegundos o microsegundos que tarda cada algoritmo ? En mi maquina t2 siempre da 0 ¿Que hago mal?

GAMBAS
  1. ' Gambas class file
  2.  
  3. Public hTimer As Timer
  4.  
  5. Public Sub Form_Open()
  6.  
  7.   hTimer = New Timer As "MyTimer"
  8.   hTimer.Restart
  9.  
  10.  
  11. Public Sub MyTimer_Timer()
  12.  
  13.   t2 = t2 + 2
  14.  
  15.  
  16. Public Sub Button1_Click()
  17.  
  18.   Dim i, j, t As Integer
  19.   Dim a As New String[]
  20.   Dim sKey As String
  21.   Dim o As Collection = ["Process": 1, "Format": 2, "Randomize": 3]
  22.  
  23.   j = 20000
  24.  
  25.   For Each t In o
  26.     a.Clear
  27.     t2 = 0
  28.     hTimer.Restart
  29.     For i = 1 To j
  30.       Select t
  31.         Case 1
  32.           sKey = UUID()
  33.  
  34.         Case 2
  35.           sKey = UIDBro()
  36.  
  37.         Case 3
  38.           sKey = Rand32()
  39.  
  40.       End Select
  41.  
  42.       If Not a.Exist(sKey) Then
  43.         a.Add(sKey)
  44.       Endif
  45.     Next
  46.     'hTimer.Stop
  47.     If a.Count < j Then
  48.       Message.Warning(Subst(("The algorithm &1 is risky as out of a rate of &2 attempts only &3 were unique."), o.Key, CStr(j), CStr(a.Count)))
  49.     Else
  50.       Message.Info(Subst(("Algorithm &1 works, for &2 attempts it took &3 milliseconds."), o.Key, CStr(j), CStr(t2)))
  51.     Endif
  52.   Next
  53.  
  54.  
  55.  
  56.   Return RTrim(File.Load("/proc/sys/kernel/random/uuid"))
  57.  
  58.  
  59.  
  60.   Return Format(Now(), "ddmmyyyhhnnssuu")
  61.  
  62.  
  63.  
  64.   Dim dd As Integer = DateDiff("01/01/1970", Now, gb.Second)
  65.   Dim ra As Integer
  66.  
  67.   ra = (Lsl(Rand(dd) And &03, 30)) Or (Lsl(Rand(dd) And &7fff, 15)) Or (Rand(dd) And &7fff)
  68.   s = Hex(ra, 8) & "-" & Hex(ra And &ffff&, 4) & "-" & Hex((ra And &0fff) Or &4000, 4) & "-" & Hex((ra And &3fff) + &8000, 4) & "-" & Hex(ra And &ffff&, 4) & Hex(ra, 8)
  69.  
  70.   Return s
  71.  


No entiendo muy bien el problema.
Un cliente envía un informe al servidor y quieres que el informe tenga un id único... ¿Dónde? ¿En su nombre?¿En su interior?¿En la base de datos (si es que existe) de informes?.
Si es en la base de datos del servidor existe el formato TimeStamp, que es más o menos el format que sugerí.
Si no es en la base de datos, pues saca el nombre del format de la hora del servidor y así no puede repetirse de ninguna manera. La secuencia sería:
Envío informe->obtengo la hora del servidor (¿Comando Stat quizá?)->le cambio el nombre al informe.
O mejor aún, usa el nombre de máquina (o usuario)+el format. Salvo que tengas máquinas que se llama igual, ya lo tienes y además el propio nombre aporta información de quién lo envió.

Saludos
(11-05-2023, 14:00)Shordi escribió: [ -> ]No entiendo muy bien el problema.

Lo que deseo conseguir es un algoritmo que genere, por si solo sin "preguntarle" nada a ningún otro ordenador, un código único.
Lo del envío del formulario es un ejemplo.
La aplicación que deseo darle ahora mismo es para crear claves de una lista pero como cada ítem es creado en menos de 1 mili segundo con el sistema que propones cada ítem tiene la misma clave.
Puedes verlo corriendo el código que adjunte antes.

Por ejemplo, sobre 200000 intentos el único que no repitió ninguno es el que toma el numero del archivo "/proc/sys/kernel/random/uuid"
Tu método solo 120 y el de Vuott casi lo logra pero repitió unos pocos

Algorithm Process works, for 200000 attempts it took 1.74475777899715 milliseconds.
The algorithm Format is risky as out of a rate of 200000 attempts only 137 were unique.
The algorithm Randomize is risky as out of a rate of 200000 attempts only 199995 were unique.


Sobre 1 millón de intentos
Algorithm Process works, for 1000000 attempts it took 7.289969399 milliseconds.
The algorithm Format is risky as out of a rate of 1000000 attempts only 570 were unique.
The algorithm Randomize is risky as out of a rate of 1000000 attempts only 999887 were unique.

intente hacerlo con 100 millones pero se colgo la maquina Angry
Páginas: 1 2 3