频道分类

Delphi 生成GUID算法的单元

作者:admin 来源: 日期:2020/10/1 20:14:58 人气: 标签:

 
unit uGUID;


{采用的开源算法 https://github.com/martinusso/ulid 加已改造成32位有序GUID}
interface

uses
  DateUtils, SysUtils, Windows;
  //有序的32位id
  function GetULID(QDataTime:TDateTime):string;
  function EncodeTime(Time:Int64):string;
  function EncodeRandom: string;
implementation

const
  ENCODING: array[0..31] of string = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                                      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K',
                                      'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X',
                                      'Y', 'Z'); // Crockford's Base32
  ENCODING_LENGTH = Length(ENCODING);

function GetULID(QDataTime:TDateTime): string;
var vInt64:Int64;
begin
  vInt64 := DateUtils.MilliSecondsBetween(QDataTime, UnixDateDelta);
  Result := EncodeTime(vInt64) + EncodeRandom;
end;

function EncodeRandom: string;
const
  ENCODED_RANDOM_LENGTH = 22;
var
  I: Word;
  Rand: Integer;
begin
  Result := '';
  for I := ENCODED_RANDOM_LENGTH downto 1 do
  begin
    Rand := Trunc(ENCODING_LENGTH * Random);
    Result := ENCODING[Rand] + Result;
  end;
end;

function EncodeTime(Time: Int64): string;
const
  ENCODED_TIME_LENGTH = 10;
var
  I: Word;
  M: Integer;
begin
  Result := '';
  for I := ENCODED_TIME_LENGTH downto 1 do
  begin
    M := (Time mod ENCODING_LENGTH);
    Result := ENCODING[M] + Result;
    Time := Trunc((Time - M) / ENCODING_LENGTH);
  end;
end;

end.