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?

mlissner
sumber

Jawaban:

250

ASCII ke int:

ord('a')

memberi 97

Dan kembali ke string:

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

memberi 'a'

Dominic Bou-Samra
sumber
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
100
>>> ord("a")
97
>>> chr(97)
'a'
renatov
sumber
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

Matthew Davis
sumber
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.

Ivo Wetzel
sumber
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. :-)

Omnifarious
sumber