Для начала преобразуем @client_nets_dec в хеш, разумеется до основного цикла foreach (@client_nets_dec) { ($net_dec, $prefix, $mask_dec, $cid) = @{$_}; $client_nets_mask{$mask_dec}{$net_dec}=$cid; } Дальше в самом цикле меняем ваш foreach (@client_nets_dec) на следущий foreach my $mask_dec (keys %client_nets_mask){ $ip1_net = $ip1_dec & $mask_dec; $C1 = $client_nets_mask{$mask_dec}{$ip1_net}; ... В $С1 или пустота в случае если ip не принадлежит ни одной подсети данной размерности либо соответствующий cid. Аналогично для второго ip. В результате мы получим что количество проходов зависит не от размера @client_nets_dec, а от количества разных масок в нем, а у вас их всего 15. Для local_nets_dec подобное смысла не имеет. Если у вас несколько клиентов могут иметь одну и ту же сеть, что несколько странно, то используем arrayref для значения: $client_nets_mask{$mask_dec}{$net_dec}=$cid; заменяем на push @{client_nets_mask{$mask_dec}{$net_dec}},$cid; и соответственно в $C1 будем иметь нужный нам arrayref, по которому надо будет пройтись в foreach или map
|