2011-01-19 4 views
2

Je suis désolé pour la question générique (je n'ai aucune connaissance sur la compression et je ne sais pas si elle a une solution possible).Python: Chaîne de code à chaîne plus courte sans signification de manière réversible

J'ai quelques codes de toujours 19 caractères.

Ces caractères peuvent être seulement: A-Z, a-z, 0-9, ., :, -

Un exemple peut être quelque chose comme 1995AbC...123..456Z

Ce que je veux faire est de trouver un moyen de convertir en un manière réversible que la chaîne à une chaîne plus courte qui ne contient que des caractères ascii: quelque chose comme gfSDd2H.

  • Est-ce possible?
  • Existe-t-il un moyen de le faire en python?

Merci!

+1

Y a-t-il une signification de niveau supérieur aux données? Une concaténation de différents domaines peut-être plus structurée? Quelle est votre motivation pour vouloir/avoir besoin de compression? –

+0

Oui, ce code est un Bibcode (http://en.wikipedia.org/wiki/Bibcode) et la raison pour laquelle je veux le compresser est que j'ai des problèmes avec les URL contenant ce code. –

Répondre

5

Vous pouvez essayer de compresser la chaîne et d'encoder le résultat par exemple en base64. Cela suppose bien sûr que vos cordes d'origine sont compressibles. Pour les chaînes de 19 caractères, cela semble improbable. Si vous êtes autorisé à conserver certaines données, vous pouvez compresser la première chaîne à 1, la seconde à 2, etc ... et vous devrez stocker le mappage que vous avez fait dans par exemple une base de données afin que vous puissiez inverser il. Vous pouvez ensuite encoder le nombre en tant que chaîne de base 64 (ou une autre base).

Ceci est similaire au fonctionnement des services de raccourcissement d'URL.

4

Vous autorisez 65 caractères différents. En supposant que toutes les entrées ont la même probabilité, chaque codage produirait pas moins de 19 * 65/128 ≈ 10 caractères. Cependant, puisque vous voulez probablement ignorer les caractères non imprimables, ceci est réduit à 19 * 65/95 = 13 caractères avec un mapping parfait. Par conséquent, une telle cartographie ne conduira pas à une réduction significative de l'espace.

+0

Vous souhaitez probablement exclure également le caractère espace; ce serait jack la taille de 14. –

2

Bien sûr (?) C'est possible en Python. Tout ce que vous feriez, c'est de convertir un numéro de base 65 en un numéro de base 95 ou de base 94, et vice versa. Il est juste que ce serait un peu lent, et comme l'a souligné dans une autre réponse, vous ne seriez pas économiser beaucoup d'espace

Ici (non testé) sont les éléments de base:

def ttoi(text, base, letter_values): 
    """converts a base-"base" string to an int""" 
    n = 0 
    for c in text: 
     n = n * base + letter_values[c] 
    return n 

def itot(number, base, alphabet, padsize): 
    """converts an int into a base-"base" string 
     The result is left-padded to "padsize" using the zero-value character""" 
    temp = [] 
    assert number >= 0 
    while number: 
     number, digit = divmod(number, base) 
     temp.append(alphabet[digit]) 
    return max(0, padsize - len(temp)) * alphabet[0] + "".join(reversed(temp)) 

Définitions pour exemple votre code base-65 existant:

b65_letter_values = { 
    'A': 0, 'Z': 25, 'a': 26, 'z': 51, '0': 52, '9': 61, 
    # etc 
    } 
b65_alphabet = "ABCetcXYZabcetcxyz.:-" 
b65_padsize = 19 
Questions connexes