Подтвердить что ты не робот

Учитывая IP и сетевую маску, как я могу вычислить сетевой адрес с помощью bash?

В bash script у меня есть IP-адрес, например 192.168.1.15, и сетевая маска, такая как 255.255.0.0. Теперь я хочу рассчитать начальный адрес этой сети, то есть использовать & -оператор на обоих адресах. В этом примере результат будет равен 192.168.0.0. У кого-то есть что-то вроде этого готового? Я ищу элегантный способ решения ip-адресов из bash

4b9b3361

Ответ 1

Использовать побитовый оператор & (AND):

$ IFS=. read -r i1 i2 i3 i4 <<< "192.168.1.15"
$ IFS=. read -r m1 m2 m3 m4 <<< "255.255.0.0"
$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
192.168.0.0

Пример с другим IP и маской:

$ IFS=. read -r i1 i2 i3 i4 <<< "10.0.14.97"
$ IFS=. read -r m1 m2 m3 m4 <<< "255.255.255.248"
$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))"
10.0.14.96

Ответ 2

Некоторые функции Bash, суммирующие все другие ответы.

ip2int()
{
    local a b c d
    { IFS=. read a b c d; } <<< $1
    echo $(((((((a << 8) | b) << 8) | c) << 8) | d))
}

int2ip()
{
    local ui32=$1; shift
    local ip n
    for n in 1 2 3 4; do
        ip=$((ui32 & 0xff))${ip:+.}$ip
        ui32=$((ui32 >> 8))
    done
    echo $ip
}

netmask()
{
    local mask=$((0xffffffff << (32 - $1))); shift
    int2ip $mask
}


broadcast()
{
    local addr=$(ip2int $1); shift
    local mask=$((0xffffffff << (32 -$1))); shift
    int2ip $((addr | ~mask))
}

network()
{
    local addr=$(ip2int $1); shift
    local mask=$((0xffffffff << (32 -$1))); shift
    int2ip $((addr & mask))
}

Ответ 3

Просто добавьте альтернативу, если у вас есть только сетевой префикс (нет сетевой маски):

IP=10.20.30.240
PREFIX=26
IFS=. read -r i1 i2 i3 i4 <<< $IP
IFS=. read -r xx m1 m2 m3 m4 <<< $(for a in $(seq 1 32); do if [ $(((a - 1) % 8)) -eq 0 ]; then echo -n .; fi; if [ $a -le $PREFIX ]; then echo -n 1; else echo -n 0; fi; done)
printf "%d.%d.%d.%d\n" "$((i1 & (2#$m1)))" "$((i2 & (2#$m2)))" "$((i3 & (2#$m3)))" "$((i4 & (2#$m4)))"

Ответ 4

Отличный ответ, хотя небольшая опечатка в ответе выше.

$ printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$(($i2  <-- $i2 should be i2

Если кто-либо знает, как рассчитать широковещательный адрес (XOR сеть), а затем вычислить используемые узлы между сетью и трансляцией, мне бы хотелось, чтобы эти следующие шаги. Я должен найти адреса в списке в пределах/23.

Ответ 5

В дополнение к @Janci ответу

IP=10.20.30.240
PREFIX=26
IFS=. read -r i1 i2 i3 i4 <<< $IP
D2B=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
binIP=${D2B[$i1]}${D2B[$i2]}${D2B[$i3]}${D2B[$i4]}
binIP0=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((32-$PREFIX))))
# binIP1=${binIP::$PREFIX}$(printf '0%.0s' $(seq 1 $((31-$PREFIX))))1
echo $((2#${binIP0::8})).$((2#${binIP0:8:8})).$((2#${binIP0:16:8})).$((2#${binIP0:24:8}))