Miron
February 9, 2016, 8:44am
1
Hi,
Im trying to write a Bash script that calculates the least common subnet for two address.
Theoretical: I have to change IP from decimal to binary, then apply XNOR on the two IPs.
I tried to write this:
#!/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"
I have two problems:
I need to apply XNOR to the binary IP (bit by bit), but if the result of a specific bit becomes zero I want to stop the operation and make another bit that follows the zero, zero also.
I need that XNOR ignores "."
Can someone help me with this issue please?
RudiC
February 9, 2016, 10:07am
2
Can't you apply/modify the priciples of this post?
Miron
February 10, 2016, 3:14am
3
Im new begining in Bash script, so your script is hard for me to understand.
couldnt you help me with my simple script
RudiC
February 10, 2016, 4:49am
4
I'd love to - if I only understood what you're after.
The mentioned scriptlet creates a 32-bit binary equivalent of an IP4 address and then XORs it with another. So - analyzing and testing it line by line could help you do what you need.
Miron
February 10, 2016, 5:00am
5
First i converted both deimal ip to binary.
i need to make a for loop that will compare the binary bits (bit by bit) (using XNOR) of first and second ip
XNOR theory:
1- if the bits of first and second ip equal, result will be 1
2- if they are diferent the result will be 0
But if the result become 0 of any two bits, the comparisation will stop and put 0 to the another bits without compare them
How about this:
#!/bin/bash
dec2bin () {
# dec2bin num [width] [var]
local bin=""
for((num=$1;num;num/=2))
do
bin=$((num%2))$bin
done
((${#3})) &&
printf -v ${3} "%0*d" ${2:-1} $bin ||
printf "%0*d" ${2:-1} $bin
}
xnor () {
# xnor bits1 bits2 [var]
local res=""
for((bit=0;bit<${#1};bit++))
do
if ((!done&&${1:bit:1}==${2:bit:1}))
then
res=${res}1
else
done=1
res=${res}0
fi
done
((${#3})) &&
printf -v ${3} "%d" $((2#$res)) ||
printf "%d" $((2#$res))
}
echo "Enter the first ip"
read ip1
echo "Enter the second ip"
read ip2
#Separate octs of first ip
set ${ip1//./ }
#convert decimal to binary
dec2bin $1 8 a1
dec2bin $2 8 a2
dec2bin $3 8 a3
dec2bin $4 8 a4
#Separate octs of second ip
set ${ip2//./ }
#convert decimal to binary (second IP)
dec2bin $1 8 b1
dec2bin $2 8 b2
dec2bin $3 8 b3
dec2bin $4 8 b4
done=0
xnor $a1 $b1 c1
xnor $a2 $b2 c2
xnor $a3 $b3 c3
xnor $a4 $b4 c4
echo $c1.$c2.$c3.$c4
Result:
Enter the first ip
192.168.16.55
Enter the second ip
192.168.7.55
255.255.224.0
Miron
February 12, 2016, 7:06am
7
Thanks Chubler_XL for ur answer
RudiC
February 12, 2016, 8:30am
8
Ooohh - you're after the netmask. Try
{ read IP1; read IP2; } < file1
BIP1=$(( 0x$(printf "%02X" ${IP1//./ })))
BIP2=$(( 0x$(printf "%02X" ${IP2//./ })))
TMP=$(( BIP1 ^ BIP2 ))
I=1
while [ $(( I*=2 )) -lt $TMP ]; do :; done
I=$(( --I ^ 2**32-1 ))
printf "%d.%d.%d.%d\n" $((I>>24)) $((I>>16&255)) $((I>>8&255)) $((I&255))
255.255.224.0
---------- Post updated at 14:30 ---------- Previous update was at 14:13 ----------
or
{ read IP1; read IP2; } < file1
BIP1=$(( 0x$(printf "%02X" ${IP1//./ })))
BIP2=$(( 0x$(printf "%02X" ${IP2//./ })))
TMP=$(( BIP1 ^ BIP2 ))
while (( TMP )); do TMP=$((TMP>>1)); ((I++)); done
I=$((2**32-1 ^ 2**I-1))
printf "%d.%d.%d.%d\n" $((I>>24)) $((I>>16&255)) $((I>>8&255)) $((I&255))