The function of obtaining an array of subnets between two ip4 addresses. May be useful for organizing addresses database. The order of the transmitted addresses does not matter.
There is also a tool for working with address databases, if anyone is interested syo.su
Code:
# return common subnet prefix of two ip:global getIpCommonPrefix do={ :local xorIp ([:tonum [:toip $1]] ^ [:tonum [:toip $2]]) :local prefix 32 :while ($xorIp) do={ :set xorIp ($xorIp >> 1) :set prefix ($prefix - 1) } :return $prefix}:put [$getIpCommonPrefix 192.168.88.77 192.168.88.111]# return array with subnets between two ip:global getSubnetsBetweenIp do={ :local ip1 [:toip $1] :local ip2 [:toip $2] :local subnets [:toarray ""] :global getIpCommonPrefix :local prefix [$getIpCommonPrefix $1 $2] :local submask (255.255.255.255 << (32 - $prefix)) :local addrspace (~$submask) :local network :local broadcast :if ($prefix = 0) do={ :set network 0.0.0.0 :set broadcast 255.255.255.255 } else={ :set network ($ip1 & $submask) :set broadcast ($ip1 | $addrspace) } :local isInArray do={ :local search [:toip $1] :for i from=([:len $2] - 1) to=0 step=-1 do={ :if ($search in ($2->$i)) do={ :return true } } :return false } :if ($ip1 > $ip2) do={ :set ip1 $ip2 :set ip2 [:toip $1] } :if ($ip1 = $network && $ip2 = $broadcast) do={ :set subnets ($subnets, ($network."/".$prefix)) } else={ :local finded1 false :local finded2 false :while ($prefix < 32 && (!$finded1 || !$finded2)) do={ :set prefix ($prefix + 1) :set submask (255.255.255.255 << (32 - $prefix)) :set addrspace (~$submask) :local step (1 << (32 - $prefix)) :if (!$finded1) do={ :local checknet ($ip1 & $submask) :local loop true :while ($loop && $checknet <= $ip2) do={ :if (![$isInArray $checknet $subnets]) do={ :local checkbro ($checknet | $addrspace) :if ($checknet >= $ip1 && $checkbro <= $ip2) do={ :if ($checknet = $ip1) do={ :set finded1 true } :if ($checkbro = $ip2) do={ :set finded2 true } :set subnets ($subnets, ($checknet."/".$prefix)) } } else={ :set loop false } :if ((255.255.255.255 - $checknet) >= $step) do={ :set checknet ($checknet + $step) } else={ :set loop false } } } :if (!$finded2) do={ :local checknet ($ip2 & $submask) :local checkbro ($checknet | $addrspace) :local loop true :while ($loop && $checkbro >= $ip1) do={ :if (![$isInArray $checkbro $subnets]) do={ :set checknet ($checkbro & $submask) :if ($checknet >= $ip1 && $checkbro <= $ip2) do={ :if ($checknet = $ip1) do={ :set finded1 true } :if ($checkbro = $ip2) do={ :set finded2 true } :set subnets ($subnets, ($checknet."/".$prefix)) } } else={ :set loop false } :if ([:tonum $checkbro] >= $step) do={ :set checkbro ($checkbro - $step) } else={ :set loop false } } } } } :return $subnets}:put [$getSubnetsBetweenIp 0.0.0.1 255.255.255.254]:put [$getSubnetsBetweenIp 255.255.255.254 0.0.0.0]:put [$getSubnetsBetweenIp 0.0.0.1 255.255.255.255]:put [$getSubnetsBetweenIp 0.0.0.0 255.255.255.255]
There is also a tool for working with address databases, if anyone is interested syo.su
Statistics: Posted by DenSyo77 — Fri Jan 12, 2024 2:15 pm