V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
brader
V2EX  ›  程序员

除了 md5 有没有比较短的哈希算法

  •  1
     
  •   brader · 2022-08-15 18:04:58 +08:00 · 4808 次点击
    这是一个创建于 591 天前的主题,其中的信息可能已经有所发展或是发生改变。

    平时都是使用 md5 做哈希,但是有时候感觉 32 位太长了,有点浪费,想问下大家除了 md5 ,还有没有其他优秀的哈希算法?比较短的

    34 条回复    2022-08-17 04:16:40 +08:00
    mengzhuo
        1
    mengzhuo  
       2022-08-15 18:06:44 +08:00
    fnv
    InDom
        2
    InDom  
       2022-08-15 18:06:58 +08:00   ❤️ 6
    substr(md5(""), 8, 16);
    mengzhuo
        3
    mengzhuo  
       2022-08-15 18:09:01 +08:00
    ps md5 是 128 位的
    lululau
        4
    lululau  
       2022-08-15 18:10:08 +08:00   ❤️ 1
    %2
    seki
        5
    seki  
       2022-08-15 18:10:55 +08:00
    crc32 ?

    越短越容易碰撞
    brader
        6
    brader  
    OP
       2022-08-15 18:11:28 +08:00
    @mengzhuo 额,是的,可能我用的单位表述不是很专业,我想说的就是看到它的是长度为 32 的字符串形式,明白就好
    brader
        7
    brader  
    OP
       2022-08-15 18:11:59 +08:00
    @InDom 想问下截取中间的是什么依据,靠谱吗
    brader
        8
    brader  
    OP
       2022-08-15 18:12:47 +08:00
    @seki 嗯嗯,明白,短的话碰撞概率就高,但是有某些简单的场景,不需要那么高的抗碰撞率
    murmur
        9
    murmur  
       2022-08-15 18:16:21 +08:00
    crc32 ,我们是做 url 二级索引的,url 多了一级索引查的很郁闷,所以先 hash 一次然后二次查询
    ysc3839
        10
    ysc3839  
       2022-08-15 18:19:28 +08:00
    CRC32 FNV1a-32 CityHash32 等,一般一些简单用途我会选 FNV1a-32 ,因为它非常简单。
    ysc3839
        11
    ysc3839  
       2022-08-15 18:25:19 +08:00
    再补充一个 MurmurHash
    Bromine0x23
        12
    Bromine0x23  
       2022-08-15 18:38:36 +08:00
    看起来不需要防碰撞,那就 CRC
    或者 https://en.wikipedia.org/wiki/List_of_hash_functions 里面挑一个
    AX5N
        13
    AX5N  
       2022-08-15 18:53:07 +08:00
    CRC3 CRC4 CRC8 CRC16 CRC32 CRC64
    lmshl
        14
    lmshl  
       2022-08-15 18:56:24 +08:00
    substr 解君忧
    zengxs
        15
    zengxs  
       2022-08-15 19:06:40 +08:00
    md5 默认是 hex 格式输出,你可以输出成 base64 ,这样去掉占位的 = 号,就只有 22 位字符了
    hgc81538
        16
    hgc81538  
       2022-08-15 19:16:54 +08:00
    續 15 樓
    md5 編碼成 base94 ?
    hsfzxjy
        17
    hsfzxjy  
       2022-08-15 21:13:09 +08:00 via Android
    xxhash 家族
    raaaaaar
        18
    raaaaaar  
       2022-08-15 21:17:27 +08:00
    直接所有 ascill 相加成 16 进制😁
    mitu9527
        19
    mitu9527  
       2022-08-15 21:19:09 +08:00
    防碰撞哈希算法就没短的,感觉你要的是快速哈希算法,比如 Murmur 或者 CRC ,快且短,但是容易发生冲突。
    tool2d
        20
    tool2d  
       2022-08-15 21:44:01 +08:00
    把 MD5 断尾没问题,你可以自己做碰撞概率测试,每个 bit 概率是一样的。
    changnet
        21
    changnet  
       2022-08-15 21:58:15 +08:00
    非标准 base64 算法。把数字,小写字母,大写字母和一些特殊字符都用上,变成 N 进制,重新再编码这样就短了。一个 uuid 都可以编码到 22 个字符以下,只是字符看你能不能接受
    Juszoe
        22
    Juszoe  
       2022-08-15 22:15:51 +08:00
    哈希截断挺常见的,很多标准库都会有这种操作
    missdeer
        23
    missdeer  
       2022-08-15 22:19:17 +08:00 via Android
    md2 ,md4
    etnperlong
        24
    etnperlong  
       2022-08-15 22:21:51 +08:00
    可以试试 blake2/3 ?
    https://www.blake2.net/
    felixlong
        25
    felixlong  
       2022-08-15 22:22:11 +08:00
    SipHash 不是专门设计来解决你这个问题的嘛?
    kenvix
        26
    kenvix  
       2022-08-15 22:22:44 +08:00
    CRC32 ,短到你用一个 int 就能存
    CRVV
        27
    CRVV  
       2022-08-16 02:07:01 +08:00
    https://security.stackexchange.com/a/72685

    直接截前面一段就行,要多长截多长
    但是 md5 本来就是比较差的算法,再截一下就更差了,如果需要防碰撞就换个 sha256 之类的吧
    bl4ckoooooH4t
        28
    bl4ckoooooH4t  
       2022-08-16 08:48:17 +08:00
    jhash 算法。 计算字符串的哈希,得到 4 字节哈希值。https://github.com/ysmood/jhash
    bigtear
        29
    bigtear  
       2022-08-16 08:51:34 +08:00
    wyhash ,输出字符串长度 16 位,而且是目前最快且安全的算法
    bigtear
        30
    bigtear  
       2022-08-16 08:54:55 +08:00
    而且 [wyhash is the default hashing algorithm of the great great Zig, V, Nim and Go (since 1.17) language]( https://github.com/wangyi-fudan/wyhash)
    newmlp
        31
    newmlp  
       2022-08-16 12:40:30 +08:00
    xxhash
    mutalisk
        32
    mutalisk  
       2022-08-16 14:36:19 +08:00
    cityhash murmurhash
    msg7086
        33
    msg7086  
       2022-08-16 15:27:21 +08:00
    xxhash 挺好的,非密码安全的哈希,速度也快。
    t6attack
        34
    t6attack  
       2022-08-17 04:16:40 +08:00
    md5 这类散列算法,得到的字符串,其实是 16 进制数据的字符串表达。这个字符串直接占用 32 个字节,但是用来表达数据的字符却仅限 0~f 。
    如果数据量放大到亿级,这种空间浪费就很巨大了。

    如果允许以二进制方式存储数据,那么最简单粗暴的方式,是直接把散列字串当 hex 压入二进制数据。
    比如这个 md5:a6307d508e9020d93273a7c086d9735f

    字符串方式直接存储:
    肉眼观察:a6307d508e9020d93273a7c086d9735f
    实际存储:61 36 33 30 37 64 35 30 38 65 39 30 32 30 64 39 33 32 37 33 61 37 63 30 38 36 64 39 37 33 35 66
    占用空间:32 字节

    二进制方式存储:
    肉眼观察:(乱码)
    实际存储:a6 30 7d 50 8e 90 20 d9 32 73 a7 c0 86 d9 73 5f
    占用空间:16 字节  ↑↑实际存储与 md5 一致

    其他思路:
    以字符串模式存储数据的情况下,让更多字符参与表达数据,提升空间利用率,缩短数据长度.

    压入二进制以后再 base64 一下:
    肉眼观察:pjB9UI6QINkyc6fAhtlzXw==
    实际存储:70 6A 42 39 55 49 36 51 49 4E 6B 79 63 36 66 41 68 74 6C 7A 58 77 3D 3D
    占用空间:24 字节

    将 16 进制转换为 36 进制:
    肉眼观察:2izcpdgz4p6o8rmbxptszbuqn
    实际存储:32 69 7A 63 70 64 67 7A 34 70 36 6F 38 72 6D 62 78 70 74 73 7A 62 75 71 6E
    占用空间:25 字节
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5940 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 02:04 · PVG 10:04 · LAX 19:04 · JFK 22:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.