Skip to content

Instantly share code, notes, and snippets.

@oguz-ismail
Created December 21, 2022 10:29
Show Gist options
  • Save oguz-ismail/ca4518fc8ce8b5b6edd1db3514836aa1 to your computer and use it in GitHub Desktop.
Save oguz-ismail/ca4518fc8ce8b5b6edd1db3514836aa1 to your computer and use it in GitHub Desktop.
# Takes an IPv6 address as argument
# and encodes it as described in RFC1924.
export LC_ALL=C
export POSIXLY_CORRECT=1
unset BC_ENV_ARGS
unset BC_LINE_LENGTH
d0='0' d10='A' d20='K' d30='U' d40='e' d50='o' d60='y' d70='+' d80='`'
d1='1' d11='B' d21='L' d31='V' d41='f' d51='p' d61='z' d71='-' d81='{'
d2='2' d12='C' d22='M' d32='W' d42='g' d52='q' d62='!' d72=';' d82='|'
d3='3' d13='D' d23='N' d33='X' d43='h' d53='r' d63='#' d73='<' d83='}'
d4='4' d14='E' d24='O' d34='Y' d44='i' d54='s' d64='$' d74='=' d84='~'
d5='5' d15='F' d25='P' d35='Z' d45='j' d55='t' d65='%' d75='>'
d6='6' d16='G' d26='Q' d36='a' d46='k' d56='u' d66='&' d76='?'
d7='7' d17='H' d27='R' d37='b' d47='l' d57='v' d67='(' d77='@'
d8='8' d18='I' d28='S' d38='c' d48='m' d58='w' d68=')' d78='^'
d9='9' d19='J' d29='T' d39='d' d49='n' d59='x' d69='*' d79='_'
bad_address() {
printf 'invalid address: %s\n' "$addr"
exit 1
} >&2
addr=$1
case $addr in
*.* )
tail=${addr##*:}
head=${addr%"$tail"}
case $tail in
'' | *[!0-9.]* )
bad_address ;;
.* | *..* | *. | *.*.*.*.* )
bad_address ;;
*[!.][!.][!.][!.]* )
bad_address ;;
*.*.*.* ) ;;
* )
bad_address
esac
tail16=$(
IFS=.
for d in $tail; do
if test $d -gt 255; then
bad_address
fi
printf '%02X' $d
done
)
addr=$head${tail16%????}:${tail16#????}
esac
case $addr in
'' | *[!0-9A-Fa-f:]* )
bad_address ;;
*:::* | *::*::* | *:*:*:*:*:*:*:*:* )
bad_address ;;
*[!:][!:][!:][!:][!:]* )
bad_address ;;
*::* ) ;;
*[!:]*:*:*:*:*:*:*:*[!:]* ) ;;
* )
bad_address
esac
case $addr in
*::* )
case $addr in
:: )
addr=0${addr}0 ;;
::* )
addr=0$addr ;;
*:: )
addr=${addr}0
esac
head=${addr%%::*}
tail=${addr#"$head":}
while true; do
case $head$tail in
*:*:*:*:*:*:*:* )
break ;;
* )
tail=:0$tail
esac
done
addr=$head$tail
esac
addr16=$(
IFS=:
for d in $addr; do
printf '%04X' 0x$d
done
)
rem85=$(bc <<eof
ibase = 16
q = $addr16
ibase = A
for (i = 0; i < 20; i++) {
r = q % 85
q -= r
q /= 85
r
}
eof
)
addr85=
for d in $rem85; do
eval "addr85=\$(printf '%c' \$d$d)\$addr85"
done
printf '%s\n' "$addr85"
# vim: ft=sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment