Resulta que, para mi proyecto terminal me vi en la necesidad de verificar que una dirección IP sea una dirección local válida, como todo buen "huevón" me puse a googlear a ver si había algo hecho por ahí, escudándome en aquella muy frecuente (güacala) frase de "reinventar la rueda" no quería hacerlo por mi mismo (aparte de que tenía mucha flojera). A fin de cuentas, no encontré nada decente digno de agregarse a mi ya muy ofuscado código y me decidí a hacerlo, después de todo sólo necesitaba hacer uso de expresiones regulares, un lápiz y un papel.
Bueno, depués de este choro que seguro nadie leerá y no se porque escribí, muestro como lo hice:
Basados en el RFC 1918, una dirección IP privada puede pertenecer a cualquiera de los siguientes tres rangos de direcciones:
o bien:
10.0.0.0 - 10.255.255.255
172.16.0.0 - 172.31.255.255
192.168.0.0 - 192.168.255.255
A primera vista pareciera que es no es tan complicado hacerlo, pero el problema no es tan trivial (tampoco es difícil ¬¬); por ejemplo: ¿Cómo saber si un número está entre 0 y 255?. La respuesta puede ser algo similar a lo siguiente:
172.16/12
192.168/16
10/8
Números de un dígito:
- Se permiten números en el rango [0-9].
- No pueden comenzar con 0, esto porque no se permiten números como 01, 02, 001, 010, etc.
- Se permite cualquier número que comience con un dígito en el rango [1-9] y siga de un número en el rango [0-9].
- Si comienza con 1 puede seguir de 2 dígitos en el rango [0-9], es decir, se permiten números como 100, 101, 150, 199, etc.
- Si comienza con 2:
- Si después hay un número en el rango [0-4], enseguida puede haber un número en el rango [0-9], es decir, se permiten números en el rango [200-249].
- Si después hay un 5, sólo se permiten números en el rango [0-6], es decir, los entre [250-255].
Números de un dígito:
Números de dos dígitos:
[0-9]
Números de tres dígitos:
[1-9][0-9]
entonces, la expresion regular para validar un número entero en el rango [0-255] es la union de los tres conjuntos de números anteriores:
1[0-9][0-9]
2([0-4][0-9]|5[0-5])
podemos factorizar la expresion anterior, nótese que:
[0-9] | [1-9][0-9] | 1[0-9][0-9] | 2([0-4][0-9] | 5[0-5])
es lo mismo que:
[0-9] | [1-9][0-9]
? es un operador que indica que puede haber uno o ningún dígito en el rango [1-9]
[1-9]?[0-9]
factorizamos:
para evitar cualquier confusión, separamos cada término usando paréntesis:
[0-9] | [1-9][0-9] | 1[0-9][0-9] | 2([0-4][0-9] | 5[0-5])
[1-9]?[0-9] | 1[0-9][0-9] | 2([0-4][0-9] | 5[0-5])
[1-9]?[0-9] | 1[0-9]{2} | 2([0-4][0-9] | 5[0-5])
ahora bien, en java la siguiente expresión valida expresiones en el rango [.0-.255] (se agrega el punto antes de los dígitos):
([1-9]?[0-9]) | (1[0-9]{2}) | (2([0-4][0-9] | 5[0-5]))
"\\.(([1-9]?[0-9])|(1[0-9]{2})|(2([0-4][0-9]|5[0-5])))"
siguiendo los mismos conceptos, el siguiente método escrito en Java valida si una dirección IP es una dirección privada válida:
/**
* Verifica que la dirección IP es una dirección privada válida.
*
* @param ip Cadena de texto con la dirección que se quiere validar.
* @return true si es una dirección válida, false en otro caso.
*/
private bool verificaHost(String ip)
{
/* patrón para los números de .0 a .255 */
String n = "\\.(([1-9]?[0-9])|(1[0-9]{2})|(2([0-4][0-9]|5[0-5])))";
/* patrón para los números de .16 a .31 */
String m = "\\.((1[6-9])|(2[0-9])|(3[01]))";
/* 192.168.0.0 a 192.168.255.255 */
if(ip.matches("^192\\.168(" + n + "){2}$"))
return true;
/* 10.0.0.0 a 10.255.255.255 */
else if(ip.matches("^10(" + n + "){3}$"))
return true;
/* 172.16.0.0 a 172.31.255.255 */
else if(ip.matches("^172" + m + "(" + n + "){2}$"))
return true;
/* la dirección no coincidió con ninguna de las anteriores */
return false;
}
6 comentarios:
te odio cagado :D
eres un chingón
Gracias por tu aporte
Excelente aporte muy bueno
No podía ser mejor! Es el primer post realmente útil :D Buena suerte!
Muy útil!!! Gracias!!
No está mal pero mi inexperiencia me dice que eso es una flipada...jeje
para los novatos como yo esto quizá se entienda mejor:
básicamente miro el número de dígitos de cada número de la ip
ej.(10.223.45.123), después de hacer el split cada número irá en un registro de aux y ahí con que se comprenda en los números deseados y no empiece por 0(lo miro con el substring) creo que ya es suficiente.
Aquí mi código:
String[] aux =FTP_HOST.split(Pattern.quote(".")); for(int i=0;aux.length>i;i++){
if(aux[i].length()==0){
logger.error("The data entered in FTP HOST is incorrect");
return null;
}else if(aux[i].length()==1){
if(Integer.valueOf(aux[i])<0 || Integer.valueOf(aux[0])>9){
logger.error("The data entered in FTP HOST is incorrect");
return null;
}
}else if(aux[i].length()==2){
if(Integer.valueOf(aux[i])<0 || Integer.valueOf(aux[i])>99 || Integer.valueOf(aux[i].substring(0,1))==0){
logger.error("The data entered in FTP HOST is incorrect");
return null;
}
}else if(aux[i].length()==3){
if(Integer.valueOf(aux[i])<0 || Integer.valueOf(aux[i])>255 || Integer.valueOf(aux[i].substring(0,1))==0){
logger.error("The data entered in FTP HOST is incorrect");
return null;
}
}
}
Publicar un comentario