You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于两个64位ID生成唯一且无序的较短ID?

如何基于两个64位唯一ID生成短且无序的唯一ID?

我有两个唯一的64位ID:

ID1 = 677313095844233279 
ID2 = 863850283313922058

需要基于这两个ID生成第三个唯一ID,核心要求是**(ID1, ID2)与(ID2, ID1)生成的ID完全一致**。我尝试了两种方法,但都有问题:

  1. 比特位合并法:

    >>> (ID1 << 64) | ID2 
    
    12494221336810479773180694257709350922
    

    生成的数值过长,且交换ID顺序后结果完全不同,不满足无序性要求。

  2. frozenset哈希法:

    >>> hash(frozenset({ID1, ID2})) 
    
    -4995465307261022717
    

    数值长度合适,但不清楚底层逻辑,想知道生成这类ID的最优算法是什么?


最优方案推荐

核心需求拆解:无序性(输入顺序不影响结果)、唯一性(不同ID对对应不同结果)、短长度(优先64位整数)。以下是不同场景下的最优选择:

1. 最简实现(非跨环境场景)

先对两个ID排序,再用Python内置哈希处理排序后的元组:

def get_unordered_id(a, b):
    sorted_ids = tuple(sorted((a, b)))
    return hash(sorted_ids)
  • 逻辑清晰:排序保证输入顺序不影响结果,元组哈希是Python内置的稳定实现(同进程内)。
  • 结果长度:64位整数,满足“短”的要求。

2. 跨环境稳定实现(低碰撞概率)

如果需要不同Python版本/进程下结果一致,用加密哈希函数处理排序后的ID对,截断为64位整数:

import hashlib

def get_unordered_id(a, b):
    if a > b:
        a, b = b, a
    # 将ID转为字符串拼接后哈希,取前8字节转为64位无符号整数
    input_str = f"{a}:{b}".encode('utf-8')
    hash_digest = hashlib.sha256(input_str).digest()
    return int.from_bytes(hash_digest[:8], byteorder='big', signed=False)
  • 稳定性:SHA-256是标准加密哈希,跨环境结果完全一致。
  • 碰撞概率:SHA-256的碰撞概率极低,对于大部分业务场景可以忽略。
  • 结果长度:64位无符号整数,数值范围在0~1.8e19之间,长度适中。

3. 绝对无碰撞实现(超高唯一性要求)

如果完全不能接受哈希碰撞的风险,排序后合并为128位整数:

def get_unordered_id(a, b):
    min_id, max_id = min(a, b), max(a, b)
    return (min_id << 64) | max_id
  • 绝对唯一:每个不同的ID对对应唯一的128位整数,无任何碰撞可能。
  • 缺点:数值长度为128位,比64位长,但在支持大整数的语言(如Python)中完全可以处理。

关于frozenset哈希的底层说明

你使用的hash(frozenset({ID1, ID2})),其底层逻辑是:集合的哈希值通过遍历所有元素,将当前哈希值与元素哈希值进行异或、移位等组合运算得到。因为集合是无序的,元素遍历顺序不影响最终结果,所以天然满足无序性要求。

但这种方法的问题是非确定性:Python启动时会给内置哈希函数添加随机盐,同一个frozenset在不同进程或Python版本下的哈希值可能不同,不适合需要跨环境一致的场景。


内容的提问来源于stack exchange,提问作者BENJAMIN GILBERT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 23:27:20