为用户生成唯一标识有什么比较简短的哈希算法吗?

2022-03-05 19:29:24 +08:00
 LeeReamond

如题,业务要求需要标记用户,目前对于未登录用户是使用 IP 和浏览器信息对用户进行唯一标识(然后再 hash 一下,变成统一长度),发现一个问题是储存比较占用空间,目前用最短的 sha1 来做,单个用户也需要 40 个字节才能储存的下来,十万个用户这种数量级的话占用内存感觉有点大了。有什么合适一些的更简短的哈希吗?比如 10 个字节或者 20 个字节就能表示的,最好使用广泛一些的,不用自己实现,我这个需求是不太在意碰撞。

谢谢大家。

2836 次点击
所在节点    问与答
27 条回复
misdake
2022-03-05 19:33:15 +08:00
那就只用 sha1 前 20 个字节?
popok
2022-03-05 19:41:09 +08:00
就 10 万规模而已,需要考虑内存占用了吗?
那你参考一楼的说法,想取几位取几位呗。
LeeReamond
2022-03-05 19:49:09 +08:00
@misdake 我不太了解哈希算法,所以来问问万能的 v 友有没有合适的,单纯截取前 20 字节的话好像,我印象里 sha1 是有通道啥的,似乎单纯截取会导致有些通道被完全弃用,感觉不太优雅所以没这么干。

@popok 也许以后更多也说不定,其实主要是想折腾一下搞个合理一点的。。
ruixue
2022-03-05 19:53:08 +08:00
Zy143L
2022-03-05 19:57:30 +08:00
Sha 中间取 16 位或者 8 位
westoy
2022-03-05 20:07:05 +08:00
第一、sha1 是 byte 20 啊, 你没必要存 hex 40 啊

第二、IP+UA 这个很明显不科学啊。 学校、网吧、普通企业都一样了, 小区宽带走 VLAN+国产浏览器重合率也蛮高的.......
xiaopc
2022-03-05 20:13:56 +08:00
@westoy 浏览器信息不止 UA ,参考下 fingerprintjs
3dwelcome
2022-03-05 20:13:59 +08:00
@westoy SHA1 是 20 个字节,我还以为自己记错了,又想了一下,应该没错。

我们对于未登录用户的识别,是先服务器请求生成一个 UUID ,然后存在浏览器本地。
victor
2022-03-05 20:55:23 +08:00
SHA1 算法得出的 SHA1 值长度为 20 个 Byte 。10 万个用户就是 200 万 Byte 。1MB = 1048576 Byte ,约 100 万 Byte 。也就是说 10 万个用户,占用了 2 MB 内存。

兄弟们我哪算错了吗?
mousewolf
2022-03-05 21:14:48 +08:00
snowflake id
LeeReamond
2022-03-05 22:05:38 +08:00
@westoy 确实有这个问题,不过还能怎么区分唯一用户呢?登录以后当然是有身份区分了,未登录的难道用网卡区分,但是网卡不在 http 信息里
3dwelcome
2022-03-05 22:13:25 +08:00
@xiaopc "浏览器信息不止 UA ,参考下 fingerprintjs"

我前一阵发过一个关于浏览器指纹的帖子。( https://browserleaks.com/canvas

测试的时候,用防指纹浏览器,每次都能给出不同的随机结果。

如果用于未登录用户识别,只会把用户数据源给污染,还不如不用。
CEBBCAT
2022-03-05 22:15:36 +08:00
见过一种做法,给游客也注册一个账号,只不过这种账号限制了权限,前台也看不到登录状态
LeeReamond
2022-03-05 22:27:21 +08:00
@CEBBCAT 感觉没啥意义,模拟存在账号的话,因为真实账号使用本质上还是依赖类似于 cookie 记录这些类似服务。


@3dwelcome 非常有趣,学习了,但是感觉区分度一般,我自己试了一下区分度是 280 个人里就有一个跟我一样的。所以使用这个 hash 加上 IP 可能是一个不错的方法。不过这个需要运行 js 才行,我想在后端获得请求的时候就区分用户。。
LeeReamond
2022-03-05 22:59:08 +08:00
@3dwelcome 我在那个网站的获取结果是

Your Fingerprint
Signature ✔9D5F1ADC
Uniqueness 99.64% (3035 of 850373 user agents have the same signature)
Image File Details
PNG Hash 193F91E186C48FF3317CBDAC67C612CC

倒是他这个 9D5F1ADC 的短 hash 非常符合我的需求
Inn0Vat10n
2022-03-05 23:51:12 +08:00
10 万*40Byte 不算大,真到大的受不了的规模也不会全放内存里
3dwelcome
2022-03-06 00:05:50 +08:00
@LeeReamond "倒是他这个 9D5F1ADC 的短 hash 非常符合我的需求"

看网站下面的说明,好像就是 MD5 截断。

以前我做过一点 hash 的每单位 bit 随机概率测试,有些算法产生的每个 bit 概率不一样,没那么散列。把 MD5 截断后,用 birthday 算法测试冲撞率,基本上没太多变化。

为了缩短空间,该砍就砍吧,这些经典算法设计的都挺好。
JamesR
2022-03-06 00:19:34 +08:00
雪花算法( Snowflake )是一种生成分布式全局唯一 ID 的算法,生成的 ID 称为 Snowflake IDs 或 snowflakes 。这种算法由 Twitter 创建,并用于推文的 ID 。
我项目用过,还行,实现简单,也比 UUID 短多了。
2NUT
2022-03-06 00:26:10 +08:00
@LeeReamond #15 太扯了,我的

Your Fingerprint
Signature ✔9D5F1ADC
Uniqueness 99.64% (3035 of 850373 user agents have the same signature)
JamesR
2022-03-06 00:26:29 +08:00
要么就 Canvas 指纹吧,也用过,还行。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/838233

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX