開發者工具 · UUID 產生器
是什麼讓 UUID 字串格式良好,以及檢查器無法知道的內容
· 工作原理
uuid 密碼學 瀏覽器 API
大寫字母、大括號、urn:前綴和缺少的連字符都會出現在實際輸入中。這篇文章定義了規範形式,展示了寬鬆的驗證者應該接受的內容,並將格式良好與存在分開。
400 應該是 404 — 草率的 UUID 驗證會產生令人困惑的 API 錯誤
API 端點從客戶端接收識別碼:{12345678-90AB-CDEF-1234-567890ABCDEF}。驗證程式碼檢查它是否符合 /[0-9a-f]{32}/ 並將其視為無效而拒絕。客戶端收到 400 錯誤請求,其意義是 404 Not Found。此標識符格式良好 - 它是大括號格式的有效 UUID - 但驗證器過於嚴格。相反,接受任何 32 字元十六進位字串(不含破折號)的端點將接受 123456789012345678901234567890123456,將其解析為有效,並錯過拼字錯誤。 RFC 9562 定義了規範的文字表示形式,但現實世界的輸入以五種不同的格式到達,並僅接受規範形式的驗證器將拒絕 1 到 5 的善意輸入。
規格文字形式 — 8-4-4-4-12 中的 32 小寫十六進位數字,恰好是 36 個字元
規範的文字形式是 32 小寫十六進位數字,分為五組,以連字號分隔:8-4-4-4-12。表示為 550e8400-e29b-41d4-a716-446655440000。此標準要求輸出小寫;在輸入時,建議不區分大小寫匹配。這種形式是明確的,在每個平台上都以相同的方式解析為位元組,並是每個 UUID 庫預設輸出的形式。如果您要從 CSPRNG 產生新的 UUID,則規範形式就是您應該產生的內容以及 ToolAcre 產生的內容。現實世界的輸入會以可預測的方式出現偏差。大寫標識符 (550E8400-E29B-41D4-A716-446655440000) 在預設為大寫的系統中很常見;它們代表相同的位元組,在標準化為小寫後應被接受。
您將在野外遇到的變體 — 大寫十六進位、{braces}、urn:uuid: 前綴和 32 字元無連字符形式,以及標準規定接受的變體
大括號形式 ({550e8400-e29b-41d4-a716-446655440000}) 是 Python 的 uuid 模組和 Microsoft 系統的標準輸出;去掉大括號給出了有效的規範形式。 URN 前綴 (urn:uuid:550e8400-e29b-41d4-a716-446655440000) 由 RFC 8141 定義,用於統一資源名稱;刪除方案和剝離標識符前綴留下規範形式。無連字號形式 (550e8400e29b41d4a716446655440000) 是沒有結構的 32 十六進位數字;它是有效位元組,但遺失了8-4-4-4-12 分組,使版本和變體可讀。這些變體都對應到相同的 128 位元值。 RFC 9562 部分 3 宣告在輸入時,應該接受大寫變體。它並不禁止其他變體;它表示在輸出時,必須使用規範的小寫形式。
版本與變體健全性 — 是否拒絕第三組以 0 開頭或第四組以 f 開頭的 UUID
格式良好的驗證器應該: 接受小寫或大寫的規範 8-4-4-4-12 形式;透過剝離它們並驗證核心形式來接受 braced 和 urn: 變體;接受無連字符的 32 位元十六進製字串並將其格式化為規範以進行比較;拒絕十六進位數字或非十六進位字元數量錯誤的字串。最常見的錯誤是拒絕大寫或大括號輸入,因為驗證器是手寫的,僅匹配規範形式。對版本和變體進行健全性檢查可以發現拼字錯誤。如果第三組以0或9開頭,則UUID無效或保留;如果第四組以 e 或 f 開頭,則該變體不是 RFC 9562。
工作範例 - 六個候選字串經過嚴格檢查和寬鬆檢查,並附有每個通過或失敗的原因
寬鬆的驗證器接受這些值;嚴格的驗證者可以拒絕它們。 ToolAcre 格式正確的檢查執行嚴格的驗證:它確認規範的 36 字元形式,並在正確的位置使用破折號,驗證每個位置的十六進位數字,並檢查版本和變體位元是否在範圍內。它不會檢查 UUID 是否存在於您的資料庫中,或者它是否是從加密安全來源產生的;這些是由您的應用程式邏輯完成的單獨檢查。格式正確的並不等於真實的。根據其形狀正確解析的 UUID 字串可能無法辨識資料庫中的任何行。
格式良好並不真實——為什麼您的資料中可能不存在語法上完美的 UUID,以及為什麼檢查器永遠不應該成為您的授權層
格式完美的 UUID 可能被錯誤地猜測或複製貼上。格式驗證是第一道關卡;存在檢查和授權檢查是第二和第三。對資料庫中的每個格式無效的輸入進行查找是一種浪費;在資料庫查詢之前拒絕格式無效的輸入可以節省時間。 ToolAcre 產生器輸出標準 36 字元 UUID;如果您正在建立自己的驗證器,請接受花括號和 urn: 變體以匹配現實世界的輸入,並在詢問資料庫之前拒絕不符合基本形狀規則的字串。實作嚴格的驗證器需要正規表示式和邊緣情況處理。規範形式很簡單:/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i(不區分大小寫)。大括號形式加入大括號:/^\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}$/i. urn: 變體新增方案:/^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.
這不包括 - 規範化儲存 ID 和選擇列類型,這是單獨的決定
處理所有變體的單一正則表達式可讀性較差,但也是可能的。大多數驗證器首先進行規範化:去掉大括號和 urn: 前綴,轉換為小寫,然後匹配規範模式。可以在模式匹配後透過檢查位置 14 和位置 19 來檢查版本和變體位,如 403 文章中所述。優雅地處理無效輸入是驗證設計的一部分。當用戶端提交格式錯誤的 UUID 時,請勿在錯誤訊息中公開正規表示式模式或內部驗證規則。傳回明確的錯誤:「無效的 UUID 格式。應為 8-4-4-4-12 格式,例如 550e8400-e29b-41d4-a716-44665440000。」 不要嘗試更正輸入;要求客戶重新提交。
重點:儘早驗證形狀,單獨查找是否存在-在接觸資料庫之前,ToolAcre 檢查會在瀏覽器中確認形狀
某些系統會記錄無效輸入以進行安全審核(偵測嘗試注入或格式混淆攻擊)。 ToolAcre 驗證器會拒絕非規範表單並給予明確的錯誤訊息,並不會嘗試自動修正。為什麼規範形式對於互通性很重要:如果一個系統將 UUID 儲存為無連字符的十六進制,而另一個系統將它們儲存為規範 8-4-4-4-12,則比較它們是否相等。大寫與小寫需要進行不區分大小寫的比較。支撐與裸露需要剝離。這些變化使得批次操作(匯入、遷移、比較)變得更加困難。輸出規範形式的標準工具可以減少摩擦。 ToolAcre 產生器始終輸出 36 字元小寫規範形式;當您從其他系統匯入 UUID 時,請在 ETL 過程中將它們標準化為這種形式,以確保一致性。