ちょっと事情があって、サブネットマスクのCIDR形式⇔アドレス形式の変換を行わせるシェルスクリプトを作成する必要が出たので、サンプルを掲載していたサイト含め紹介する。 解説は不要かもしれないが、各スクリプト名は「mask2cdr」がアドレス形式→CIDR形式、「cdr2mask」がCIDR形式→アドレス形式となる。 なお、基本的には関数として抽出し、末尾にサンプルを記載しておく。

/bin/sh形式

このスクリプトは、こちらのフォーラムに掲載されていた。

mask2cidr

#!/bin/sh
mask2cidr ()
{
 # Assumes there's no "255." after a non-255 byte in the mask
 local x=${1##*255.}
 set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) ${x%%.*}
 x=${1%%$3*}
 echo $(( $2 + (${#x}/4) ))
}

# examples:
mask2cidr 255.255.255.0

cidr2mask

#!/bin/sh
cidr2mask ()
{
# Number of args to shift, 255..255, first non-255 byte, zeroes
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
[ $1 -gt 1 ] && shift $1 || shift
echo ${1-0}.${2-0}.${3-0}.${4-0}
}

# examples:
cidr2mask 24

/bin/bash形式

このスクリプトは、こちらのフォーラムに掲載されていた。

mask2cidr

#!/bin/bash
mask2cidr() {
    nbits=0
    IFS=.
    for dec in $1 ; do
        case $dec in
            255) let nbits+=8;;
            254) let nbits+=7;;
            252) let nbits+=6;;
            248) let nbits+=5;;
            240) let nbits+=4;;
            224) let nbits+=3;;
            192) let nbits+=2;;
            128) let nbits+=1;;
            0);;
            *) echo "Error: $dec is not recognised"; exit 1
        esac
    done
    echo "$nbits"
}

# examples:
MASK=255.255.254.0
numbits=$(mask2cidr $MASK)
echo "/$numbits"
exit 0

cidr2mask

#!/bin/bash
cidr2mask() {
  local i mask=""
  local full_octets=$(($1/8))
  local partial_octet=$(($1%8))

  for ((i=0;i<4;i+=1)); do
    if [ $i -lt $full_octets ]; then
      mask+=255
    elif [ $i -eq $full_octets ]; then
      mask+=$((256 - 2**(8-$partial_octet)))
    else
      mask+=0
    fi
    test $i -lt 3 && mask+=.
  done

  echo $mask
}

# examples:
numbits=24
MASK=$(cidr2mask $numbits)
echo "$MASK"
exit 0

/bin/ksh形式

このスクリプトは、こちらのフォーラムに掲載されていた。 なお、「cidr2mask」に関しては「/bin/sh」のソースを流用し、動作確認をしている。

mask2cidr

#!/bin/ksh
mask2cidr() {
typeset -A octets=([255]=8 [254]=7 [252]=6 [248]=5 [240]=4
[224]=3 [192]=2 [128]=1 [0]=0)

while read -rd '.' dec
do
[[ -z ${octets[$dec]} ]] && echo "Error: $dec is not recognised" && exit 1
(( nbits += ${octets[$dec]} ))
[[ $dec -lt 255 ]] && break
done <<<"$1."
echo "/$nbits"
}

mask2cidr "255.255.255.0"
exit 0

cidr2mask

#!/bin/ksh
cidr2mask ()
{
# Number of args to shift, 255..255, first non-255 byte, zeroes
set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
[ $1 -gt 1 ] && shift $1 || shift
echo ${1-0}.${2-0}.${3-0}.${4-0}
}

# examples:
cidr2mask 24