Implement an encoder for RFC 1924 IPv6 Addresses
Pyth, 93 91 bytes

Ks[jkUTrG1G"!#$%&amp;()*+-;&lt;=&gt;?@^_`{|}~")$from ipaddress import*;z=int(ip_address(z))$sm@Kdjz85


Second submission in Pyth!

Can't try online because $ is unsafe.

When tested against the example, produces the expected result:

$ pyth -c 'Ks[jkUTrG1G"!#$%&amp;()*+-;&lt;=&gt;?@^_`{|}~")$from ipaddress import *$$z=int(ip_address(z))$sm@Kdjz85'
1080::8:800:200C:417A
4)+k&amp;C#VzJ4br&gt;0wv%Yp


Edits:


Saved two bytes by replacing $$ with ; and removing space before *


Explanation

First part creates the mapping string and assigns it to K:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&amp;()*+-;&lt;=&gt;?@^_`{|}~


This is done as follows:

Ks[jkUTrG1G"!#$%&amp;()*+-;&lt;=&gt;?@^_`{|}~")
K                                       implicitly assign to K
 s[                                 )   the string joined from the following list
     UT                                 range [0..9]
   jk                                   joined with the empty string: 0123456789
       rG1                              capitalized version of the string G (whole alphabet)
          G                             G itself
           "!#$%&amp;()*+-;&lt;=&gt;?@^_`{|}~"    all other symbols (shorter to declare than generate)


Then, the second part is two pieces of normal python amounting to 47 bytes, to convert the input ipv6 address to a number (because z is accessed later in the code, it is first implicitly assigned to any input value before running the Python code)

*from ipaddress import *$$z=int(ip_address(z))$


Then, the last part converts the resulting number to base 85 as a list and maps every value to the mapping string K:

sm@Kdjz85
     jz85  convert z to base 85
 m         map over the converted number with lambda d:
  @Kd      K[d]
s          join as a string and implicitly print


Pure Pyth, 100 bytes

Ks[jkUTrG1G"!#$%&amp;()*+-;&lt;=&gt;?@^_`{|}~")IgJx=zcz\:kZ=z-z]k=z.n++&lt;zJ]*-8lz]\0&gt;zJ)=zimid16z65536sm@Kdjz85


You can try it here

In order to support leading/middle/trailing ::, I must insert a list of missing zeroes in the correct position in the ip once converted to a list of hex numbers, which takes up more space than the inline Python version. There's room for improvement but I doubt it can beat the other version!

63 bytes version

Doesn't support the :: notation to skip zeroes:

Ks[jkUTrG1G"!#$%&amp;()*+-;&lt;=&gt;?@^_`{|}~")=zimid16cz\:65536sm@Kdjz85


You can try it here

The different part here is converting the ipv6 to a number using base conversions:

=zimid16cz\:65536
         z          read string from input and assign it to z
        c \:        split it at columns
   m                map over the split list with lambda d:
    id16            convert d from base 16 to 10
  i         65536   convert list of ints from base 65536 to 10
=z                  assign result back to z