Comunidad Gambas-es
Identificador único universal - Versión para impresión

+- Comunidad Gambas-es (https://gambas-es.org)
+-- Foro: Gambas (https://gambas-es.org/forum-3.html)
+--- Foro: Aplicaciones/Fragmentos de Código (https://gambas-es.org/forum-8.html)
+--- Tema: Identificador único universal (/thread-1355.html)

Páginas: 1 2 3


Identificador único universal - tincho - 09-05-2023

Hola amigos.

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

Código:
Private Function UUID() As String

  Return RTrim(File.Load("/proc/sys/kernel/random/uuid"))

End
[1] https://es.wikipedia.org/wiki/Identificador_%C3%BAnico_universal
[1] https://en.wikipedia.org/wiki/Universally_unique_identifier


RE: Identificador único universal - Shordi - 10-05-2023

Ni idea, oiga
Confused Confused


RE: Identificador único universal - vuott - 10-05-2023

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.
Código:
Public Sub Main()
 
 Dim listaID as String[]
 
 listaID = Dir("/dev/disk/by-id").Sort(gb.Ascent)
 
' Una vez obtenida la lista de discos duros de forma ordenada, se elige el primero que esté presente:
 Print listaID[0]
 
End



RE: Identificador único universal - tincho - 10-05-2023

(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.


RE: Identificador único universal - vuott - 11-05-2023

Confused  Quizás... podrías usar este código:

Código:
Public Sub Main()

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

Private Function Rand32() As Integer
    
  Dim dd As Integer = DateDiff("01/01/1970", Now, gb.Second)
    
  Return (Lsl(Rand(dd) And &03, 30)) Or (Lsl(Rand(dd) And &7fff, 15)) Or (Rand(dd) And &7fff)
 
End



RE: Identificador único universal - tincho - 11-05-2023

(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

Código:
Static Public Function Rand32() As String

  Dim dd As Integer = DateDiff("01/01/1970", Now, gb.Second)
  Dim ra As Integer
  Dim s As String

  ra = (Lsl(Rand(dd) And &03, 30)) Or (Lsl(Rand(dd) And &7fff, 15)) Or (Rand(dd) And &7fff)
  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)

  Return s

End

Gracias Vuott.


RE: Identificador único universal - Shordi - 11-05-2023

¿No te vale símplemente un

[code]

, por ejemplo?

Es un valor que no se va a volver a repetir nunca.


RE: Identificador único universal - tincho - 11-05-2023

(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?

Código:
' Gambas class file

Public t2 As Integer
Public hTimer As Timer

Public Sub Form_Open()

  hTimer = New Timer As "MyTimer"
  hTimer.Restart

End

Public Sub MyTimer_Timer()

  t2 = t2 + 2

End

Public Sub Button1_Click()

  Dim i, j, t As Integer
  Dim a As New String[]
  Dim sKey As String
  Dim o As Collection = ["Process": 1, "Format": 2, "Randomize": 3]

  j = 20000

  For Each t In o
    a.Clear
    t2 = 0
    hTimer.Restart
    For i = 1 To j
      Select t
        Case 1
          sKey = UUID()

        Case 2
          sKey = UIDBro()

        Case 3
          sKey = Rand32()

      End Select

      If Not a.Exist(sKey) Then
        a.Add(sKey)
      Endif
    Next
    'hTimer.Stop
    If a.Count < j Then
      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)))
    Else
      Message.Info(Subst(("Algorithm &1 works, for &2 attempts it took &3 milliseconds."), o.Key, CStr(j), CStr(t2)))
    Endif
  Next

End

Private Function UUID() As String

  Return RTrim(File.Load("/proc/sys/kernel/random/uuid"))

End

Private Function UIDBro() As String

  Return Format(Now(), "ddmmyyyhhnnssuu")

End

Private Function Rand32() As String

  Dim dd As Integer = DateDiff("01/01/1970", Now, gb.Second)
  Dim ra As Integer
  Dim s As String

  ra = (Lsl(Rand(dd) And &03, 30)) Or (Lsl(Rand(dd) And &7fff, 15)) Or (Rand(dd) And &7fff)
  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)

  Return s

End



RE: Identificador único universal - Shordi - 11-05-2023

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


RE: Identificador único universal - tincho - 11-05-2023

(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