我正在尝试编写一个Bash脚本来计算两个地址的最小公共子网。
理论:我必须将IP从十进制更改为二进制,然后在两个IP上应用XNOR。
我试着写这个:
#!/bin/bash
echo "Ebter the first ip"
read ip1
echo "Enter the second ip"
read ip2
#Separate octs of first ip
a1=`echo $ip1 | awk 'BEGIN{FS="."}{print $1}'`
a2=`echo $ip1 | awk 'BEGIN{FS="."}{print $2}'`
a3=`echo $ip1 | awk 'BEGIN{FS="."}{print $3}'`
a4=`echo $ip1 | awk 'BEGIN{FS="."}{print $4}'`
#convert decimal to binary
b1=`echo "obase=2;$a1" | bc`
b2=`echo "obase=2;$a2" | bc`
b3=`echo "obase=2;$a3" | bc`
b4=`echo "obase=2;$a4" | bc`
#Separate octs of second ip
c1=`echo $ip2 | awk 'BEGIN{FS="."}{print $1}'`
c2=`echo $ip2 | awk 'BEGIN{FS="."}{print $2}'`
c3=`echo $ip2 | awk 'BEGIN{FS="."}{print $3}'`
c4=`echo $ip2 | awk 'BEGIN{FS="."}{print $4}'`
#convert decimal to binary (second IP)
d1=`echo "obase=2;$c1" | bc`
d2=`echo "obase=2;$c2" | bc`
d3=`echo "obase=2;$c3" | bc`
d4=`echo "obase=2;$c4" | bc`
e1=`echo $b1 || $d1 | rev`
e2=`echo $b2 || $d2 | rev`
e3=`echo $b3 || $d3 | rev`
e4=`echo $b4 || $d4 | rev`
echo "$e1.$e2.$e3.$e4"
我有两个问题:
我需要将XNOR应用于二进制IP(逐位),但如果特定位的结果变为零,我想停止操作并使另一位跟随零,零也。 / p>
我需要XNOR忽略“。”。
有人可以帮我解决这个问题吗?
答案 0 :(得分:2)
首先,使用read
将地址拆分为整数部分要简单得多。
IFS=. read a1 a2 a3 a4 <<< "$ip1"
IFS=. read b1 b2 b3 b4 <<< "$ip2"
完成后,您可以在每个部分使用shell算法;不需要先将每个显式转换为二进制文件。
但是,在bash
中计算掩码仍然有点棘手。试试这个:
set_mask_part () {
local m=255
local a=$1
local b=$2
# While a and b are different, shift m left
# and shift and b right. When a and b are equal,
# the mask converges to the correct value.
while (( a != b )); do
(( m = (m << 1) & 255 ))
(( a = a >> 1 ))
(( b = b >> 1 ))
done
echo "$m"
}
# Get the left-most mask byte first, and repeat for
# each byte to the right as long as the previous byte is 255
m1=$(set_mask_part "$a1" "$b1")
(( m1 == 255 )) && m2=$(set_mask_part "$a2" "$b2") || m2=0
(( m2 == 255 )) && m3=$(set_mask_part "$a3" "$b3") || m3=0
(( m3 == 255 )) && m4=$(set_mask_part "$a4" "$b4") || m4=0
mask="$m1.$m2.$m3.$m4"