2010-04-08 2 views
10

Je travaille en python sur appengine.Générer un hachage de longueur fixe en python pour le paramètre url

Je suis en train de créer ce qui est équivalent à la valeur « v » dans l'url de youtube (http://www.youtube.com/watch?v=XhMN0wlITLk) pour récupérer des entités spécifiques. Le magasin de données génère automatiquement une clé mais il est beaucoup trop long (34 chiffres). J'ai expérimenté avec hashlib pour construire le mien, mais encore une fois je reçois une longue chaîne. Je voudrais le garder à moins de 11 chiffres (je ne traite pas d'un grand nombre d'entités) et les lettres et les chiffres sont acceptables.

Il semble qu'il devrait y avoir une solution assez standard. Je suis probablement juste le manque.

Répondre

8

Vous pouvez utiliser la clé integer id générée automatiquement pour générer le hachage. Un moyen simple de générer le hachage serait de convertir l'identifiant entier en base62 (alphanumérique). Pour récupérer l'objet, convertissez simplement en décimal à partir de base62 et utilisez get_by_id pour récupérer l'objet.

Voici une simple fonction de conversion base62 que j'ai utilisée dans l'une de mes applications.

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

Ces deux liens ont été très utiles. Le problème maintenant est de trouver le moyen idéal pour encoder et décoder en base62. J'ai fait quelques lectures, y a-t-il une méthode que vous suggérez? – LeRoy

+1

vous pouvez utiliser des techniques de base de conversion de base de nombre. Pour faire la longueur de hachage, ajoutez juste un peu de remplissage au nombre base62. – z33m

5

Si vous avez une valeur unique pour chaque entité, vous pouvez obtenir une version plus courte en la hachant et en la tronquant. Les hachages comme md5 ou sha1 sont bien mélangés, ce qui signifie que chaque bit de la sortie a 50% de chance de basculer si vous changez un bit dans l'entrée. Si vous tronquez le hachage, vous augmentez simplement les chances d'une collision, mais vous pouvez faire le compromis entre la longueur et les chances de collision.

L'encodage base64 sécurisé Url est une bonne option pour convertir le hachage en texte.

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

Avec base64, vous avez 6 bits d'information par caractère, 11 caractères vous donne 66 bits d'unicité, ou un 1 2 ** 66 risque de collision.

+0

Y at-il une raison pour laquelle vous choisiriez la conversion base64 sur base62 comme ce qui est suggéré ci-dessus? – LeRoy

+0

Base64 semble toujours inclure un "=" qui n'est pas vraiment sûr de Querystring. – LeRoy

+0

J'utilise base64 sur base62 juste parce que c'est plus familier. Le = est un remplissage. Vous êtes de toute façon tronqué, n'est-ce pas? –

Questions connexes