2014-10-28 101 views
0

我想爲數據庫記錄使用UUID,但如果我使用它作爲URL,我希望它是5到8個字符。如何縮短UUID到特定長度?

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

回答

2

您無法縮短UUID。

Wikipedia

甲UUID是16個八位字節(128位)數。

以其規範形式,UUID由32個小寫十六進制數字表示。

如果你縮短了它,它不會再是UUID。

創建較短的URL有多種技術。只需搜索「網址縮寫器」即可找到任何數量的寶石。

+0

謝謝兩位單行功能。數據庫中的URL縮短器會被識別出來嗎? – asaignment 2014-10-28 18:49:30

+0

URL縮短的一種技術是將標識符與數據記錄一起存儲在數據庫中。您是否應該使用此方法取決於您擁有的數據記錄類型和/或您想要的URL類型。如果你正在尋找SEO(搜索引擎優化),你的網址應該包含有意義的文本,比如'example.com/path/to/my-shortened-url',你需要一種將縮短的URL標識符映射到數據記錄。 – 2014-10-28 19:22:50

6

正如另一個答案所指出的那樣,您無法獲得真實的UUID,但可以縮短它們的一部分。 UUID是128位整數,可用於32位十六進制數字。您可以輕鬆地存儲每個字符6位,並將長度降至22個字符,這就是base 64編碼的含義。標準的base 64編碼使用大寫和小寫字母,數字和「+」和「/」來完成它。如果你用「 - 」和「_」替換「+」和「/」,你最終會得到一個不需要url編碼的字符串。你可以像下面這樣做(用UUIDTools創建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會議:

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作爲表的主鍵,並通過他們的IDS各種網站這種方法。它不會節省很多空間,但它確實使一些URL適合一個80字符的行,其中標準格式的完整UUID不會。使用破折號,標準的UUID是36個字符,因此22是約2/3的大小。

0

我創建了一個基於邁克爾·查尼

def encode(uuid)  
    [uuid.tr('-', '').scan(/../).map(&:hex).pack('c*')].pack('m*').tr('+/', '-_').slice(0..21)             
end 
def decode(short_id) 
(short_id.tr('-_', '+/') + '==').unpack('m0').first.unpack('H8H4H4H4H12').join('-')                                                               
end 

uuid = "355bf501-ffea-4f5a-a9e2-16074de6fcf2"                                                        
=> "355bf501-ffea-4f5a-a9e2-16074de6fcf2"                                           
encode(uuid)  
=> "NVv1Af_qT1qp4hYHTeb88g"   
decode(_)   
=> "355bf501-ffea-4f5a-a9e2-16074de6fcf2