borrame.com - Colección particular de recortes de código y documentación para programación web

Lo más fresco

  1. Cadena aleatoria en PHP (¡ahora también multi-byte!) Modificado
  2. Cookies en JavaScript Modificado
  3. Reiniciar Apache con cuidado (graceful restart) Modificado

Sugerencias del chef

Lo más visitado

  1. Dar formato a un número
  2. Fecha y hora
  3. Cookies
  4. Rotar logs en Windows
  5. Reiniciar Apache con cuidado (graceful restart)

Convertir IP entre cadena y número

Hasta donde este humilde cronista ha podido determinar, Oracle no dispone de funciones nativas para convertir direcciones IP formateadas como cadenas (v.gr. 192.168.0.100) en números enteros (v.gr. 3232235620) y a la inversa. Así que aquí tenemos unas de fabricación casera.

Como no sabía qué nombre ponerles he usado la convención de PHP: ip2long() y long2ip(). En otros lenguajes se llaman inet_aton() e inet_ntoa(), que es casi igual de confuso.

CREATE OR REPLACE FUNCTION IP2LONG (
    IP_CADENA IN VARCHAR2
) RETURN NUMBER DETERMINISTIC
IS
    IP1 NUMBER;
    IP2 NUMBER;
    IP3 NUMBER;
    IP4 NUMBER;
BEGIN
    /*
     * Recibe una dirección IPv4 en formato cadena y devuelve el número entero correspondiente
     * Devuelve NULL si no es una IP válida
     */

    IF NOT REGEXP_LIKE(IP_CADENA, '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$') THEN
        RETURN NULL;
    END IF;

    IP1 := TO_NUMBER(REGEXP_SUBSTR(IP_CADENA, '[0-9]+', 1, 1));
    IP2 := TO_NUMBER(REGEXP_SUBSTR(IP_CADENA, '[0-9]+', 1, 2));
    IP3 := TO_NUMBER(REGEXP_SUBSTR(IP_CADENA, '[0-9]+', 1, 3));
    IP4 := TO_NUMBER(REGEXP_SUBSTR(IP_CADENA, '[0-9]+', 1, 4));

    IF IP1 BETWEEN 0 AND 255 AND IP2 BETWEEN 0 AND 255 AND IP3 BETWEEN 0 AND 255 AND IP4 BETWEEN 0 AND 255 THEN
    RETURN
        IP1 * 16777216 + -- 2^24
        IP2 *    65536 + -- 2^16
        IP3 *      256 + -- 2^8
        IP4;             -- 2^0
    ELSE
        RETURN NULL;
    END IF;
END IP2LONG;
/



CREATE OR REPLACE FUNCTION LONG2IP (
    IP_NUMERO IN NUMBER
) RETURN VARCHAR2 DETERMINISTIC
IS
BEGIN
    /*
     * Recibe una dirección IPv4 en formato numérico y devuelve la cadena correspondiente
     * Devuelve NULL si no es una IP válida
     */

    IF IP_NUMERO BETWEEN 0 AND 4294967295 THEN -- [0, 2^32 - 1]
        RETURN
            BITAND(IP_NUMERO / 16777216, 255) || '.' || -- 2^24 / 2^8 - 1
            BITAND(IP_NUMERO /    65536, 255) || '.' || -- 2^16 / 2^8 - 1
            BITAND(IP_NUMERO /      256, 255) || '.' || -- 2^8  / 2^8 - 1
            BITAND(IP_NUMERO,            255);          -- 2^0  / 2^8 - 1
    ELSE
        RETURN NULL;
    END IF;
END LONG2IP;
/

Compatibilidad

IP2LONG() utiliza expresiones regulares así que requiere Oracle 10 o superior.

Esta página ha sido impresa el jueves 29 de julio de 2010 (21:25:21 +0200) desde http://borrame.com/recortes/oracle/ip2long-long2ip.html. La última vez que miré contenía HTML válido con CSS fresquito y si tiene flatas de ortografía ha sido sin querer.

borrame.com es el sitio anteriormente conocido como bits.demogracia.com (no confundir con Demogracia, que sólo pasaba por ahí).

© 2005-2010 by Álvaro G. Vicario (alvaro.es) • Burgos (España) • borrame.com