RosettaCodeData/Task/Canonicalize-CIDR/UNIX-Shell/canonicalize-cidr.sh

46 lines
991 B
Bash

function inet_aton {
typeset -i addr byte
typeset -a bytes
if [[ -n $BASH_VERSION ]]; then
IFS=. read -a bytes <<<"$1"
elif [[ -n $ZSH_VERSION ]]; then
IFS=. bytes=($=1)
else
IFS=. bytes=($1)
fi
addr=0
for byte in "${bytes[@]}"; do
(( addr = 256 * addr + byte ))
done
printf '%s\n' "$addr"
}
function inet_ntoa {
typeset -i addr=$1
typeset dotted i
for (( i=0; i<4; ++i )); do
dotted=$(( addr & 255 ))${dotted:+.$dotted}
(( addr >>= 8 ))
done
printf '%s\n' "$dotted"
}
function canonicalize_cidr {
typeset ip prefix fixed
typeset -i netmask addr
while (( $# )); do
IFS=/ read ip prefix <<<"$1"
netmask=$(( (-1 << (32-prefix)) & -1 ))
addr=$(inet_aton "$ip")
fixed=$(( addr & netmask ))
printf '%s/%s\n' "$(inet_ntoa $fixed)" "$prefix"
shift
done
}
# demo code
if (( ! $# )); then
set -- 36.18.154.103/12 62.62.197.11/29 67.137.119.181/4 161.214.74.21/24 184.232.176.184/18
fi
canonicalize_cidr "$@"