2010-04-08 56 views
10

我在appengine的python上工作。在python中爲url參數生成固定長度的散列

我想創造什麼是等同於「V」值YouTube網址的(http://www.youtube.com/watch?v=XhMN0wlITLk)用於檢索特定實體。數據存儲自動生成一個密鑰,但它太長(34位數字)。我已經嘗試用hashlib來建立我自己的,但是我又得到了一個很長的字符串。我想保留在11位以下(我沒有處理大量的實體),字母和數字是可以接受的。

看來應該有一個非常標準的解決方案。我可能只是想念它。

回答

8

您可以使用密鑰的自動生成的integer id來生成散列。生成散列的簡單方法是將整數ID轉換爲base62(字母數字)。要獲取對象,只需從base62轉換回十進制,並使用get_by_id來檢索對象。

這是一個簡單的base62轉換函數,我用在我的一個應用程序中。

import string 
alphabet = string.letters + string.digits 
max = 11 

def int_to_base62(num): 
    if num == 0: 
     return alphabet[0] 

    arr = [] 
    radix = len(alphabet) 
    while num: 
     arr.append(alphabet[num%radix]) 
     num /= radix 
    arr.reverse() 
    return (alphabet[0] * (max - len(arr))) + ''.join(arr) 

def base62_to_int(str): 
    radix = len(alphabet) 
    power = len(str) - 1 
    num = 0 
    for char in str: 
     num += alphabet.index(char) * (radix ** power) 
     power -= 1 
    return num 
+0

這兩個鏈接非常有幫助。現在的問題是找到base62編碼和解碼的理想方式。我已經做了一些閱讀,有沒有你建議的方法? – LeRoy 2010-04-08 17:18:19

+1

您可以使用基本的數字庫轉換技術。爲了使哈希固定長度,只需在base62編號中添加零填充即可。 – z33m 2010-04-09 01:33:39

5

如果您對每個實體都有唯一的值,則可以通過對其進行散列和截斷來獲得更短的版本。像md5或sha1這樣的散列混合良好,這意味着如果在輸入中更改一位,則輸出中的每一位都有50%的翻轉概率。如果截斷哈希值,則只是增加碰撞機率,但可以在長度和碰撞機率之間進行權衡。

Url-safe base64編碼是將散列轉換爲文本的好選擇。

orig_id = 'weiowoeiwoeciw0eijw0eij029j20d232weifw0jiw0e20d2' # the original id 
shorter_id = base64.urlsafe_b64encode(hashlib.md5(orig_id).digest())[:11] 

使用Base64,你必須的每個字符信息的6位,11個字符給你的獨特的66個比特,或1 2 ** 66偶然碰撞。

+0

是否有一個原因,你會選擇Base64轉換超過base62像上面提出的建議? – LeRoy 2010-04-08 17:20:07

+0

Base64似乎總是包含一個「=」,這不是真正的查詢字符串安全。 – LeRoy 2010-04-08 17:43:58

+0

我在base62上使用base64只是因爲它比較熟悉。 =是填充。無論如何你都在截斷,對吧? – 2010-04-08 19:29:54

相關問題