寻求一种短 UUID 解决方案 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
SingeeKing
10.19D

寻求一种短 UUID 解决方案

  •  
  •   SingeeKing
    PRO
    2018 年 5 月 28 日 7704 次点击
    这是一个创建于 2887 天前的主题,其中的信息可能已经有所发展或是发生改变。

    要求:

    1. 16 位以下
    2. db 范围内唯一
    3. PostgreSQL 可用

    UUID 是 32 位的,short UUID 总觉得有坑。。

    是否有什么好的实现方式?

    13 条回复    2018-06-01 17:33:15 +08:00
    Chyroc
        1
    Chyroc  
       2018 年 5 月 28 日   2
    uuid 是 16 字节,如果是 16 进制( 0-9a-f )的,会有 32 个字符,有点长;所以考虑使用 64 进制,这样的话只有 16 个字符串;

    可以参考这个文章: https://blog.chyroc.cn/articles/2017-8-2-247355155.html
    lurenw
        2
    lurenw  
       2018 年 5 月 28 日   1
    snowflake,64bit,刚好可以压缩成 16 个字符( 16 进制)
    beginor
        3
    beginor  
       2018 年 5 月 28 日 via Android
    mark,期待万能的 V 友
    lukefan
        4
    lukefan  
       2018 年 5 月 28 日   1
    mongodb 的 objectid, 12bit
    MiffyLiye
        5
    MiffyLiye  
       2018 年 5 月 28 日   1
    UUID 类型是 128 bit,即 16 byte,并不是 32 个字符。

    你如果用 MySQL 没有原生 UUID 类型的话,我还可以推荐一下
    https://www.npmjs.com/package/snowflake-codon

    PostgreSQL 原生支持 UUID 就直接用吧。
    ericls
        6
    ericls  
       2018 年 5 月 28 日 via iPhone   1
    hashids?
    fuyufjh
        7
    fuyufjh  
       2018 年 5 月 28 日   1
    snowflake +1
    changnet
        8
    changnet  
       2018 年 5 月 28 日 via Android   1
    我之前设计这个东西也想了很久。16bit 基本不可能做出来,在单一数据库里从 0 自增都不够用,算上分布式更加不够。最简单的方法就是 uuid 转 64 进制,随处可用。mongodb 的 object id 只是做集群还行。我做游戏的还要考虑合服,只能用数字,不支持 int64 这些,没有一个适用的。自己按具体需要设计一个,无非就是把时间戳,自增,业务唯一标识拼接一下,然后压缩处理,比如转 64 进制,时间戳不从 1970 算。

    网上还有些从概率上算的,认为碰撞概率小于多少便是唯一,那个确实比较短,看你的业务是不是能用
    sutra
        9
    sutra  
       2018 年 5 月 29 日   1
    曾经拿 Javascript 写了一段让它表现得更短的代码,思路也就是 #1 的用更多的字符来编码:

    通常我们用 0-F 16 个字符来编码,我这里改成了用 62 个字符来编码:

    (不过由于 Javascript 浮点数最大能表达的数字的问题,我这段代码并不是最佳的)

    // var DIGITS = "0123456789ABCDEF"
    // var DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$&'()*+/:;=?@._~"
    var DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    var BASE = DIGITS.length
    var SEPARATOR = '-'

    function encodeNumber(num) {
    var digit
    var residual = Math.floor(num)
    var result = ''

    do {
    digit = residual % BASE
    result = DIGITS.charAt(digit) + result
    residual = Math.floor(residual / BASE)
    } while (residual > 0)

    return result
    }

    function decodeNumber(str) {
    var result = 0
    var digits = str.split('')
    var e, l = digits.length
    for (e = 0; e < l; e++) {
    result = (result * BASE) + DIGITS.indexOf(digits[e])
    }
    return result
    }

    function encodeUUID(uuid) {
    var results = []
    var s = uuid.replace(/-/g, '').toUpperCase()

    var uuidInts = [
    parseInt(s.substring(0, 8), 16),
    parseInt(s.substring(8, 16), 16),
    parseInt(s.substring(16, 24), 16),
    parseInt(s.substring(24, 32), 16)
    ]

    var i, l = uuidInts.length
    for (i = 0; i < l; i++) {
    results.push(encodeNumber(uuidInts[i]))
    }

    return results.join(SEPARATOR)
    }

    function decodeUUID(str) {
    var uuidStrs = str.split(SEPARATOR)
    var i, l = uuidStrs.length
    var result = ''
    var pad = '00000000'
    var s
    for (i = 0; i < l; i++) {
    s = decodNumber(uuidStrs[i]).toString(16)
    s = pad.substring(0, pad.length - s.length) + s
    result += s
    }
    return result.replace(/([A-Za-z0-9]{8})([A-Za-z0-9]{4})([A-Za-z0-9]{4})([A-Za-z0-9]{4})([A-Za-z0-9]{12})/, "$1-$2-$3-$4-$5").toUpperCase()
    }

    module.exports = {
    encodeUUID: encodeUUID,
    decodeUUID: decodeUUID
    }
    owt5008137
        10
    owt5008137  
       2018 年 5 月 29 日 via Android   1
    https://github.com/atframework/atsf4g-co/blob/sample_solution/src/server_frame/rpc/db/uuid.cpp#L79
    一级池 id 使用数据库自增,二级自己分配的一种方法。uint64,单个 type_id 内唯一
    honeycomb
        11
    honeycomb  
       2018 年 5 月 29 日 via Android   1
    snowflake 8 字节,mongo 的 object 12 字节,udid (储存成 binary 的话) 16 字节
    sujin190
        12
    sujin190  
       2018 年 5 月 29 日   1
    snowflake 麻烦是节点位太小了,很难自动根据当前部署机器和进程信息自动生成节点 id,在自动化分布式部署的时候可能会很麻烦

    mongodb 的 bson objectid 是 12 自己,base64 编码之后就是 16 字符啊,这就好了啊
    Chyroc
        13
    Chyroc  
       2018 年 6 月 1 日
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5435 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 107ms UTC 06:52 PVG 14:52 LAX 23:52 JFK 02:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86