CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Random

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Ground0
Beiträge: 318
Registriert: 05.02.2005 02:09
Wohnort: Stilli, Schweiz
Kontaktdaten:

CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Random

Beitrag von Ground0 »

Wer eine Library unabhängige Zufällige UUID Generieren möchte. Hier ist ein Codeschnipsel aus der derzeitigen SDK

Sorry hate noch einen Fehler drin... (Binär & Hex Konvertierung (8 bit))

Code: Alles auswählen

; WCS_UUID by René Linder
; 
; To the extent possible under law, the person who associated CC0 With
; WCS_UUID has waived all copyright And related Or neighboring rights
; To WCS_UUID.
; 
; You should have received a copy of the CC0 legalcode along With this
; work. If Not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
    
Enumeration WCS_UUID_Version
  #UUID_V1
  #UUID_V2
  #UUID_V3
  #UUID_V4 ; Standard.
  #UUID_V5
EndEnumeration

Procedure.s CreateUUID(Type.i=#UUID_V4, String.s="")
  ;[T] CreateUUID(Type.i, String.s="") 
  ;[D] Gibt eine UUID des Entsprechenden Types  als String zurück.
  ;[D] Derzeit nur Version 4 Implementiert.  
  ;[V] 0.0.1
  ;[M] 0.0.1   
  Protected P_Type.i = Type.i
  Protected P_String.s = String.s
  Protected P_UUID.s = ""
  Protected Dim P_Numbers.a(16)
  ;Protected P_Temp.a
  Protected P_Count.a
  Structure Struc_UUID
    
    low.a  
  EndStructure
  
  Select P_Type
    Case #UUID_V1
      
    Case #UUID_V2
      
    Case #UUID_V3
      
    Case #UUID_V5
      
    Default     ;#UUID_V4 RFC 4122 Konform
                ;xx xx xx xx - xx xx - 4x xx - yx xx - xx xx xx xx xx xx
      *Key = AllocateMemory(16)
      If OpenCryptRandom() And *Key
        CryptRandomData(*Key, 16)
        
        For P_Count = 0 To 15
          P_Numbers(P_Count) = PeekB(*Key+P_Count)
        Next P_Count     
        
        CloseCryptRandom()
      Else
        ;Not Save
        For P_Count = 0 To 15
          P_Numbers(P_Count) = Random(255)
        Next P_Count
      EndIf
      
      If *Key
        FreeMemory(*Key)
      EndIf
      
      P_Numbers(6) = Val("$4"+Right(RSet(Hex(P_Numbers(6), #PB_Byte), 2, "0"), 1))
      P_Numbers(8) = Val("%10"+Right(RSet(Bin(P_Numbers(8), #PB_Byte), 8, "0"), 6))
      P_UUID = ""
      For P_Count = 0 To 15
        If P_Count = 4 Or P_Count = 6 Or P_Count = 8 Or P_Count = 10
          P_UUID + "-"
        EndIf
        P_UUID + RSet(Hex(P_Numbers(P_Count), #PB_Byte), 2, "0")
      Next P_Count
      
  EndSelect
  
  ProcedureReturn P_UUID.s
EndProcedure


;Beispiel Code für zufällige UUID V4 
For Y = 1 To 1000
  Debug CreateUUID()
Next Y

lmon Monitoring Service inkl. Clients
lweb Multi-Threaded Webserver
lbup-server Backup Server applikation
lmanager ERP Applikation.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Ran

Beitrag von ts-soft »

Hier gibt es noch ein Beispiel zur V4: http://www.purebasic.fr/german/viewtopi ... 06#p280506
wobei mir die Version ohne Lib besser gefällt :allright:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Ground0
Beiträge: 318
Registriert: 05.02.2005 02:09
Wohnort: Stilli, Schweiz
Kontaktdaten:

Re: CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Ran

Beitrag von Ground0 »

Meine Intention war eine Unabhängige Version für Win/Lin/Mac zu haben :D

Besteht die Interesse an der V3 & V5 (V1 & V2 werden wahrscheinlich gar nie Implementiert wegen Sicherheitsbedenken MAC Adresse der Netzwerkkarte ist in die UUID eingearbeitet.... nur wenn jemand explizit den Wunsch dazu äussert ;-) )
lmon Monitoring Service inkl. Clients
lweb Multi-Threaded Webserver
lbup-server Backup Server applikation
lmanager ERP Applikation.
Benutzeravatar
Ground0
Beiträge: 318
Registriert: 05.02.2005 02:09
Wohnort: Stilli, Schweiz
Kontaktdaten:

Re: CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Ran

Beitrag von Ground0 »

Nun eine Threadsafe Variante die den CryptoRandom nur einmal öffnet:

Code: Alles auswählen

;**************************************
;* 
;* UUID.pbi
;*
;* (c) by Linder Hard- und Software
;*
;This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. 
;To view a copy of this license, 
;visit http://creativecommons.org/licenses/by-sa/4.0/ 
;OR send a letter To Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

Enumeration WCS_UUID_Version
  #UUID_V1
  #UUID_V2
  #UUID_V3
  #UUID_V4 ; Standard.
  #UUID_V5
EndEnumeration

Global WCS_UUID_CryptRandom.i

If OpenCryptRandom()
  WCS_UUID_CryptRandom = 1
Else 
  WCS_UUID_CryptRandom = 0
EndIf

Procedure.s CreateUUID(Type.i=#UUID_V4, String.s="")
  ;[T] CreateUUID(Type.i, String.s="")
  ;[D] Gibt eine UUID des Entsprechenden Types  als String zurück.
  ;[D] Derzeit nur Version 4 Implementiert. 
  ;[V] 0.0.2
  ;[M] 0.0.2 Threadsafe OpenCryptRandom only Once
  ;[M] 0.0.1   
  Protected P_Type.i = Type.i
  Protected P_String.s = String.s
  Protected P_UUID.s = ""
  Protected Dim P_Numbers.a(16)
  ;Protected P_Temp.a
  Protected P_Count.a
  Protected Key
  
  Structure Struc_UUID
   
    low.a 
  EndStructure
 
  Select P_Type
;     Case #UUID_V1
;      
;     Case #UUID_V2
;      
;     Case #UUID_V3
;      
;     Case #UUID_V5
    Case 10
      
    Default     ;#UUID_V4 RFC 4122 Konform
                ;xx xx xx xx - xx xx - 4x xx - yx xx - xx xx xx xx xx xx
      Key = AllocateMemory(16)

      If WCS_UUID_CryptRandom And Key
        CryptRandomData(Key, 16)
       
        For P_Count = 0 To 15
          P_Numbers(P_Count) = PeekB(Key+P_Count)
        Next P_Count     
       
      Else
        ;Not Save
        For P_Count = 0 To 15
          P_Numbers(P_Count) = Random(255)
        Next P_Count
      EndIf
     
      If Key
        FreeMemory(Key)
      EndIf
     
      P_Numbers(6) = Val("$4"+Right(RSet(Hex(P_Numbers(6), #PB_Byte), 2, "0"), 1))
      P_Numbers(8) = Val("%10"+Right(RSet(Bin(P_Numbers(8), #PB_Byte), 8, "0"), 6))

      P_UUID = ""
      
      For P_Count = 0 To 15
        If P_Count = 4 Or P_Count = 6 Or P_Count = 8 Or P_Count = 10
          P_UUID + "-"
        EndIf
        P_UUID + RSet(Hex(P_Numbers(P_Count), #PB_Byte), 2, "0")
      Next P_Count
     
  EndSelect

  ProcedureReturn P_UUID
EndProcedure

Procedure IsUUID(UUID.s , Type.i = #UUID_V4)
  ;[T] IsUUID(UUID.s , Type.i = #UUID_V4) 
  ;[D] Prüft ob die UUID entsprechend Version 4 und RFC 4122 Konform ist.
  ;[V] 0.0.1
  ;[M] 0.0.1     
  If Mid(UUID.s, 15,1) = Str(Type+1)
    If Left(Bin(Val("$"+Mid(UUID.s, 15,2)), #PB_Byte),2) = "10"
      ProcedureReturn #True
    EndIf
  EndIf
  
  ProcedureReturn #False
EndProcedure
lmon Monitoring Service inkl. Clients
lweb Multi-Threaded Webserver
lbup-server Backup Server applikation
lmanager ERP Applikation.
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Ran

Beitrag von mk-soft »

Würde ich nicht nehmen. Viele UUID sind bereits von System oder Fondations festvergeben.
Das schlimmste was passieren kann ist das ein bereits fest vergebene UUID erzeugst und dann mit der die Registry zerschießt.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
JMaker
Beiträge: 102
Registriert: 19.01.2015 10:18

Re: CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Ran

Beitrag von JMaker »

? UUID ist doch einzigartiger als GUID oder liege ich falsch ? Wird da nicht zu sätzlich mit Zeitstempel generiert ? Wie kann es den die Registry zerschiessen ?
Ich benutze Pure Basic 5.30 auf Microsoft Windows 7.
Gruß
JM
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Ran

Beitrag von ts-soft »

Es ist doch gerade der Sinn der Sache, das möglichst keine gleichen UUIDs erzeugt werden. Mit der Routine können wohl,
mehrere hunderte Jahre lang UUIDs erzeugt werden, ohne das eine bereits vergeben ist oder bereits in der Registry existiert :mrgreen:
GUID und UUID sind dasselbe, nur das GUID eine Bezeichnung von Microsoft ist.

https://de.wikipedia.org/wiki/Universal ... Identifier
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Ran

Beitrag von Kiffi »

Code: Alles auswählen

InitNetwork()

*Buffer = ReceiveHTTPMemory("https://www.uuidgenerator.net/api/version4")
If *Buffer
  Size = MemorySize(*Buffer)
  Debug "UUID: " + PeekS(*Buffer, Size, #PB_UTF8|#PB_ByteLength)
  FreeMemory(*Buffer)
Else
  Debug "Failed"
EndIf
-> How to use the UUIDGenerator.net API

:mrgreen:
Hygge
Benutzeravatar
Ground0
Beiträge: 318
Registriert: 05.02.2005 02:09
Wohnort: Stilli, Schweiz
Kontaktdaten:

Re: CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Ran

Beitrag von Ground0 »

Wow solte mich mal öfters einlogen hier ....
mk-soft hat geschrieben:Würde ich nicht nehmen. Viele UUID sind bereits von System oder Fondations festvergeben.
Das schlimmste was passieren kann ist das ein bereits fest vergebene UUID erzeugst und dann mit der die Registry zerschießt.
Also da eine Gem RFC 4122 Version 4 UUID erzeugt wird ist die Wahrscheinlichkeit < 0,(unendlich 0)1 oder ähnlich das eine doppelte UUID erzeugt wird. Gem. Spezifikation kann das eigentlich nicht passieren und vor allem fest vergebene wie 1.2.3 und 5er.

Code: Alles auswählen

;xx xx xx xx - xx xx - 4x xx - yx xx - xx xx xx xx xx xx
Die 4 an der Stelle sagt / bedeutet das das ein Vollständiger Random UUID ist und da ist definitiv nichts Fest vergeben ;-) Diese Routine arbeitet seit nunmehr 2 Wochen in einer Shared Web/Java/Linux/Windows Umgebung mit Täglich mehr als 100'000 Anfragen Fehlerfrei.

PS: Sorry sollte alles Korrektur lesen vor dem Absenden :freak:
lmon Monitoring Service inkl. Clients
lweb Multi-Threaded Webserver
lbup-server Backup Server applikation
lmanager ERP Applikation.
Benutzeravatar
Ground0
Beiträge: 318
Registriert: 05.02.2005 02:09
Wohnort: Stilli, Schweiz
Kontaktdaten:

Re: CreateUUID(Type.i=#UUID_V4, String.s="") Derzeit nur Ran

Beitrag von Ground0 »

Und nun noch eine Variante aus der Cloud SDK Suite die SpiderBasic & PureBasic Tauglich ist benötigt aber noch das GEN.pbi für den Debug Bereich...

SYS/GEN/GEN.pbi:

Code: Alles auswählen

;**************************************
;* 
;* GEN.pbi
;*
;* Generische Funktionen Makros
;*
;* (c) by Linder Hard- und Software
;*
;This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. 
;To view a copy of this license, 
;visit http://creativecommons.org/licenses/by-sa/4.0/ 
;OR send a letter To Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

CompilerIf Not Defined(WCS_DEBUG, #PB_Constant)
  CompilerError "#WCS_DEBUG Muss Definiert sein"
CompilerEndIf

#Debug_Element = "all"

Macro DebugElement(DebugElements, Lvl)
  If #Debug_Element = "all"
    CompilerIf #PB_Compiler_OS = #PB_OS_Web
      Debug Lvl + DebugElements  
    CompilerElse
      PrintN(Lvl + DebugElements)
    CompilerEndIf
  ElseIf #Debug_Element = Left(DebugElements, Len(#Debug_Element))
    CompilerIf #PB_Compiler_OS = #PB_OS_Web
      Debug Lvl + DebugElements  
    CompilerElse
      PrintN(Lvl + DebugElements)
    CompilerEndIf
  EndIf
EndMacro

Macro DebugLvl0(DebugMSG)
  CompilerIf #WCS_DEBUG >= 0
    ;Debug DebugMSG
    DebugElement(DebugMSG , "lvl0:")
  CompilerEndIf    
EndMacro

Macro DebugLvl1(DebugMSG)
  CompilerIf #WCS_DEBUG >= 1
    ;Debug DebugMSG
    DebugElement(DebugMSG , "lvl1:")
  CompilerEndIf
EndMacro

Macro DebugLvl2(DebugMSG)
  CompilerIf #WCS_DEBUG >= 2
    ;Debug DebugMSG
    DebugElement(DebugMSG , "lvl2:")
  CompilerEndIf
EndMacro

Macro DebugLvl3(DebugMSG)
  CompilerIf #WCS_DEBUG >= 3
    ;Debug DebugMSG
    DebugElement(DebugMSG , "lvl3:")
  CompilerEndIf
EndMacro
SYS/GEN/UUID.pbi

Code: Alles auswählen

;**************************************
;* 
;* UUID.pbi
;*
;* (c) by Linder Hard- und Software
;*
;This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. 
;To view a copy of this license, 
;visit http://creativecommons.org/licenses/by-sa/4.0/ 
;OR send a letter To Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

Enumeration WCS_UUID_Version
  #UUID_V1
  #UUID_V2
  #UUID_V3
  #UUID_V4 ; Standard.
  #UUID_V5
EndEnumeration

Global WCS_UUID_CryptRandom.i

CompilerIf #PB_Compiler_OS = #PB_OS_Web
  WCS_UUID_CryptRandom = 0
CompilerElse
  If OpenCryptRandom()
    WCS_UUID_CryptRandom = 1
  Else 
    WCS_UUID_CryptRandom = 0
  EndIf
CompilerEndIf

Procedure.s CreateUUID(Type.i=#UUID_V4, String.s="")
  ;[T] CreateUUID(Type.i, String.s="")
  ;[D] Gibt eine UUID des Entsprechenden Types  als String zurück.
  ;[D] Derzeit nur Version 4 Implementiert. 
  ;[V] 0.0.1
  ;[M] 0.0.1   
  Protected P_Type.i = Type.i
  Protected P_String.s = String.s
  Protected P_UUID.s = ""
  Protected Dim P_Numbers.a(16)
  ;Protected P_Temp.a
  Protected P_Count.a
  Protected Key
  
  Structure Struc_UUID
   
    low.a 
  EndStructure
 
  Select P_Type
;     Case #UUID_V1
;      
;     Case #UUID_V2
;      
;     Case #UUID_V3
;      
;     Case #UUID_V5
    Case 10
      
    Default     ;#UUID_V4 RFC 4122 Konform
                ;xx xx xx xx - xx xx - 4x xx - yx xx - xx xx xx xx xx xx
      DebugLvl3("CreateUUID: Start Allocate")
      
      Key = AllocateMemory(16)
      ;Key = 0
      DebugLvl3("CreateUUID: Alocated Address:"+Str(Key))
      CompilerIf #PB_Compiler_OS <> #PB_OS_Web
      If WCS_UUID_CryptRandom And Key
      DebugLvl3("CreateUUID: Randomcrypt.")
        
        CryptRandomData(Key, 16)
       
        For P_Count = 0 To 15
          
            P_Numbers(P_Count) = PeekB(Key+P_Count)
          
        Next P_Count     
       
      Else
      CompilerElse
      If WCS_UUID_CryptRandom = 0
      CompilerEndIf
        DebugLvl3("CreateUUID: Unsave Random")
        For P_Count = 0 To 15
          P_Numbers(P_Count) = Random(255)
        Next P_Count
      EndIf
      DebugLvl3("CreateUUID: Memoryfreigabe")
     
      If Key
        FreeMemory(Key)
      EndIf
      DebugLvl3("CreateUUID: P_Numbers")
     
      P_Numbers(6) = Val("$4"+Right(RSet(Hex(P_Numbers(6), #PB_Byte), 2, "0"), 1))
      P_Numbers(8) = Val("%10"+Right(RSet(Bin(P_Numbers(8), #PB_Byte), 8, "0"), 6))
      DebugLvl3("CreateUUID: Umwandeln zu String")
      P_UUID = ""
      For P_Count = 0 To 15
        If P_Count = 4 Or P_Count = 6 Or P_Count = 8 Or P_Count = 10
          P_UUID + "-"
        EndIf
        P_UUID + RSet(Hex(P_Numbers(P_Count), #PB_Byte), 2, "0")
      Next P_Count
     
  EndSelect
  DebugLvl3("CreateUUID: Rückgabe:"+P_UUID)
  ProcedureReturn P_UUID
EndProcedure

Procedure IsUUID(UUID.s , Type.i = #UUID_V4)
  ;[T] IsUUID(UUID.s , Type.i = #UUID_V4) 
  ;[D] Prüft ob die UUID entsprechend Version 4 und RFC 4122 Konform ist.
  ;[V] 0.0.1
  ;[M] 0.0.1     
  If Mid(UUID.s, 15,1) = Str(Type+1)
    If Left(Bin(Val("$"+Mid(UUID.s, 15,2)), #PB_Byte),2) = "10"
      ProcedureReturn #True
    EndIf
  EndIf
  
  ProcedureReturn #False
EndProcedure
lmon Monitoring Service inkl. Clients
lweb Multi-Threaded Webserver
lbup-server Backup Server applikation
lmanager ERP Applikation.
Antworten