• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

triplexim32

Ip nacional

15 mensagens neste tópico

Como faço no PHP para verificar se o IP em causa é nacional ou não?

abraço ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tens de ter uma lista dos IP's nacionais e depois teres um script para verificar se o IP do utilizador que te está a visitar faz parte de alguma gama de IP's nacionais.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tens de ter uma lista dos IP's nacionais e depois teres um script para verificar se o IP do utilizador que te está a visitar faz parte de alguma gama de IP's nacionais.

eu consegui arranjar alguns ips, tenho tipo isto:

146.193.32.0/19

213.63.0.0/17

194.145.59.0/24

212.113.160.0/19

192.104.37.0/24

(...)

tenho uma carrada deles

mas nao percebo o que é aquele numero a frente da barra, será a mascara de subrede?

Tipo nao sei como verificar mascaras de subrede... ou o que é aquilo?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Metes numa bd, e depois fazes uma query a verificar se existe. Podes encontrar informações sobre mysql no site do php. ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Esses IPs são as chamadas ranges. O número a seguir à barra é o número de bits fixo para cada range.

Por exemplo 146.193.32.0/19.

Se traduzirmos isto para binário fica 10010010.11000001.00100000.00000000

Agora para ver se um determinado IP pertence a esta range temos que fazer um AND bit a bit dos dois IPs ignorando os últimos 19 bits.

Por exemplo o IP 146.0.0.1 (10010010.00000000.00000000.00000001) pertence a esta range?

10010010.1100(0001.00100000.00000000)

10010010.0000(0000.00000000.00000001)

11111111.0011

Como podes ver, neste caso o AND bit a bit não dá sempre 1, por isso o IP não pertence à range

E se for o IP 146.193.158.137 (10010010.11000001.10011110.10001001)?

10010010.1100(0001.00100000.00000000)

10010010.1100(0001.10011110.10001001)

11111111.1111

Neste caso o AND bit a bit dá sempre 1, o que significa que IP pertence à range.

Acho que é isto, espero não estar a dizer uma enorme asneira.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Metes numa bd, e depois fazes uma query a verificar se existe. Podes encontrar informações sobre mysql no site do php. ;)

ja consegui, fiz um find replace em varios sitios e fiquei com isto:

if(

($IP >=  ip_to_number('62.28.0.0') and $IP <=  ip_to_number('62.28.255.255'))

or ($IP >=  ip_to_number('62.41.70.32') and $IP <=  ip_to_number('62.41.70.95'))

or ($IP >=  ip_to_number('62.48.128.0') and $IP <=  ip_to_number('62.48.255.255'))

or ($IP >=  ip_to_number('62.93.191.248') and $IP <=  ip_to_number('62.93.191.255'))

(...)

)

echo 'IP nacional';

else

echo 'Ip inter';

-------

a função para converter o IP em numerário:

function ip_to_number($IPaddress){

if ($IPaddress == "") {

return 0;

} else {

$ips = split ("\.", "$IPaddress");

return ($ips[3] + $ips[2] * 256 + $ips[1] * 256 * 256 + $ips[0] * 256 * 256 * 256);

}

}

Esses IPs são as chamadas ranges. O número a seguir à barra é o número de bits fixo para cada range.

Por exemplo 146.193.32.0/19.

Se traduzirmos isto para binário fica 10010010.11000001.00100000.00000000

Agora para ver se um determinado IP pertence a esta range temos que fazer um AND bit a bit dos dois IPs ignorando os últimos 19 bits.

Por exemplo o IP 146.0.0.1 (10010010.00000000.00000000.00000001) pertence a esta range?

10010010.1100(0001.00100000.00000000)

10010010.0000(0000.00000000.00000001)

11111111.0011

Como podes ver, neste caso o AND bit a bit não dá sempre 1, por isso o IP não pertence à range

E se for o IP 146.193.158.137 (10010010.11000001.10011110.10001001)?

10010010.1100(0001.00100000.00000000)

10010010.1100(0001.10011110.10001001)

11111111.1111

Neste caso o AND bit a bit dá sempre 1, o que significa que IP pertence à range.

É semelhante à máscara de rede mas com uma pequena (grande) diferença. Depois explico se quiseres.

Penso que nao vai ser preciso pois ja tenho uma solução para a coisa.

Mas na mesma:

Não conheces maneira de ver (em PHP) se um ip esta neste range:

(por exemplo) 192.104.37.0/24

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se tiveres o ip inicial e terminal da range é só usares o ip2long()

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se tiveres o ip inicial e terminal da range é só usares o ip2long()

ip2long() se percebi transforma o teu IP em numerário certo?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não conheces maneira de ver (em PHP) se um ip esta neste range:

(por exemplo) 192.104.37.0/24

Bom, não estou muito à vontade com o PHP e se calhar já não precisas, mas de qualquer maneira fica aqui na mesma que é para eu praticar um bocadinho o PHP.

function is_in_range($ip,$ip_base)
{
    $ip_split = split(".","$ip");
    $ip_base_split = split ("/.", "$ip_base");

    // Pegamos nos 4 grupos de 8 bits do IP que queremos verificar e colocamos todos lado a lado numa variável.
    // Seja abcdefgh cada grupo de 8 bits. As próximas linhas fazem o seguinte:
    // abcdefgh000000000000000000000000
    $ip_bin = $ip_split[0]<<24;
    // xxxxxxxxabcdefgh0000000000000000
    $ip_bin = $ip_bin & ($ip_split[1] << 16);
    // xxxxxxxxxxxxxxxxabcdefgh00000000
    $ip_bin = $ip_bin & ($ip_split[2] << 8);
    // xxxxxxxxxxxxxxxxxxxxxxxxabcdefgh
    $ip_bin = $ip_bin & ($ip_split[3]);

    // Agora fazemos exactamente o mesmo para o IP base
    $ip_base_bin = $ip_base_split[0]<<24;
    $ip_base_bin = $ip_base_bin & ($ip_base_split[1] << 16);
    $ip_base_bin = $ip_base_bin & ($ip_base_split[2] << 8);
    $ip_base_bin = $ip_base_bin & ($ip_base_split[3]);

    // Os últimos N bits de cada IP não nos interessam por isso deitamo-los fora
    // Fica 0000000000000000000xxxxxxxxxxxx
    $ip_base_bin = $ip_base_bin >> $ip_base_split[4];
    $ip_bin = $ip_bin >> $ip_base_split[4];

     // Se os dois IPs ficaram iguais, então o IP que queriamos testar, pertence à range
     return ($ip_base_bin == $ip_bin);
}

Não sei se os inteiros em PHP têm 32 bits. Se não tiverem, tens de dividir os IPs em 2 e fazer metade de cada vez.

Não testei, pode ter bugs.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

eu acabei por fazer um script para inserir automaticamente na base de dados (depois e so verificar).

mas vou guardar o teu script caso os IP's que arranjei depois nao funcionem devidamente (tenho sempre os outros iniciais com a mascara de subrede).

muito obrigado pela ajuda

-----

Edit:

tenho uma duvida:

$ip_bin = $ip_bin & ($ip_split[1] << 16);

o que é que faz o "&"

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Edit:

tenho uma duvida:

$ip_bin = $ip_bin & ($ip_split[1] << 16);

o que é que faz o "&"

É o AND binário.

EDIT: Agora é que reparei que fiz uma pequena grande asneira.

function is_in_range($ip,$ip_base)
{
    $ip_split = split(".","$ip");
    $ip_base_split = split ("/.", "$ip_base");

    // Pegamos nos 4 grupos de 8 bits do IP que queremos verificar e colocamos todos lado a lado numa variável.
    // Seja abcdefgh cada grupo de 8 bits. As próximas linhas fazem o seguinte:
    // 11111111111111111111111111111111
    $ip_bin = 0xFFFFFFFF;
    // abcdefgh111111111111111111111111
    $ip_bin = $ip_bin & ($ip_split[0]<<24);
    // xxxxxxxxabcdefgh1111111111111111
    $ip_bin = $ip_bin & ($ip_split[1] << 16);
    // xxxxxxxxxxxxxxxxabcdefgh11111111
    $ip_bin = $ip_bin & ($ip_split[2] << 8);
    // xxxxxxxxxxxxxxxxxxxxxxxxabcdefgh
    $ip_bin = $ip_bin & ($ip_split[3]);

    // Agora fazemos exactamente o mesmo para o IP base
    $ip_base_bin = 0xFFFFFFFF;
    $ip_base_bin = $ip_base_bin & ($ip_base_split[0]<<24);
    $ip_base_bin = $ip_base_bin & ($ip_base_split[1] << 16);
    $ip_base_bin = $ip_base_bin & ($ip_base_split[2] << 8);
    $ip_base_bin = $ip_base_bin & ($ip_base_split[3]);

    // Os últimos N bits de cada IP não nos interessam por isso deitamo-los fora
    // Fica 0000000000000000000xxxxxxxxxxxx
    $ip_base_bin = $ip_base_bin >> $ip_base_split[4];
    $ip_bin = $ip_bin >> $ip_base_split[4];

     // Se os dois IPs ficaram iguais, então o IP que queriamos testar, pertence à range
     return ($ip_base_bin == $ip_bin);
}

Assim é que está correcto, julgo eu.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora