不好意思,UUID 該換了!

ULID:Universally Unique Lexicographically Sortable Identifier(通用唯一詞典分類標識符)

UUID:Universally Unique Identifier(通用唯一標識符)

爲什麼不選擇 UUID

UUID 目前有 5 個版本:

版本 1:在許多環境中是不切實際的,因爲它需要訪問唯一的,穩定的 MAC 地址,容易被攻擊;

版本 2:將版本 1 的時間戳前四位換爲 POSIX 的 UID 或 GID,問題同上;

版本 3:基於 MD5 哈希算法生成,生成隨機分佈的 ID 需要唯一的種子,這可能導致許多數據結構碎片化;

版本 4:基於隨機數或僞隨機數生成,除了隨機性外沒有提供其他信息;

版本 5:通過 SHA-1 哈希算法生成,生成隨機分佈的 ID 需要唯一的種子,這可能導致許多數據結構碎片化;

這裏面常用的就是 UUID4 了,但是,即使是隨機的,但是也是存在衝突的風險。

和 UUID 要麼基於隨機數,要麼基於時間戳不同,ULID 是既基於時間戳又基於隨機數,時間戳精確到毫秒,毫秒內有 1.21e + 24 個隨機數,不存在衝突的風險,而且轉換成字符串比 UUID 更加友好。

ULID 特性:

ulid() # 01ARZ3NDEKTSV4RRFFQ69G5FAV

ULID 規範

以下是在 python(ulid-py) 中實現的 ULID 的當前規範。二進制格式已實現

01AN4Z07BY      79KA1307SR9X4MV3

|----------|    |----------------|
 Timestamp          Randomness
  10chars            16chars
   48bits             80bits

組成

時間戳

隨機性

排序

最左邊的字符必須排在最前面,最右邊的字符必須排在最後(詞彙順序)。必須使用默認的 ASCII 字符集。在同一毫秒內,不能保證排序順序

編碼方式

如圖所示,使用了 Crockford 的 Base32。該字母表不包括字母 I,L,O 和 U,以避免混淆和濫用。

0123456789ABCDEFGHJKMNPQRSTVWXYZ

二進制佈局和字節順序

組件被編碼爲 16 個八位位組。每個組件都以最高有效字節在前(網絡字節順序)進行編碼。

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      32_bit_uint_time_high                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     16_bit_uint_time_low      |       16_bit_uint_random      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       32_bit_uint_random                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       32_bit_uint_random                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

應用場景

用法(python)

安裝

pip install ulid-py

創建一個全新的 ULID。

時間戳記值(48 位)來自 time.time(),精度爲毫秒。

隨機值(80 位)來自 os.urandom()

>>> import ulid
>>> ulid.new()
<ULID('01BJQE4QTHMFP0S5J153XCFSP9')>

根據現有的 128 位值(例如 UUID)創建新的 ULID 。支持 ULID 值類型有 int,bytes,str,和 UUID。

>>> import ulid, uuid
>>> value = uuid.uuid4()
>>> value
UUID('0983d0a2-ff15-4d83-8f37-7dd945b5aa39')
>>> ulid.from_uuid(value)
<ULID('09GF8A5ZRN9P1RYDVXV52VBAHS')>

從現有時間戳值(例如datetime對象)創建新的 ULID 。支持時間戳值類型有 int,float,str,bytes,bytearray,memoryview,datetime,Timestamp,和 ULID

>>> import datetime, ulid
>>> ulid.from_timestamp(datetime.datetime(1999, 1, 1))
<ULID('00TM9HX0008S220A3PWSFVNFEH')>

根據現有的隨機數創建一個新的 ULID。

支持隨機值類型有 int,float,str,bytes,bytearray,memoryview,Randomness,和 ULID。

>>> import os, ulid
>>> randomness = os.urandom(10)
>>> ulid.from_randomness(randomness)
>>> <ULID('01BJQHX2XEDK0VN0GMYWT9JN8S')>

一旦有了 ULID 對象,就有多種與之交互的方法。

timestamp()方法將爲您提供 ULID 的前 48 位的時間戳快照,而randomness()方法將爲您提供後 80 位的隨機數快照。

>>> import ulid
>>> u = ulid.new()
>>> u
<ULID('01BJQM7SC7D5VVTG3J68ABFQ3N')>
>>> u.timestamp()
<Timestamp('01BJQM7SC7')>
>>> u.randomness()
<Randomness('D5VVTG3J68ABFQ3N')>

github:https://github.com/ahawker/ulid

版權聲明:本文爲 CSDN 博主「pushiqiang」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/pushiqiang/article/details/117365290

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/nYNVawDwtRkJUomoh2JIyA