Private/New-QAOpsUlid.ps1
|
function New-QAOpsUlid { <# Generates a canonical ULID using 48-bit Unix milliseconds plus 80 cryptographic random bits; PowerShell 5.1 compatible. #> [CmdletBinding()] param() $epoch = [DateTime]::SpecifyKind([DateTime]'1970-01-01T00:00:00Z',[DateTimeKind]::Utc) $ms = [Int64]([Math]::Floor(([DateTime]::UtcNow - $epoch).TotalMilliseconds)) $bytes = New-Object byte[] 16 for ($i=5; $i -ge 0; $i--) { $bytes[$i] = [byte]($ms -band 0xff); $ms = [Math]::Floor($ms / 256) } $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create() try { $random = New-Object byte[] 10; $rng.GetBytes($random); [Array]::Copy($random,0,$bytes,6,10) } finally { $rng.Dispose() } $alphabet = '0123456789ABCDEFGHJKMNPQRSTVWXYZ' $value = [System.Numerics.BigInteger]::Zero $be = New-Object byte[] 17 for ($i=0; $i -lt 16; $i++) { $be[$i] = $bytes[15-$i] } $value = New-Object System.Numerics.BigInteger (, $be) $chars = New-Object char[] 26 for ($i=25; $i -ge 0; $i--) { $idx = [int]($value % 32); $chars[$i] = $alphabet[$idx]; $value = [System.Numerics.BigInteger]::Divide($value, 32) } -join $chars } |