Bash 实现子网掩码与前缀长度互转

前缀长度转换为子网掩码

脚本: prefix_to_mask.sh

#!/bin/bash
# date: 2018-03-03
# license: GPLv3 https://www.gnu.org/licenses/gpl-3.0.txt
# author: nanpuyue <nanpuyue@gmail.com> https://blog.nanpuyue.com

num=$(( 4294967296 - 2**(32-$1) ))
for i in {3..0};do
    echo -n $(( $num / 256**$i ))
    num=$(( $num % 256**$i ))
    [[ $i = 0 ]] && echo || echo -n .
done

这段脚本完全使用 Bash 内置函数实现,不调用外部进程。

子网掩码转换为前缀长度

脚本: mask_to_prefix.sh

#!/bin/bash
# date: 2018-03-03
# license: GPLv3 https://www.gnu.org/licenses/gpl-3.0.txt
# author: nanpuyue <nanpuyue@gmail.com> https://blog.nanpuyue.com

num=0
for n in ${1//./ };do
    if (( $n < 128 )) && (( $n != 0 ));then
        exit 1
    elif [[ $(echo "obase=2;$n"|bc) =~ ^(1*)0*$ ]];then
        if (( $(( $num % 8 )) == 0 ));then
            num=$(( $num + ${#BASH_REMATCH[1]} ))
        elif (( ${#BASH_REMATCH[1]} > 0 ));then
            exit 1
        fi
    else
        exit 1
    fi
done
echo $num

本来也想用纯 Bash 实现,但为了脚本的简洁还是调用了 bc 命令,当给出的子网掩码有误时,输出结果为空同时脚本返回值为 1 。

Gist:

  1. 将前缀长度转换为子网掩码
  2. 将子网掩码转换为前缀长度

标签: Linux, Bash, Shell, Network

已有 4 条评论

  1. leaeasy leaeasy

    看着好疼,乔老师玩python吧
    netmask = "255.255.255.0"
    sum([bin(int(x)).count("1") for x in netmask.split(".")])

  2. jiyan jiyan

    有个叫做 ipcalc 的软件很适合最这个事情~

添加新评论