six_001
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
||||
class SnowflakeIDGenerator:
|
||||
# 目标:总比特数约40位,十进制最多12位(2^40 ≈ 1.1e12)
|
||||
# 时间戳用28位(可覆盖约8.5年),机器ID用6位(64台),序列号用6位(每毫秒64个)
|
||||
TIMESTAMP_BITS = 28
|
||||
WORKER_ID_BITS = 6
|
||||
SEQUENCE_BITS = 6
|
||||
|
||||
# 起始时间戳(2025-01-01 00:00:00 UTC),单位毫秒
|
||||
CUSTOM_EPOCH = 1735689600000
|
||||
|
||||
MAX_WORKER_ID = -1 ^ (-1 << WORKER_ID_BITS)
|
||||
MAX_SEQUENCE = -1 ^ (-1 << SEQUENCE_BITS)
|
||||
|
||||
# 移位计算
|
||||
WORKER_ID_SHIFT = SEQUENCE_BITS
|
||||
TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS
|
||||
|
||||
def __init__(self, worker_id, sequence=0):
|
||||
if worker_id > self.MAX_WORKER_ID or worker_id < 0:
|
||||
raise ValueError(f"Worker ID must be between 0 and {self.MAX_WORKER_ID}")
|
||||
self.worker_id = worker_id
|
||||
self.sequence = sequence
|
||||
self.last_timestamp = -1
|
||||
self.lock = threading.Lock()
|
||||
|
||||
def _wait_next_ms(self, last_ts):
|
||||
ts = self._now()
|
||||
while ts <= last_ts:
|
||||
ts = self._now()
|
||||
return ts
|
||||
|
||||
def _now(self):
|
||||
return int(time.time() * 1000)
|
||||
|
||||
def generate_id(self):
|
||||
with self.lock:
|
||||
ts = self._now()
|
||||
if ts < self.last_timestamp:
|
||||
raise Exception("Clock moved backwards")
|
||||
if ts == self.last_timestamp:
|
||||
self.sequence = (self.sequence + 1) & self.MAX_SEQUENCE
|
||||
if self.sequence == 0:
|
||||
ts = self._wait_next_ms(self.last_timestamp)
|
||||
else:
|
||||
self.sequence = 0
|
||||
self.last_timestamp = ts
|
||||
|
||||
# 相对时间(毫秒),只取低TIMESTAMP_BITS位
|
||||
relative_ts = (ts - self.CUSTOM_EPOCH) & ((1 << self.TIMESTAMP_BITS) - 1)
|
||||
new_id = (relative_ts << self.TIMESTAMP_SHIFT) | \
|
||||
(self.worker_id << self.WORKER_ID_SHIFT) | \
|
||||
self.sequence
|
||||
return new_id
|
||||
|
||||
def generate_str(self):
|
||||
return str(self.generate_id())
|
||||
|
||||
|
||||
# 全局生成器实例 (worker_id和datacenter_id需在分布式环境中保证唯一)
|
||||
# 单机开发环境可暂时固定,生产环境建议通过配置中心或启动参数传入
|
||||
generator = SnowflakeIDGenerator(worker_id=1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(generator.generate_id())
|
||||
print(type(generator.generate_id()))
|
||||
print(generator.generate_str())
|
||||
Reference in New Issue
Block a user