2012-04-26 8 views
7

Domanda veloce. Sto cercando di trovare o scrivere un codificatore in Python per abbreviare una stringa di numeri usando lettere maiuscole e minuscole. Le stringhe numeriche assomigliano a questa:Codifica di una stringa numerica in una stringa alfanumerica abbreviata e di nuovo indietro

20120425161608678259146181504021022591461815040210220120425161608667 

La lunghezza è sempre la stessa.

Il mio primo pensiero è stato quello di scrivere qualche semplice codificatore di utilizzare lettere e numeri maiuscole e minuscole per accorciare questa stringa in qualcosa che assomiglia di più a questo:

a26Dkd38JK 

Questo è stato del tutto arbitrario, solo cercando di essere il più chiaro possibile. Sono certo che c'è un modo davvero brillante per farlo, probabilmente già integrato. Forse questa è una domanda imbarazzante che potrebbe anche essere fatta.

Inoltre, ho bisogno di essere in grado di prendere la stringa abbreviata e convertirla di nuovo nel valore numerico più lungo. Devo scrivere qualcosa e postare il codice, oppure è una linea costruita in funzione di Python di cui dovrei già essere a conoscenza?

Grazie!

+4

[base64] (http://docs.python.org/library/base64.html) – JBernardo

+0

JBernardo- inchiodato. Pubblicalo come risposta :) !! –

+0

È una buona cosa che stai offrendo di scrivere il codice te stesso e pubblicarlo qui. – Julian

risposta

10

Questa è una buona compressione:

import base64 

def num_to_alpha(num): 
    num = hex(num)[2:].rstrip("L") 

    if len(num) % 2: 
     num = "0" + num 

    return base64.b64encode(num.decode('hex')) 

Si scopre prima il numero intero in un bytestring e poi base64 codifica. Ecco il decoder:

def alpha_to_num(alpha): 
    num_bytes = base64.b64decode(alpha) 
    return int(num_bytes.encode('hex'), 16) 

Esempio:

>>> num_to_alpha(20120425161608678259146181504021022591461815040210220120425161608667) 
'vw4LUVm4Ea3fMnoTkHzNOlP6Z7eUAkHNdZjN2w==' 
>>> alpha_to_num('vw4LUVm4Ea3fMnoTkHzNOlP6Z7eUAkHNdZjN2w==') 
20120425161608678259146181504021022591461815040210220120425161608667 
+0

+1.Nota che questo prende un int, non una stringa –

+0

Sembra che funzioni alla grande. Esattamente quello che stavo cercando, grazie. RE: int vs. string: il passaggio di una stringa a questa funzione in realtà non funziona. Deve essere un int. Buon lavoro! –

+0

Ciò richiede numeri interi arbitrari di precisione, che fortunatamente ha Python. – ninjagecko

0
>>> s="20120425161608678259146181504021022591461815040210220120425161608667" 
>>> import base64, zlib 
>>> base64.b64encode(zlib.compress(s)) 
'eJxly8ENACAMA7GVclGblv0X4434WrKFVW5CtJl1HyosrZKRf3hL5gLVZA2b' 
>>> zlib.decompress(base64.b64decode(_)) 
'20120425161608678259146181504021022591461815040210220120425161608667' 

quindi zlib non è reale intelligente a comprimere stringhe di cifre :(

6

ci sono due funzioni che sono personalizzati (non basato su base64), ma produce una produzione più corta:

chrs = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 
l = len(chrs) 

def int_to_cust(i): 
    result = '' 
    while i: 
     result = chrs[i % l] + result 
     i = i // l 
    if not result: 
     result = chrs[0] 
    return result 

def cust_to_int(s): 
    result = 0 
    for char in s: 
     result = result * l + chrs.find(char) 
    return result 

E i risultati sono:

>>> int_to_cust(20120425161608678259146181504021022591461815040210220120425161608667) 
'9F9mFGkji7k6QFRACqLwuonnoj9SqPrs3G3fRx' 
>>> cust_to_int('9F9mFGkji7k6QFRACqLwuonnoj9SqPrs3G3fRx') 
20120425161608678259146181504021022591461815040210220120425161608667L 

È possibile anche ridurre la stringa generata, se si aggiungono altri personaggi alla variabile chrs.

+0

Immagino che tu stia eseguendo la codifica di base 64 invece di usare la lib. –

+1

@PaulHoang: Immagino che la tua ipotesi sia sbagliata. Ho presentato la funzione che funziona in modo simile, ma 1) senza bisogno di padding (prova a rimuovere '=' s dalla risposta di nightcracker), 2) con la capacità di definire i tuoi caratteri usati per rappresentare il valore convertito. Il modo in cui funziona è molto simile a base64, ma non è base64. Probabilmente esiste una libreria per fare qualcosa del genere, ma non ha trovato quale sia. – Tadeck

+0

Mi piace molto questa soluzione. Giocando con le varie soluzioni suggerite, mi piace il meglio perché posso limitarlo a lettere e numeri e avere il controllo sull'aggiunta di più personaggi in futuro. Ben fatto. –