AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein TGUID - einzigartige ID auf andere Computer Systeme ?
Thema durchsuchen
Ansicht
Themen-Optionen

TGUID - einzigartige ID auf andere Computer Systeme ?

Ein Thema von paule32.jk · begonnen am 20. Okt 2023 · letzter Beitrag vom 2. Nov 2023
Antwort Antwort
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 27. Okt 2023, 18:42
Danke Euch.

@Sinspin
Eine Änderung des Zeitstempels (des Realwertes) sollte m.E. nur möglich sein, wenn man mit den Werten rechnet.

Ich
- ermittle jedoch den Wert nur einmalig,
- speichere ihn in die Variablen,
- übergebe ich an Methoden,
- schreibe in in einen Stream,
- wandle ihn in einen String um und zurück,
- und vergleiche die Werte auf Gleichheit.

Besteht auch in diesen Fällen die Gefahr einer Verfälschung?
Wenn nicht, würde ich lieber bei den Timestamps bleiben, da diese dann beim Debugging auch besser einzuordnen sind(gestern erzeugt oder letzten Monat).

Die Systemlaufzeit wäre gleich sicher aber weniger sprechend. Wenn in meinem Anwendungsfall tatsächlich die Gefahr einer Timestampverfälschung bestehen kann, dann würde ich aber tatsächlich lieber umstellen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
mytbo

Registriert seit: 8. Jan 2007
461 Beiträge
 
#2

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 27. Okt 2023, 22:48
Für alle, die es schon vermisst haben, mORMot hat dieses Angebot:
Zitat:
TSynUniqueIdentifierGenerator: thread-safe 64-bit integer unique identifier computation
- contain generation time
- they are increasing over time (so are much easier to store/shard/balance than UUID/GUID)
- each identifier would contain a 16-bit process identifier, which is supplied by the application
- identifiers may be obfuscated as hexadecimal text, using both encryption and digital signature
Hier etwas Quelltext:
Delphi-Quellcode:
uses
  mormot.core.base,
  mormot.core.unicode,
  mormot.crypt.secure;

var
  guid: Int64;
  guidStr: String;
  guidGen: TSynUniqueIdentifierGenerator;
begin
  guidGen := TSynUniqueIdentifierGenerator.Create({Identifier:}12345, {SharedObfuscationKey:}'TopSecret', 10); // create once in application
  try
    guid := guidGen.ComputeNew;
    ShowMessage(Format('Guid: %s', [guid.ToString]));

    guidStr := Utf8ToString(guidGen.ToObfuscated(guid));
    ShowMessage(Format('Guid obfuscated: %s', [guidStr]));

    var fromObfuscatedGuid: TSynUniqueIdentifier; // Int64
    if guidGen.FromObfuscated(StringToUtf8(guidStr), fromObfuscatedGuid) then
      ShowMessage(Format('Guid: %d, From obfuscated: %d', [guid, Int64(fromObfuscatedGuid)]));

    var guidBits: TSynUniqueIdentifierBits;
    guidBits.From(guid);
    ShowMessage(Format('DateTime created: %s', [DateTimeToStr(guidBits.CreateDateTime)]));

    ShowMessage(Format('JSON: %s', [Utf8ToString(guidBits.AsVariant._JSON)]));
  finally
    guidGen.Free;
  end;
Im Beispiel ist der Identifikator "12345". Es stehen 16-Bit zur Verfügung. Eine Möglichkeit wäre, jedem Kunden/Installation eine eigene zuzuweisen.

Die Ausgabe für das Beispiel ist:
Code:
Guid: 3647375681599078401
Guid obfuscated: 7dc1647a8d032aaeebe65dff209d32ff
Guid: 3647375681599078401, From obfuscated: 3647375681599078401
DateTime created: 27.10.2023 21:20:55
JSON: {"Created":"2023-10-27T21:20:55","Identifier":12345,"Counter":1,"Value":3647375681599078401,"Hex":"329E14DB981C8001"}
Bis bald...
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.012 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 28. Okt 2023, 19:37
Dieser Thread erinnert mich stark an https://xkcd.com/927/
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
627 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 30. Okt 2023, 08:23
Ich
- ermittle jedoch den Wert nur einmalig,
- speichere ihn in die Variablen,
- übergebe ich an Methoden,
- schreibe in in einen Stream,
- wandle ihn in einen String um und zurück,
- und vergleiche die Werte auf Gleichheit.

Besteht auch in diesen Fällen die Gefahr einer Verfälschung?
D11 System.Pas:
TDateTime = type Double; Ein Gleitkommazahlenwert ist intern als Bruch gespeichert, um so weiter Du hinter das Komma kommst um so ungenauer wird die Zahl.
Es hängt davon ab wie Du umwandelst. Also wieviele Stellen nach dem Komma mit erfasst werden um eine ausreichend genau zu sein.
Beim zurück wandeln von String in Gleitkomma ensteht intern mit hoher Wahrscheinlichkeit eine andere Zahl / anderer Bruch, wenn Du nicht sicherstellst das Du wieder eine ausreichende Anzahl von Nachkommastellen lieferst.

Vergleichen von Gleitkommazahlen ist wie Lose ziehen. Die Operationen finden zwar mit dem Wissen statt dass Gleitkommazahlen verglichen werden, aber 100% sicher ist das nicht.
Was klappt, aber langsam ist, wäre erst in Zeit-String-Representation umwandeln.

Generell macht es wenig Sinn sich mit Gleitkommazahlen rumzuquählen wenn es nicht unbedingt sein muss.
Deswegen wird in vielen OS darauf verzichtet. Warum Delphi sich den Schuss ins Knie geleistet hat und steif daran festhält erschließt sich mir nicht.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
Benutzerbild von paule32.jk
paule32.jk

Registriert seit: 24. Sep 2022
Ort: Planet Erde
218 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 30. Okt 2023, 09:15
Hallo,

auf welcher Basis ist denn der Delphi TDateTime ?
Wenn denn dann die Unix ist - also die bei 1970 anfängt...
... dann ist bei 2038 Sense im Gelände.

Ich weiß zwar nicht, ob ich an diesen Datum noch programmiere ... aber vielleicht ist das ja was interessantes für die jüngere Generation ...
Frag doch einfach
Alles was nicht programmiert werden kann, wird gelötet
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.434 Beiträge
 
Delphi 7 Professional
 
#6

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 30. Okt 2023, 09:24
Suchmaschine meiner WahlTDateTime Delphi

Delphihilfe: System.TDateTime
  Mit Zitat antworten Zitat
Benutzerbild von paule32.jk
paule32.jk

Registriert seit: 24. Sep 2022
Ort: Planet Erde
218 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 30. Okt 2023, 10:05
okay, war ne doofe Frage ...
hätte ich auch gleich drauf kommen können ...
siehe Anhang (Bild) ...
Angehängte Grafiken
Dateityp: jpg bigdate.jpg (88,4 KB, 44x aufgerufen)
Frag doch einfach
Alles was nicht programmiert werden kann, wird gelötet
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 30. Okt 2023, 13:58
Vielen Dank für die Infos und Hilfen!


Ich habe mir mal angehen, wie TSystemTime realisiert ist.
Nur mal eine kurze Übersicht, falls es jemanden direkt interessiert:
Delphi-Quellcode:
  PSystemTime = ^TSystemTime;
  _SYSTEMTIME = record
    wYear: Word;
    wMonth: Word;
    wDayOfWeek: Word;
    wDay: Word;
    wHour: Word;
    wMinute: Word;
    wSecond: Word;
    wMilliseconds: Word;
  end;
  {$EXTERNALSYM _SYSTEMTIME}
  TSystemTime = _SYSTEMTIME;
  SYSTEMTIME = _SYSTEMTIME;
  {$EXTERNALSYM SYSTEMTIME}
Das braucht natürlich einiges an Speicherplatz. Ich habe mich jetzt für GetTickCount entschieden, das die Systemlaufzeit als Cardinalwert zurück liefert.

Als Korrektur will ich die neue Unit nochmal hier einbinden. Vielleich hilf es ja mal jemandem.

Delphi-Quellcode:
unit myGuid;

interface

  uses

    System.Classes;

  type

    PmyGUID = ^TmyGUID;

    TmyGUID = record //: 12 Byte / 96 Bit
      C : Cardinal; //: 4 Byte / 32 Bit
      TS1: Cardinal; //: 4 Byte / 32 Bit
      TS2: Cardinal; //: 4 Byte / 32 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.Hash, Winapi.Windows;

  const

    MaxCardinal = 4294967295;

  var

    customTS1: Cardinal = 0;
    customTS2: Cardinal = 0;
    customC : Cardinal = 0;

  {: **************************************** TmyGUID *************************************** :}

  {: ---------------------------------------- default --------------------------------------- :}

  //: 2023-10-30
  class function TmyGUID.Create(const aGuid: String): TmyGUID;
  begin
    if (aGuid <> '') then
      begin
        Result := TmyGUID.CreateEmpty;
        Result.FromString(aGuid)
      end
    else
      begin
        Result := TmyGUID.CreateNew;
      end;
  end;

  //: 2023-10-30
  class function TmyGUID.Create(const aGuid: TmyGUID): TmyGUID;
  begin
    Result := aGuid;
  end;

  //: 2023-10-30
  class function TmyGUID.Create(const aGuid: PmyGUID): TmyGUID;
  begin
    Result := aGuid^;
  end;

  //: 2023-10-30
  class function TmyGUID.CreateEmpty: TmyGUID;
  begin
    Result.TS1 := 0;
    Result.TS2 := 0;
    Result.C := 0;
  end;

  //: 2023-10-30
  class function TmyGUID.CreateNew: TmyGUID;
  begin
    customTS2 := GetTickCount;
    Result.TS1 := customTS1;
    Result.TS2 := customTS2;
    Result.C := customC;
    if (customC = MaxCardinal) then
      customC := 0
    else
      Inc(customC);
  end;

  //: 2023-10-30
  class function TmyGUID.StringIsValidGuid(const aGuid: String): Boolean;
  var
    I: Integer;
    C: Char;
  begin
    //: #FFFFFFFF-FFFFFFFF-FFFFFFFF
    //: 123456789012345678901234567 - > Length = 27
    if (Length(aGuid) = 27) 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;
              10, 19:
                if C <> '-then
                  begin
                    Result := False;
                    Break;
                  end;
            else
              if not CharInSet(C, ['0'..'9', 'A'..'F']) then
                begin
                  Result := False;
                  Break;
                end;
            end;
          end;
      end
    else
      Result := False;
  end;

  //: 2023-10-30
  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-30
  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-30
  function TmyGuid.GetHashCode: Integer;
  begin
    Result := 17;
    Result := Result * 397 + Integer(C);
    Result := Result * 397 + THashBobJenkins.GetHashValue(TS1, sizeOf(Cardinal), 5);
    Result := Result * 397 + THashBobJenkins.GetHashValue(TS2, sizeOf(Cardinal), 7);
  end;

  //: 2023-10-30
  function TmyGUID.IsEmpty: Boolean;
  begin
    Result := ((TS1 = 0) and (Ts2 = 0) and (C = 0));
  end;

  function TmyGUID.ToString: String;
  begin
    //: #FFFFFFFF-FFFFFFFF-FFFFFFFF
    //: 123456789012345678901234567 - > Length = 27
    Result := '#' + TS1.ToHexString + '-' + TS2.ToHexString + '-' + C.ToHexString;
  end;

  //: 2023-10-30
  procedure TmyGUID.DoEmpty;
  begin
    TS1 := 0;
    TS2 := 0;
    C := 0;
  end;

  //: 2023-10-30
  procedure TmyGUID.DoNew;
  var
    lGuid: TmyGUID;
  begin
    lGuid := CreateNew;
    TS1 := lGuid.TS1;
    TS2 := lGuid.TS2;
    C := lGuid.C;
  end;

  //: 2023-10-30
  procedure TmyGUID.FromString(const aGuid: String);
  begin
    //: #FFFFFFFF-FFFFFFFF-FFFFFFFF
    //: 123456789012345678901234567 - > Length = 27
    if (StringIsValidGuid(aGuid)) then
      begin
        TS1 := StrToInt('$' + Copy(aGuid, 2, 8));
        TS2 := StrToInt('$' + Copy(aGuid, 11, 8));
        C := StrToInt('$' + Copy(aGuid, 20, 8));
      end
    else
      begin
        TS1 := 0;
        Ts2 := 0;
        C := 0;
      end;
  end;

  //: 2023-10-30
  procedure TmyGUID.ReadFromStream(const aStream: TMemoryStream);
  begin
    aStream.ReadData(C);
    aStream.ReadData(TS1);
    aStream.ReadData(Ts2);
  end;

  //: 2023-10-30
  procedure TmyGUID.WriteToStream(const aStream: TMemoryStream);
  begin
    aStream.WriteData(C);
    aStream.WriteData(TS1);
    aStream.WriteData(Ts2);
  end;

initialization

  //: 2023-10-30
  customTS1 := GetTickCount;
  customTS2 := GetTickCount;
  customC := 0;

end.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von paule32.jk
paule32.jk

Registriert seit: 24. Sep 2022
Ort: Planet Erde
218 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 30. Okt 2023, 14:09
Vielen Dank für Deinen Code.
Ich würde da noch eine Copyright oder PD Notiz machen ...

Nur mal so als Idee:

vielleicht könntest Du ja den Code auch dafür verwenden, wenn Du mit RPC Gedanken spielst ?
weil, für MIDL und Co. ja viele solcher GUID's verwendet werden.

vielleicht könntest Du ja noch statt einen MemoryStream, ein FileStream einbauen, damit man dann ein Template für die MIDL RPC Dingends hat.

vielleicht könntest Du dann ja auch noch TRY EXCEPT Blöcke einbauen, die dann Fehler abfangen, wenn zum Beispiel Daten geschrieben werden sollen, auf denen man dann keinen Zugriff hat ...

nur mal so gedacht...
Frag doch einfach
Alles was nicht programmiert werden kann, wird gelötet
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.472 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

AW: TGUID - einzigartige ID auf andere Computer Systeme ?

  Alt 30. Okt 2023, 16:08
Das braucht natürlich einiges an Speicherplatz. Ich habe mich jetzt für GetTickCount entschieden, das die Systemlaufzeit als Cardinalwert zurück liefert.
Ich glaube, darüber solltest Du nochmal nachdenken, denn GetTickCount fängt beim Start des Rechners bei 0 an und hat nach ca. 21 Tagen einen Überlauf, d.h. es fängt wieder bei 0 an.

Darauf bin ich vor Jahren mal reingefallen ...
Thomas Mueller
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz