Encode IP address using all printable characters in Python 2.7.x
Question: I would like to encode an IP address in as short a string as possible using
all the printable characters. According to
<https://en.wikipedia.org/wiki/ASCII#Printable_characters> these are codes
20hex to 7Ehex.

For example:

    
    
    shorten("172.45.1.33") --> "^.1 9" maybe.
    

In order to make decoding easy I also need the length of the encoding always
to be the same. I also would like to avoid using the space character in order
to make parsing easier in the future.

> How can one do this?

I am looking for a solution that works in Python 2.7.x.

* * *

My attempt so far to modify Eloims's answer to work in Python 2:

First I installed the ipaddress backport for Python 2
(<https://pypi.python.org/pypi/ipaddress>) .

    
    
    #This is needed because ipaddress expects character strings and not byte strings for textual IP address representations 
    from __future__ import unicode_literals
    import ipaddress
    import base64
    
    #Taken from http://stackoverflow.com/a/20793663/2179021
    def to_bytes(n, length, endianess='big'):
        h = '%x' % n
        s = ('0'*(len(h) % 2) + h).zfill(length*2).decode('hex')
        return s if endianess == 'big' else s[::-1]
    
    def def encode(ip):
        ip_as_integer = int(ipaddress.IPv4Address(ip))
        ip_as_bytes = to_bytes(ip_as_integer, 4, endianess="big")
        ip_base85 = base64.a85encode(ip_as_bytes)
        return ip_base
    
    print(encode("192.168.0.1"))
    

This now fails because base64 doesn't have an attribute 'a85encode'.


Answer: An IP stored in binary is 4 bytes.

You can encode it in 5 printable ASCII characters using Base85.

Using more printable characters won't be able to shorten the resulting string
more than that.

    
    
    import ipaddress
    import base64
    
    def encode(ip):
        ip_as_integer = int(ipaddress.IPv4Address(ip))
        ip_as_bytes = ip_as_integer.to_bytes(4, byteorder="big")
        ip_base85 = base64.a85encode(ip_as_bytes)
        return ip_base85
    
    print(encode("192.168.0.1"))
    

