Generating a CUID (Collision-resistant Unique Identifier) in Delphi involves using various functions to achieve timestamp generation, counter management, machine fingerprinting, and randomness. Delphi provides robust libraries for handling these operations, though some custom implementation is necessary.
Steps to Generate a CUID in Delphi
- Timestamp: Use the current timestamp.
- Counter: Implement a counter mechanism.
- Fingerprint: Generate a machine-specific fingerprint.
- Randomness: Add random characters.
- Base36 Encoding: Encode components in Base36.
Example Code
Here's an example implementation of a CUID generator in Delphi:
unit CUIDGenerator;
interface
uses
System.SysUtils, System.DateUtils, System.Hash, System.Math, IdGlobal, IdStack, IdStackWindows;
function GenerateCUID: string;
implementation
const
Base36Chars: array[0..35] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
var
LastTimeStamp: Int64 = 0;
Counter: Integer = 0;
function EncodeBase36(Value: Int64): string;
begin
Result := '';
while Value > 0 do
begin
Result := Base36Chars[Value mod 36] + Result;
Value := Value div 36;
end;
Result := Result.PadLeft(8, '0');
end;
function GetMachineFingerprint: string;
var
Hash: THashMD5;
begin
Hash := THashMD5.Create;
try
Result := Hash.GetHashString(GStack.LocalAddress);
Result := Copy(Result, 1, 4);
finally
Hash.Free;
end;
end;
function GetRandomString(Length: Integer): string;
var
I: Integer;
begin
Result := '';
for I := 1 to Length do
Result := Result + Base36Chars[Random(36)];
end;
function GenerateCUID: string;
var
Timestamp: Int64;
CounterValue: Integer;
TimestampPart, CounterPart, FingerprintPart, RandomPart: string;
begin
Timestamp := DateTimeToUnix(Now) * 1000;
// Simple counter mechanism
if Timestamp = LastTimeStamp then
begin
Inc(Counter);
end
else
begin
LastTimeStamp := Timestamp;
Counter := 0;
end;
CounterValue := Counter;
// Encode components in Base36
TimestampPart := EncodeBase36(Timestamp);
CounterPart := EncodeBase36(CounterValue);
FingerprintPart := GetMachineFingerprint;
RandomPart := GetRandomString(4);
// Combine components to form the CUID
Result := 'c' + TimestampPart + CounterPart + FingerprintPart + RandomPart;
end;
end.
Explanation
Base36 Encoding:
- The
EncodeBase36
function converts a number to a Base36 encoded string, padded to ensure a consistent length.
- The
Timestamp:
Timestamp := DateTimeToUnix(Now) * 1000
gets the current timestamp in milliseconds.
Counter:
- The counter is incremented if the timestamp is the same as the last one, ensuring uniqueness for multiple CUIDs generated in quick succession.
Machine Fingerprint:
GetMachineFingerprint
generates a fingerprint using the machine's local IP address hashed with MD5, taking the first 4 characters.
Random String:
GetRandomString
generates a random string of specified length using Base36 characters.
Combine Components:
- The
GenerateCUID
function combines the timestamp, counter, fingerprint, and random parts to form the final CUID.
- The
Summary
This Delphi implementation of CUID generation uses available libraries and functions to handle timestamps, hashing, and randomness. The approach ensures that the generated CUIDs are unique, readable, and collision-resistant, making them suitable for various applications.