如何将 UUID 缩短为特定长度? [英] How can I shorten a UUID to a specific length?

查看:113
本文介绍了如何将 UUID 缩短为特定长度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将 UUID 用于数据库记录,但如果我将它用于 URL,我希望它是 5 到 8 个字符.

I'd like to use a UUID for database records but if I'm using it for the URL I'd like it to be 5 to 8 characters.

我知道我需要使用 SecureRandombase64,但是如何指定我需要的长度?

I know I need to use SecureRandom and base64, but how do I specify the length I need?

推荐答案

正如另一个答案指出的那样,您无法将真正的 UUID 减少到 5-8 个字符,但您可以稍微缩短它们.UUID 是 128 位整数,可计算为 32 位十六进制数字.您可以轻松地为每个字符存储 6 位并将长度减少到 22 个字符,这就是 base 64 编码.标准的 base 64 编码使用大小写字母、数字以及+"和/"来完成.如果你用-"和_"替换+"和/",你最终会得到一个不需要url编码的字符串.您可以这样做(使用 UUIDTools 创建 UUID):

You can't get a real UUID down to 5-8 characters, as another answer points out, but you can shorten them somewhat. UUIDs are 128-bit integers which works out to 32 hex digits. You can easily store 6 bits per character and cut the length down to 22 characters, which is what base 64 encoding is. Standard base 64 encoding uses upper and lower case letters, digits, and "+" and "/" to finish it out. If you replace "+" and "/" with "-" and "_" you will end up with a string that doesn't have to be url encoded. You can do it like this (using UUIDTools to create the UUID):

uuid = UUIDTools::UUID.random_create
str = [uuid.raw].pack('m*').tr('+/','-_').slice(0..21)

要收回您的价值:

(str + "==\n").tr('-_','+/').unpack('m*').first if str =~ /^[a-zA-Z0-9_\-]{22}$/

假设 UUID 可以放入原始格式,其中它是 16 个 8 位字符的字符串.这是一个展示真实示例的 irb 会话:

That's assuming the UUID can be put into a raw format where it's a string of 16 8-bit characters. Here's an irb session showing a real example:

2.1.1 :016 > uuid=UUIDTools::UUID.random_create
 => #<UUID:0x83f1e98c UUID:20d07b6c-52af-4e53-afea-6b3ad0d0c627> 
2.1.1 :017 > uuid.raw
 => " \xD0{lR\xAFNS\xAF\xEAk:\xD0\xD0\xC6'" 
2.1.1 :018 > str = [uuid.raw].pack('m*').tr('+/','-_').slice(0..21)
 => "INB7bFKvTlOv6ms60NDGJw" 
2.1.1 :019 > uuid2 =  (str + "==\n").tr('-_','+/').unpack('m*').first
 => " \xD0{lR\xAFNS\xAF\xEAk:\xD0\xD0\xC6'" 
2.1.1 :022 > UUIDTools::UUID.parse_raw(uuid2)
 => #<UUID:0x849e6b44 UUID:20d07b6c-52af-4e53-afea-6b3ad0d0c627> 

我在各种网站上使用这种方法,在这些网站上我通常使用 Postgres 生成 UUID 作为表的主键并将它们作为 id 传递.它不会节省很多空间,但它确实使一些 URL 适合一个 80 个字符的行,而标准格式的完整 UUID 则不能.对于破折号,标准的 UUID 是 36 个字符,因此 22 大约是大小的 2/3.

I use this method on various web sites where I typically use Postgres to generate UUIDs as primary keys for tables and pass them as ids. It doesn't save a lot of space but it does make some URLs fit on one 80 character line where a full UUID in standard format wouldn't. With dashes, a standard UUID is 36 characters so 22 is about 2/3 the size.

这篇关于如何将 UUID 缩短为特定长度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆