Ver Mensaje Individual
  #1 (permalink)  
Antiguo 03/06/2011, 10:27
leif_sk8er
 
Fecha de Ingreso: junio-2009
Mensajes: 309
Antigüedad: 14 años, 10 meses
Puntos: 5
IPV6 y IPV4 en campo INT

Buenas,

He estado buscando informacion sobre como almacenar las IPs en la base de datos. En los textos que he encontrado hay quien dice de almacenar el campo tanto IP4 (165.14.165.45) como IP6 (FEBC:A574:382B:23C1:AA49:4592:4EFE:9982), como cadena, pero claro eso es ineficiente para la base de datos por que un varchar ocupa mucho mas.

Para ello existe ip2long que pasa una ip4 a un int, pero al parecer tiene problemas con ip6. He estado buscando y he encontrado este par de funciones que pasa tanto ip4 y 6 a un int.

Código PHP:
Ver original
  1. function ip2bin($ip){
  2.     if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false)
  3.         return base_convert(ip2long($ip),10,2);
  4.     if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false)
  5.         return false;
  6.     if(($ip_n = inet_pton($ip)) === false) return false;
  7.     $bits = 15; // 16 x 8 bit = 128bit (ipv6)
  8.     while ($bits >= 0){
  9.         $bin = sprintf("%08b",(ord($ip_n[$bits])));
  10.         $ipbin = $bin.$ipbin;
  11.         $bits--;
  12.     }
  13.     return $ipbin;
  14. }
  15.  
  16. function bin2ip($bin){
  17.    if(strlen($bin) <= 32) // 32bits (ipv4)
  18.        return long2ip(base_convert($bin,2,10));
  19.    if(strlen($bin) != 128)
  20.        return false;
  21.    $pad = 128 - strlen($bin);
  22.    for ($i = 1; $i <= $pad; $i++)
  23.    {
  24.        $bin = "0".$bin;
  25.    }
  26.    $bits = 0;
  27.    while ($bits <= 7)
  28.    {
  29.        $bin_part = substr($bin,($bits*16),16);
  30.        $ipv6 .= dechex(bindec($bin_part)).":";
  31.        $bits++;
  32.    }
  33.    return inet_ntop(inet_pton(substr($ipv6,0,-1)));
  34. }


El resultado generado por ejemplo para la IP6 es algo como el siguiente:
11111110101111001010010101110100001110000010101100 10001111000001101010100100100101000101100100100100 1110111111101001100110000010

Con 128 digitos....... Ahora la duda del millon: ¿Como guardo 128 digitos? Por que en ningun sitio se explica, hay quien dice que usando 2 campos bigint , y en ese mismo sitio pone que cada campo bigint tiene 64 caracteres de capacidad!! :S :S
Los campos bigint unsigned tienen 20 caracteres de capacidad (18.446.744.073.709.551.615 , http://www.desarrolloweb.com/articulos/1054.php), es decir, necesitarias 7 columnas de bigint donde en cada columna se guarden 20, y en la ultima 8.....

No puede ser esa la forma de hacerse :S

7 columnas para almacenar una IP?? Parece de risa.


¿¿No hay una forma general donde se pueda guardar tanto IP4 y 6 de forma general en un campo int ocupando lo minimo posible??

Última edición por leif_sk8er; 03/06/2011 a las 10:35