Converter int em ASCII e voltar em Python

137

Estou trabalhando para criar um encurtador de URL para o meu site, e meu plano atual (estou aberto a sugestões) é usar um ID de nó para gerar o URL encurtado. Assim, em teoria, o nó 26 pode ser short.com/z, o nó 1 pode ser short.com/a, o nó 52 pode ser short.com/Ze o nó 104 pode ser short.com/ZZ. Quando um usuário acessa esse URL, preciso reverter o processo (obviamente).

Posso pensar em algumas maneiras esquisitas de fazer isso, mas acho que existem outras melhores. Alguma sugestão?

mlissner
fonte
possível duplicado da Base de Dados de conversão 62 no pitão
mlissner

Respostas:

239

ASCII para int:

ord('a')

97

E voltando a uma string:

  • em Python2: str(unichr(97))
  • em Python3: chr(97)

'a'

Dominic Bou-Samra
fonte
82
e apenas chr () em python3!
Ehsan M. Kermani 03/07
1
palavras chr no intervalo dos caracteres ascii (0 - 255), no entanto, o unichr funciona para o conjunto de caracteres unicode.
Shivendra Soni
98
>>> ord("a")
97
>>> chr(97)
'a'
renatov
fonte
9

Se vários caracteres estiverem vinculados a um único inteiro / comprimento, como foi o meu problema:

s = '0123456789'
nchars = len(s)
# string to int or long. Type depends on nchars
x = sum(ord(s[byte])<<8*(nchars-byte-1) for byte in range(nchars))
# int or long to string
''.join(chr((x>>8*(nchars-byte-1))&0xFF) for byte in range(nchars))

Rendimentos '0123456789'ex = 227581098929683594426425L

Matthew Davis
fonte
2
Obrigado por perguntar. Concordo que esteja um pouco fora do caso de uso no OP, já que a codificação base64 ou base58 seria a mais aplicável. Cheguei a essa questão com base no título, convertendo literalmente um número inteiro em texto ascii como se o inteiro tivesse dados codificados em ASCII incorporados em seus bytes. Postei esta resposta caso outros chegassem aqui com o mesmo resultado desejado.
Matthew Davis
7

E o BASE58 que codifica o URL? Como por exemplo o flickr faz.

# note the missing lowercase L and the zero etc.
BASE58 = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ' 
url = ''
while node_id >= 58:
    div, mod = divmod(node_id, 58)
    url = BASE58[mod] + url
    node_id = int(div)

return 'http://short.com/%s' % BASE58[node_id] + url

Transformar isso de volta em um número também não é grande coisa.

Ivo Wetzel
fonte
2
Isso é ótimo. Acabei encontrando outra resposta (mais completa) aqui no SO: stackoverflow.com/questions/1119722/…
mlissner
-1

Usar hex(id)[2:] e int(urlpart, 16). Existem outras opções. A codificação base32 do seu ID também funcionaria, mas não sei se existe alguma biblioteca que codifique a base32 incorporada no Python.

Aparentemente, um codificador base32 foi introduzido no Python 2.4 com o módulo base64 . Você pode tentar usar b32encodee b32decode. Você deve dar Truetanto para o casefoldemap01 opções , b32decodecaso as pessoas anotem seus URLs encurtados.

Na verdade, eu retiro isso. Ainda acho que a codificação base32 é uma boa idéia, mas esse módulo não é útil para o caso de encurtamento de URL. Você pode observar a implementação no módulo e criar seu próprio caso específico. :-)

Omniforme
fonte