如何缩短UUID?

6
在一个项目中,我需要处理v4格式的UUID,例如:
931d4657-2e07-477f-be0c-5dd02906a516

基本上,它们都没什么问题,只是手动输入它们太长了。因此,我正在考虑缩短它们的方法-但不能失去返回原始UUID的能力。因此,仅考虑前n个字节不是一个选项 ;-)
我的第一个想法是将其表示为Unicode字符,而不是十六进制代码,但这会导致非可打印(和非可键入)字符。因此,这也不是一个选项。
然后我想到了Base64(Base58等)编码,但它们并没有真正使事情变得更短(我没有特定的目标长度,我只想让它少一些字符,并且节省2个字符不是我的意思;-))。
有没有聪明的技巧可以做到这一点,同时保持返回UUID的选项?有人有想法吗?

1
"它们太长了,手动输入会很麻烦。" - 这是指您将GUID呈现给用户吗?如果是的话,那么您可能不应该这样做! - Mitch Wheat
1
不是的。它们在管理界面中显示,代表用户(UUID 是用户 ID,也是我们唯一可以依赖的东西)。因此,重点是让管理员的工作变得更轻松一些。 - Golo Roden
2个回答

2

UUID是128位(16字节)长的。如果您删除版本和变体,可能会有一些可以移除的位; 但我认为在您的情况下这不是一个选项(而且您只能安全地删除6个位,请参见此处)。

使用base64编码将减少约40%。

# example uses Ruby
SecureRandom.base64(16) # => UBm-_zkz20ka6dOAA8dkMg
SecureRandom.uuid       # => 3754e815-87fe-4872-8d9b-ae529607c277

在您的评论中,您写道这是用于您的用户的标识符。因此,您可以在您的UI中使用缩短版本,就像git处理短SHA一样。这取决于您要处理的实体数量,但您应该能够大大减少“处理”,并仍然具有非常低的碰撞可能性。如果发生碰撞,则可以要求用户提供更多的标识符。

2

UUID是128位数字;十六进制形式只是人类使用的表示方式,每个字符只有3.55位密度。去掉破折号后,每个字符变成4位。

使用base64代替base16,你会得到每个字符6位,共22位。这是你能做到并保持可读性的最好结果。实际上,你可以接近每个字节7位,这将再减少1-2个字节,但这会增加更多的复杂性(即风险),而这种小的收益无法证明其合理性。

从数学上讲,这已经是你能走的最远的路了,并且仍然能够进行往返转换。如果你还需要更短的长度,那么你必须放弃这一点——这可能对你的整体设计产生其他影响。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接