![]() |
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
wir hatten doch mal so ein kleines Thema mit der Reg.DB bei Mathias...
|
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
Zitat:
|
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
War da bei von Windows generierten GUID nicht was mit der MAC-Adresse (einer) der Netzwerkkarten? Ich meine mich dunkel zu erinnern, dass die von Windows mit verwendet wird. Kann aber sein, dass das völliger Unsinn oder veraltet ist.
|
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
es ging mir folgendes durch den Kopf:
- viele spielen doch mit ihren Daten und Programmen, und versehen dann Adressen oder Offsets gerne mit:
Code:
$cafebabe oder:
$cafe oder: $babe oder: $affe |
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
Unter Windows ist die erzeugte GUID unter anderem auf der MAC-Adrese basierend und somit weltweit eindeutig. Du kannst niemals 2x die gleiche GUID bekommen.
|
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
du weißt aber schon, das man die MAC ändern kann ?
|
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
Zitat:
|
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
Ich habe mir für den Zweck eine eigene Guid aufgebaut.
Wichtig ist mir, dass diese global persistent eindeutig sind und dass die Reihenfolge (jedenfalls auf einem Rechner) aufsteigend nachvollziehbar ist. Sie besteht aus zwei Zeitstempeln und einem fortlaufenden Zähler. Der erste Zeitstempel enthält den Moment des Projektstarts (ist also so eine Art Session-ID), der zweite den Moment der ID-Erzeugung. Der Zähler läuft bei jeder ID-Erzeugung weiter zwischen 0 bis 65535. So ist die Reihenfolge gut nachvollziehbar und es gibt noch eine Differenzierung falls doch mal beide Zeitstempel auf zwei Geräten gleich sein sollten. Ich bin nicht auf die Standard-Guid angewiesen und so ist das für mich sinnvoller und nachvollziehbarer. Sie braucht mit 18 Byte zwei Byte mehr als die Standard-Guid.
Delphi-Quellcode:
unit myGuid;
interface uses System.Classes; const MaxWord = 65535; type PmyGuid = ^TmyGuid; TmyGuid = record //: 18 Byte / 144 Bit C : Word; //: 2 Byte / 16 Bit TS1: TDateTime; //: 8 Byte / 64 Bit Ts2: TDateTime; //: 8 Byte / 64 Bit class function Create(const aGuid: PmyGuid): TmyGuid; overload; static; class function Create(const aGuid: String): TmyGuid; overload; static; class function Create(const aGuid: TmyGuid): TmyGuid; overload; static; class function CreateEmpty: TmyGuid; static; class function CreateNew: TmyGuid; static; class function StringIsValidGuid(const aGuid: String): Boolean; static; class operator Equal(const Left, Right: TmyGuid): Boolean; class operator NotEqual(const Left, Right: TmyGuid): Boolean; inline; function GetHashCode: Integer; function IsEmpty: Boolean; function ToString: String; procedure DoEmpty; procedure DoNew; procedure FromString(const aGuid: String); procedure ReadFromStream(const aStream: TMemoryStream); procedure WriteToStream(const aStream: TMemoryStream); end; implementation uses System.SysUtils, System.DateUtils, System.Hash; var customTS1: TDateTime = 0; customTS2: TDateTime = 0; customC : Word = 0; {: *********************************** TmyGuid ********************************** :} {: ----------------------------------- default ---------------------------------- :} //: 2023-10-27 class function TmyGuid.Create(const aGuid: String): TmyGuid; begin Result := TmyGuid.CreateEmpty; Result.FromString(aGuid); end; //: 2023-10-27 class function TmyGuid.Create(const aGuid: TmyGuid): TmyGuid; begin Result := aGuid; end; //: 2023-10-27 class function TmyGuid.Create(const aGuid: PmyGuid): TmyGuid; begin Result := aGuid^; end; //: 2023-10-27 class function TmyGuid.CreateEmpty: TmyGuid; begin Result.TS1 := 0; Result.TS2 := 0; Result.C := 0; end; //: 2023-10-27 class function TmyGuid.CreateNew: TmyGuid; begin customTS2 := Now; if (customC = MaxWord) then customC := 0 else Inc(customC); Result.TS1 := customTS1; Result.TS2 := customTS2; Result.C := customC; end; //: 2023-10-27 class function TmyGuid.StringIsValidGuid(const aGuid: String): Boolean; var I: Integer; C: Char; begin if (Length(aGuid) = 42) then begin Result := True; for I := 1 to Length(aGuid) do begin C := aGuid[I]; case I of 1: if C <> '#' then begin Result := False; Break; end; 19, 37: if C <> '-' then begin Result := False; Break; end; else if not CharInSet(C, ['0'..'9']) then begin Result := False; Break; end; end; end; end else Result := False; end; //: 2023-10-27 class operator TmyGuid.Equal(const Left, Right: TmyGuid): Boolean; begin Result := ((Left.TS1 = Right.TS1) and (Left.TS2 = Right.TS2) and (Left.C = Right.C)); end; //: 2023-10-27 class operator TmyGuid.NotEqual(const Left, Right: TmyGuid): Boolean; begin Result := ((Left.TS1 <> Right.TS1) or (Left.TS2 <> Right.TS2) or (Left.C <> Right.C)); end; //: 2023-10-27 function TmyGuid.GetHashCode: Integer; begin Result := 17; Result := Result * 397 + Integer(C); Result := Result * 397 + THashBobJenkins.GetHashValue(TS1, sizeOf(TDateTime), 5); Result := Result * 397 + THashBobJenkins.GetHashValue(TS2, sizeOf(TDateTime), 7); end; //: 2023-10-27 function TmyGuid.IsEmpty: Boolean; begin Result := ((TS1 = 0) and (Ts2 = 0) and (C = 0)); end; function TmyGuid.ToString: String; var S1, S2, S3: String; begin //: #yyyymmddhhnnsszzz-yyyymmddhhnnsszzz-xxxxx //: #12345678901234567890123456789012345678901 - > Length = 42 if (TS1 = 0) then S1 := '00000000000000000' else S1 := FormatDateTime('yyyymmddhhnnsszzz', TS1); if (Ts2 = 0) then S2 := '00000000000000000' else S2 := FormatDateTime('yyyymmddhhnnsszzz', Ts2); if (C = 0) then S3 := '00000' else S3 := Format('%0.5d', [C]); Result := '#' + S1 + '-' + S2 + '-' + S3; end; //: 2023-10-27 procedure TmyGuid.DoEmpty; begin TS1 := 0; TS2 := 0; C := 0; end; //: 2023-10-27 procedure TmyGuid.DoNew; var lGuid: TmyGuid; begin lGuid := CreateNew; TS1 := lGuid.TS1; TS2 := lGuid.TS2; C := lGuid.C; end; //: 2023-10-27 procedure TmyGuid.FromString(const aGuid: String); function EncodeTS(aGuid: String): TDateTime; var AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; begin AYear := StrToInt(Copy(aGuid, 1, 4)); AMonth := StrToInt(Copy(aGuid, 5, 2)); ADay := StrToInt(Copy(aGuid, 7, 2)); AHour := StrToInt(Copy(aGuid, 9, 2)); AMinute := StrToInt(Copy(aGuid, 11, 2)); ASecond := StrToInt(Copy(aGuid, 13, 2)); AMilliSecond := StrToInt(Copy(aGuid, 15, 3)); Result := EncodeDateTime(AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond); end; begin if (StringIsValidGuid(aGuid)) then begin TS1 := EncodeTS(Copy(aGuid, 2, 17)); Ts2 := EncodeTS(Copy(aGuid, 20, 17)); C := StrToInt(Copy(aGuid, 38, 5)); end else begin TS1 := 0; Ts2 := 0; C := 0; end; end; //: 2023-10-27 procedure TmyGuid.ReadFromStream(const aStream: TMemoryStream); begin aStream.ReadData(C); aStream.ReadData(TS1); aStream.ReadData(Ts2); end; //: 2023-10-27 procedure TmyGuid.WriteToStream(const aStream: TMemoryStream); begin aStream.WriteData(C); aStream.WriteData(TS1); aStream.WriteData(Ts2); end; initialization customTS1 := Now; customTS2 := Now; customC := MaxWord; end. |
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
ich bin mir fast sicher, dass die
Delphi-Quellcode:
so nicht stimmen :angle2:
//: 18 Byte / 144 Bit
|
AW: TGUID - einzigartige ID auf andere Computer Systeme ?
Oh, das stimmt.
SizeOf gibt 24 Byte an, bei TGuid nur 16. Die einzelnen Werte sind ja aber korrekt:
Delphi-Quellcode:
TmyGUID = record
C : Word; //: 2 Byte TS1: TDateTime; //: 8 Byte TS2: TDateTime; //: 8 Byte Summe=18
Delphi-Quellcode:
Wo ist da mein Denkfehler bzw. Wissenslücke?
TGUID = record
D1: Cardinal; //: 4 Byte D2: Word; //: 2 Byte D3: Word; //: 2 Byte D4: array[0..7] of Byte; //: 8 Byte Summe=16 TGuid ist ja auch kein gepackter Record oder so? Mir kam es bei meinen Überlegungen darauf an, ob es "verhältnismäßig" ist, eine eigene Guid zu verwenden. Entsprechend hatte ich die einzelnen Variablen angesehen, die verwendet werden und bin auf die kaum höhere Größe gekommen. Die reale Größe hatte ich dann gar nicht untersucht. EDIT: Ok, mit "packed record" komme ich auf das erwartete Ergebnis. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:57 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz