当前位置: 首页 > news >正文

UUIDv1秒变v6的位运算魔法:uuid-creator TimeOrderedCodec源码剖析

UUIDv1秒变v6的位运算魔法:uuid-creator TimeOrderedCodec源码剖析

【免费下载链接】uuid-creatorUUID Creator is a Java library for generating Universally Unique Identifiers. It generates all standard identifiers from UUIDv1 to UUIDv7. It also provides an alternative to the classic JDK's UUID (alt.GUID), many codecs (codec.*) and several utilities (util.*).项目地址: https://gitcode.com/gh_mirrors/uu/uuid-creator

uuid-creator 是一个开源 Java 库,可生成 UUIDv1 到 UUIDv7 全部标准标识符。本文带你剖析它的 TimeOrderedCodec 源码——仅凭几行位运算,就能把老式 UUIDv1 秒变时间可排序的 UUIDv6,无需任何字符串拼接或第三方依赖。

为什么要把 UUIDv1 转成 UUIDv6?

先搞清楚痛点。UUIDv1 的时间戳被"打散"存放在三个互不相邻的字段里(time_low、time_mid、time_high),导致按字符串排序时,先后生成的 ID 在字典序上是乱序的

这对数据库很不友好:

  • B+ 树写入碎片化:主键随机散落,页分裂频繁,写入性能差
  • 范围查询低效:想按时间取"最近 100 条",索引帮不上忙
  • 缓存命中率低:新记录无法追加在索引末尾

而 UUIDv6 的魔法在于:把 60 位时间戳重排成一个连续的大端整数,字符串字典序 ≈ 时间先后序。这正是 TimeOrderedCodec 要完成的唯一任务。

核心原理:v1 与 v6 的位布局对比

UUID 的 128 位分为高 64 位(msb)和低 64 位(lsb)。TimeOrderedCodec 只动 msb,lsb(时钟序列 + 48 位节点 ID)原样保留:

位段(msb 64位)UUIDv1 布局UUIDv6 布局
bit 63~48time_high(12位)time_high(12位)
bit 47~32time_mid(16位)time_mid(16位)
bit 31~16time_low(16位)time_mid 续… version + time_low 高位
bit 15~12version = 0001version = 0110
bit 11~0time_low 低12位… time_high 高位time_low 低12位

一句话总结转换逻辑:

v1 → v6:把打散的时间戳重新拼成连续整数,版本号从 1 改成 6。v6 → v1:原路拆散回三个字段,版本号改回 1。

源码剖析:3 个十六进制常数就是全部魔法

源码文件位于src/main/java/com/github/f4b6a3/uuid/codec/other/TimeOrderedCodec.java,整个类不到 100 行。

正向转换:v1 秒变 v6

encode方法的核心只有 4 行(约第 62~70 行):

long timestamp = UuidUtil.getTimestamp(uuid); long msb = ((timestamp & 0x0ffffffffffff000L) << 4) // | (timestamp & 0x0000000000000fffL) // | 0x0000000000006000L; // set version 6 long lsb = uuid.getLeastSignificantBits(); return new UUID(msb, lsb);

逐行拆解这 3 个"魔数":

  1. timestamp & 0x0ffffffffffff000L—— 取 60 位时间戳的高 52 位(砍掉最低 12 位)
  2. << 4—— 整体左移 4 位,把版本号的 4 个"坑位"腾出来
  3. | (timestamp & 0xfff)—— 把刚才砍掉的低 12 位补到最末尾
  4. | 0x6000—— 在 bit 15~12 写入0110,宣告"我是 UUIDv6"

妙处在于:左移 + 低位补回,等于把 60 位时间戳无损地"折叠"成一个大端排列——高位在前、低位在后,字典序排序即时间排序。全程没有任何循环和字符串操作,纯位运算,纳秒级完成。

注意时间戳不是直接读出来的,而是委托给src/main/java/com/github/f4b6a3/uuid/util/UuidUtil.java中的getTimestamp()(约第 272 行),它会按 UUID 版本选择正确的拆位策略。

反向转换:v6 还原 v1

decode方法(约第 81~102 行)就是把"折叠"的动作原样展开:

long timeHigh = (timestamp & 0x0fff_0000_00000000L) >>> 48; // 拆出 12 位高位 long timeMid = (timestamp & 0x0000_ffff_00000000L) >>> 16; // 拆出 16 位中段 long timeLow = (timestamp & 0x0000_0000_ffffffffL) << 32; // 拆出 32 位低位 long version = 0x0000000000001000L; // Set version 1

每个"掩码 + 移位"组合,把 v6 连续时间戳中对应的字段搬回 v1 的原始位置,最后或上0x1000把版本号改回 1。由于 encode/decode 是严格互逆的,往返转换零信息损失。

动手实践:一行代码完成转换

// v1 → v6 UUID uuid1 = UuidCreator.getTimeBased(); UUID uuid6 = new TimeOrderedCodec().encode(uuid1); // v6 → v1(可无限往返) UUID back = new TimeOrderedCodec().decode(uuid6);

类中还提供了单例TimeOrderedCodec.INSTANCE,生产环境推荐复用它避免重复 new。如果不想手动转换,也可以直接用门面 APIUuidCreator.getTimeOrdered()一步生成 v6(底层工厂在src/main/java/com/github/f4b6a3/uuid/factory/standard/TimeOrderedFactory.java)。

测试怎么保证正确?

配套的src/test/java/com/github/f4b6a3/uuid/codec/other/TimeOrderedCodecTest.java用 100 次循环做了三重断言:

测试点验证目标
isTimeOrdered(uuid6)产物确实是合法的 v6
时间戳相等转换不丢时间精度
decode(encode(v1)) == v1往返转换完全可逆

总结

  • TimeOrderedCodec 用3 个掩码 + 移位 + 或运算完成了 v1 与 v6 的互转,是位运算在 ID 设计中的教科书级应用
  • 核心收益:ID 天然按时间有序,显著提升 B+ 树数据库的写入与范围查询性能
  • 源码仅 ~100 行且依赖极简,非常适合通读学习——建议结合UuidUtilgetTimestamp一起看

掌握这 4 行核心代码后,你甚至可以在任何语言里复现这套"时间有序化"技巧。

【免费下载链接】uuid-creatorUUID Creator is a Java library for generating Universally Unique Identifiers. It generates all standard identifiers from UUIDv1 to UUIDv7. It also provides an alternative to the classic JDK's UUID (alt.GUID), many codecs (codec.*) and several utilities (util.*).项目地址: https://gitcode.com/gh_mirrors/uu/uuid-creator

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.cnnetsun.cn/news/4247756.html

相关文章:

  • 极简语言编年史:milliForth、sectorForth 与 sectorLISP 深度对比
  • 大模型应用开发全流程:从初始构思到实验、效果评估和产品化!
  • C语言内存管理
  • 多传感器模块设计指南:从选型到固件的可穿戴实践
  • 什么是Transformer?什么是视觉Transformer?与CNN的比较谁更胜一筹?
  • 【AI大模型】一文讲透 AI Agent 与 AI Workflow 的区别和深度解析:从自动化到智能化的演进
  • 2026北京GEO优化服务商推荐:企业出海如何同步布局AI搜索品牌资产
  • AI Agent工具调用安全加固:Pyshackle预执行门控实战
  • YOLO手语识别实战:开箱即用数据集与模型训练全流程
  • Qwen 2.5 Max与DeepSeek R1测试对比,看到就是赚到!!
  • 基于LoRA的Qwen-VL视觉语言模型指令微调实战指南
  • 商业园林机器人:智能运维才是核心,而非割草本身
  • AgentX与InferenceX:智能体推理基准如何评估多步推理与工具调用
  • 最新盘点:五大厂开源GitHub项目,开发者不容错过的技术宝藏!
  • RAG技术完全指南:从零开始构建大模型知识库问答系统!大模型应用开发实战
  • 2024 人工智能最前沿:分享几个大模型(LLMs)的热门研究方向
  • i.MX6ULZ无头嵌入式计算方案:DART模块开发实践
  • 2026年UI/UX设计界震撼!AI工具崛起,传统设计岗位需求锐减30%,AI体验设计师薪资却飙升50%!
  • GPT-4+GraphRAG:知识图谱如何让RAG系统更智能?
  • 为什么现在大家都把Agent叫“智能体“呢?
  • 【AI大模型】RAG(检索增强生成)新探索:IdentityRAG 提高 RAG 准确性
  • DeepSeek-OCR 2 使用教程
  • MCU方案通过Alexa语音认证:架构拆解与量产实践指南
  • 树莓派3B即插即用替代方案:RK3566 SBC实测迁移指南
  • 2026年开始学习AI,是否为时已晚?揭秘为何30+人群在AI领域更具竞争力
  • 从互联网大厂到传统行业,AI产品经理的黄金时代
  • ensp-VAR基本操作
  • C盘突然爆满?11个超实用清理技巧,轻松释放50GB+空间(Windows终极指南)
  • 一文搞懂大模型:从Transformer到智能体,无技术门槛也能学会
  • 零训练开放词汇分割:Perceptual Anchoring原理与PyTorch实现