若要解碼 ULID 時間戳,請取其 26 個 Crockford Base32 字元中的前 10 個,將其視為 48 位元的 Unix 毫秒值;最後 16 個字元包含 80 位元的隨機性,且不影響時間。ULID 設計為可按字典順序排序,因為時間戳位於識別碼最左側,因此正確儲存的正規化字串也能顯示大致的建立時間。ULID 產生器可精準處理這項工作:選擇 Generate 以建立 1 到 100 個單調遞增的 ID,或選擇 Decode、貼上正規化的 ULID,然後讀取其毫秒值與 ISO UTC instants。產生與解碼都在瀏覽器本機進行,因此識別碼與時間戳不會被上傳。本指南同時也是解碼速查表:對應每個字元、說明 48 位元與 80 位元的界限、展示如何在不削弱排序功能的情況下儲存產生的值,並指出哪些情況應予以拒絕,而不是猜測日期。

為何 ULID 產生器適合這項工作
ULID 產生器以單一瀏覽器工作流程處理產生與時間戳解碼。它會建立具正規格化 26 字元、可排序識別碼格式的識別碼,其中包含 48 位元時間欄位與 80 位元隨機欄位。Generate 模式會產生一批單調遞增的 ID,而 Decode 模式會從現有的正規化字串讀取毫秒時間戳。當你需要檢查 ULID、為應用程式測試建立識別碼,或驗證儲存的值仍維持預期格式時,這項工具相當實用。產生、解碼、格式化與複製作業都留在瀏覽器中,因此識別碼與解碼後的時間戳不會被上傳。
ULID 欄位對照表
ULID 的排序行為來自各欄位的位置。時間戳位於最前面,因此可使用一般字典序比較,依時間將識別碼分組。隨機部分位於時間戳之後,提供唯一性支援,但不會參與內嵌日期的計算。
| 元件 | 位置或格式 | 意義 |
|---|---|---|
| 時間戳欄位 | 前 10 個字元 | 以毫秒為單位的 48 位元 Unix 時間戳 |
| 隨機欄位 | 最後 16 個字元 | 80 位元的隨機性 |
| 正規化表示 | 26 個 Crockford Base32 字元 | 固定寬度的可排序識別碼 |
| 正規化字母表 | 32 個可能的符號 | 排除 I、L、O 與 U |
| 時間戳範圍 | 48 位元無符號值 | 0 到 281474976710655 毫秒 |
| 排序假設 | 完整的 26 字元字串 | 逐位元組或相容於 ASCII 的字典序排序規則 |
手動解碼規則:毫秒值是 Crockford Base32 中第 1 到 10 個字元所代表的無符號整數。最後 16 個字元不會改變這項計算。解碼器在正規化後可接受不分大小寫的輸入,但正規化後只接受字母表中的字元。請以大寫儲存,因為大小寫摺疊可能干擾字典序排序。正規化 ULID 規格提供權威的欄位配置與編碼規則。
以三個步驟解碼 ULID 時間戳
下列工作流程涵蓋產生、永久儲存與解碼,且不需逐字目視檢查。
- 選擇 Generate 並設定數量。選擇 1 到 100 的數量,建立一批單調遞增的識別碼。
- 將完整識別碼複製到儲存系統。在保留大小寫的欄位中保留全部 26 個字元,並使用資料庫限制來強制唯一性。
- 選擇 Decode 並讀取內嵌時間。貼上正規化的 ULID,然後讀取顯示的毫秒值與 UTC 時間戳。
Decode 控制項僅適用於正規格化的 26 字元值。其輸出包含底層毫秒值與 UTC instant,而顯示的 ISO 時間代表 UTC。由於時區因素,本機日曆顯示可能呈現不同日期,即使毫秒值並未改變。驗證來自其他系統的識別碼時,請先檢查其長度、正規化字母表、大小寫政策與時間戳範圍,再將解碼結果視為有效的應用程式資料。
單調遞增批次及其精確界限
每次點擊 Generate 都會擷取一個整數毫秒值,並對點擊所建立批次中的每個 ID 使用相同值。瀏覽器的密碼學隨機來源會提供初始的 80 位元隨機值。接著,產生器會將隨機區域逐一遞增 1,包括進位,因此所傳回的字串在一般 ASCII 字典序中嚴格遞增。
這項排序保證僅適用於同一批次內。此工具不會在不同的點擊之間保留識別碼或隱藏狀態,也無法與其他分頁、裝置、服務或先前產生的值協同作業。如果遞增隨機區域會使其 80 位元欄位溢位,產生作業會失敗,而不會繞回。請將產生的順序用於其指定目的,但不要將單調遞增的批次視為獨立系統之間的全域唯一性機制。
讀取時間戳而不過度解讀
毫秒值是在識別碼所屬批次產生時擷取的;解碼只會還原該內嵌值。它是排序索引、日誌關聯與理解記錄順序的實用中繼資料,但並非可信事件發生時間的經驗證事實。任何了解此格式的人都能從識別碼推導出大致的建立時間,因此不應將解碼後的時間戳當作記錄或事件真實性的證據。
時間欄位必須符合從 0 到 281474976710655 毫秒的 48 位元無符號範圍。因此,最大的正規化字串以 7 開頭。以 8 或更高效數字開頭的 26 字元 Base32 值包含超過 128 位元,會被拒絕。這是表示方式的界限,而不是猜測或調整日期的理由。請以解碼器提供的毫秒值與 UTC instant 作為結果,同時記住本機日曆檢視可能因時區而異。
將完整 ULID 儲存在排序安全的綱要中
請在保留大小寫的資料庫欄位中,保留完整的大寫 26 字元值。預期的字典序排序以正規化表示及一般逐位元組或相容於 ASCII 的排序規則為前提。大小寫摺疊、地區設定敏感的排序規則、截斷、填補或欄位大小不足,都可能破壞預期順序。請測試確切的資料庫排序規則與綱要,不要假設兩個在技術上保留大小寫的欄位會以相同方式排序。
永久儲存的資料庫應強制執行唯一性限制,並以不可分割的方式處理衝突。隨機性可降低碰撞機率,但無法提供絕對的唯一性保證。先檢查再插入的工作流程會留下競爭視窗,因此不得將其作為最終的唯一性控制機制。產生器會檢查批次建構與單調遞增溢位,但無法偵測與其他地方建立之值的衝突。
| 儲存或控制選擇 | 可能後果 | 較安全的做法 |
|---|---|---|
| 大小寫摺疊或地區設定敏感的排序規則 | 字典序可能與正規化順序不同 | 保留大小寫並測試確切的排序規則 |
| 截斷、填補或欄位大小不足 | 完整識別碼或其預期順序可能遺失 | 允許全部 26 個正規化字元 |
| 未以不可分割方式處理衝突的先檢查再插入 | 並行請求可能發生競爭 | 使用唯一性限制,並以不可分割方式處理衝突 |
| 隨機性但未由資料庫強制執行 | 無法絕對防止碰撞 | 在永久儲存資料層維護唯一性控制 |
請記住的限制與安全界限
ULID 是識別碼,不是密碼、API 金鑰、持有者權杖、授權規則或加密金鑰。當缺少存取控制時,其可見的時間戳與隨機後綴無法防止記錄遭枚舉或洩漏。請使用目標平台專用的機制產生認證資訊,並將這些認證資訊保存在秘密管理工具中,而不是挪用 ULID。
若必須隱藏大致建立時間,請勿使用 ULID。避免記錄與個人或機密記錄關聯的 ULID,因為日誌可能成為另一條資料洩漏路徑。產生與解碼在本機進行可減少資料傳輸曝露,但無法取代應用程式存取控制或審慎的日誌政策。
實用的速查表規則很簡單:保留正規化的 26 個字元、讓時間戳維持在指定範圍內、在資料庫中強制執行唯一性,並將解碼後的時間視為可見的中繼資料,而非經驗證的事實。