Ubah int ke ASCII dan kembali dengan Python


145

Saya sedang membuat penyingkat URL untuk situs saya, dan rencana saya saat ini (saya terbuka untuk saran) adalah menggunakan ID node untuk menghasilkan URL yang dipersingkat. Jadi, secara teori, node 26 mungkin short.com/z, node 1 mungkin short.com/a, node 52 mungkin short.com/Z, dan node 104 mungkin short.com/ZZ. Ketika seorang pengguna membuka URL itu, saya perlu membalik prosesnya (jelas).

Saya dapat memikirkan beberapa cara yang rumit untuk melakukan hal ini, tetapi saya rasa ada yang lebih baik. Ada saran?

Jawaban:


250

ASCII ke int:

ord('a')

memberi 97

Dan kembali ke string:

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

memberi 'a'


82
dan hanya chr () di python3!
Ehsan M. Kermani

1
chr dalam rentang karakter ascii (0 - 255), namun, unichr berfungsi untuk kumpulan karakter unicode.
Shivendra Soni


10

If multiple characters are bound inside a single integer/long, as was my issue:

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))

Yields '0123456789' and x = 227581098929683594426425L


2
Thanks for asking. I'll grant it's slightly off of the use case in the OP, given that base64 or base58 encoding would be most applicable. I had arrived on this question based on the title, literally converting an integer to ascii text as if the integer has ascii encoded data embedded in its bytes. I posted this answer in the event others arrived here with the same desired outcome.
Matthew Davis

7

What about BASE58 encoding the URL? Like for example flickr does.

# 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

Turning that back into a number isn't a big deal either.


2
This is great. I ended up finding another (more complete) answer here on SO though: stackoverflow.com/questions/1119722/…
mlissner

-1

Use hex(id)[2:] and int(urlpart, 16). There are other options. base32 encoding your id could work as well, but I don't know that there's any library that does base32 encoding built into Python.

Apparently a base32 encoder was introduced in Python 2.4 with the base64 module. You might try using b32encode and b32decode. You should give True for both the casefold and map01 options to b32decode in case people write down your shortened URLs.

Actually, I take that back. I still think base32 encoding is a good idea, but that module is not useful for the case of URL shortening. You could look at the implementation in the module and make your own for this specific case. :-)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.