Skip to content

Instantly share code, notes, and snippets.

@xmonader
Created December 17, 2022 07:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xmonader/b0b277124a6f67d063881c55d8d5eacf to your computer and use it in GitHub Desktop.
Save xmonader/b0b277124a6f67d063881c55d8d5eacf to your computer and use it in GitHub Desktop.
uuid.pas
{$mode objfpc}{$H+}
unit UUID;
interface
uses
Classes, SysUtils, Math;
type
TUUID = packed record
TimeLow: LongWord;
TimeMid: Word;
TimeHiAndVersion: Word;
ClockSeqHiAndReserved: Byte;
ClockSeqLow: Byte;
Node: array[0..5] of Byte;
end;
function GenerateUUID: TUUID;
function UUIDToString(const UUID: TUUID): String;
function StringToUUID(const UUIDStr: String): TUUID;
implementation
function GenerateUUID: TUUID;
var
Rand: TMemoryStream;
Bytes: array[0..15] of Byte;
begin
Rand := TMemoryStream.Create;
try
Rand.LoadFromFile('/dev/urandom');
Rand.ReadBuffer(Bytes, SizeOf(Bytes));
finally
Rand.Free;
end;
Result.TimeLow := (Bytes[0] shl 24) or (Bytes[1] shl 16) or (Bytes[2] shl 8) or Bytes[3];
Result.TimeMid := (Bytes[4] shl 8) or Bytes[5];
Result.TimeHiAndVersion := (Bytes[6] shl 8) or Bytes[7];
Result.ClockSeqHiAndReserved := Bytes[8];
Result.ClockSeqLow := Bytes[9];
Result.Node[0] := Bytes[10];
Result.Node[1] := Bytes[11];
Result.Node[2] := Bytes[12];
Result.Node[3] := Bytes[13];
Result.Node[4] := Bytes[14];
Result.Node[5] := Bytes[15];
end;
function UUIDToString(const UUID: TUUID): String;
begin
Result := Format('%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x',
[UUID.TimeLow, UUID.TimeMid, UUID.TimeHiAndVersion,
UUID.ClockSeqHiAndReserved, UUID.ClockSeqLow,
UUID.Node[0], UUID.Node[1], UUID.Node[2],
UUID.Node[3], UUID.Node[4], UUID.Node[5]]);
end;
function StringToUUID(const UUIDStr: String): TUUID;
var
Parts: TStringList;
begin
Parts := TStringList.Create;
try
ExtractStrings(['-'], [' '], PChar(UUIDStr), Parts);
Result.TimeLow := StrToInt('$' + Parts[0]);
Result.TimeMid := StrToInt('$' + Parts[1]);
Result.TimeHiAndVersion := StrToInt('$' + Parts[2]);
Result.ClockSeqHiAndReserved := StrToInt('$' + Parts[3][1]);
Result.ClockSeqLow := StrToInt('$' + Parts[3][2]);
Result.Node[0] := StrToInt('$' + Parts[4][1] + Parts[4][2]);
Result.Node[1] := StrToInt('$' + Parts[4][3] + Parts[4][4]);
Result.Node[2] := StrToInt('$' + Parts[4][5] + Parts[4][6]);
Result.Node[3] := StrToInt('$' + Parts[4][7] + Parts[4][8]);
Result.Node[4] := StrToInt('$' + Parts[4][9] + Parts[4][10]);
Result.Node[5] := StrToInt('$' + Parts[4][11] + Parts[4][12]);
finally
Parts.Free;
end;
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment