jueves, 14 de enero de 2016

Calculadora IP





Hola a tod@s


Aquí os muestro una pequeña calculadora de direcciones IP desarrollada en WPF y C# .NET 4.5 y con la que vemos una pequeña demostración de una clase y su funcionamiento.



El funcionamiento de la app es muy fácil, cuadros de texto para la IP y cuadro de texto para la máscara de subred  con notación CIDR que quiere decir que el número introducido, indica el número de bits a 1 de la máscara de subred, es decir si introduzco 28, quiere decir que la máscara tiene 28 bit a 1, lo que sería:
11111111  11111111  11111111  11110000

el equivalente a 255.255.255.240.

A continuación adjunto la clase la cual no tiene ningún misterio (no he sido muy exquisito en cuanto a código, pero para aprender creo que está bien), propiedades públicas con los resultados y los métodos que si detallo:

 

Métodos públicos
  • SetNetAddress. Asigna la dirección de red
  • SetBroadCast. Asigna el Broadcast
  • SetIPt. Asigna la dirección ip
  • SetNetType. Asigna el tipo de red (A,B,C,D o E)
  • SetHostMin.Asigna a la propiedad el valor de host mínimo de la red
  • SetHostMax. Asigna a la propiedad el valor máximo de la red
  • GetIPToString. Obtiene la IP como un valor de cadena de la forma XXX.XXX.XXX.XXX
  • GetIPBinaryToString. Obtiene la IP como un valor de cadena en binario.
Métodos privados
  • NotifyPropertyChanged. Método delegado del evento cuando no es válida la IP. De esta manera, desde la clase donde instancio esta, puedo capturar si la IP no es válida e indicarlo.
  • BinaryToDecimal. Método sobrecargado para convertir números o direcciones ip de binario a decimal.
  • DecimalToBinary. Método sobrecargado para convertir números o direcciones ip de decimal a binario.
  • OperationOR. Operador OR sobre la dirección IP para obtener la máscara de entrada
  • OperationAND. Operador AND sobre la la dirección IP para obtener el broadcast
  • OperationNOT. Operador NOT sobre la la dirección IP para obtener el broadcast junto con el operador AND.
  • ValidateIP. Valida la IP, comprobando que sus valores son correctos y está bien formada.
Nota: Recordad que para obtener la dirección del red, se realiza la operación AND entre la IP y la máscara de subred y que para obtener el broadcast, se utiliza el operador OR entre la IP y la NOT de la máscara de subred (donde hay ceros, cambio a unos y viceversa).



OPERADOR AND
a
b
RESULTADO(Q)
0
0
0
0
1
0
1
0
0
1
1
1




OPERADOR OR
a
b
RESULTADO(Q)
0
0
1
0
1
1
1
0
1
1
1
0



OPERADOR NOT
a
RESULTADO(Q)
0
0
0
0


 Si alguno ha dado el algebra de Boole, recordáis que a AND b= NOT (a OR b)?
solo hay que mirar la tabla AND y la OR, donde hay un 1 en la otra hay un 0!

y por último el símbolo de estos operadores (y de alguno más) es:
(una puerta NOR es una OR con una NOT, que es la que usamos para obtener el broadcast)

 

Para descargar la calculadora IP, pulsar aquí

Espero que os sirva y adjunto el código de la clase principal.
/* ************************************************************************************************************************************************
* © JOAQUIN MARTINEZ RUS 2015
* PROYECTO:         IpAddress Calculator
* Nombre:           AndrewWiles
* Archivo:          IpAddress.cs
* Descripción:      Clase principal
* Historial:
*                   1. Joaquin Martínez Rus - 13 ene 2016. Creación
*
* Comentarios:      Calculador de redes
*
*
**************************************************************************************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.ComponentModel;

namespace AndrewWiles
{
    public class IpAddress:INotifyPropertyChanged
    {
        public IpAddress()
        {
            CreateArrays();
            this.IP = "0.0.0.0";
            
        }

        public IpAddress(string ip)
        {
            CreateArrays();
            this.IP = ip;
            
        }

        #region Propiedades, eventos

        public event PropertyChangedEventHandler PropertyChanged;

        private string _ip;

        public string IP
        {
            get { return _ip; }
            set 
            {
                _ip = value;

                IsValidIP = this.ValidateIP();

                if (IsValidIP)
                {
                    ipNumbers = _ip.Split('.');

                    for (int i = 0; i < ipNumbers.Length; i++)
                    {
                        ipNumbersByte[i] = DecimalToBinary(ipNumbers[i]);
                    }
                }
            }
        }
        public string[] ipNumbers { get; set; }
        public string[] ipNumbersByte { get; set; }
        public string[] NetWorkAddress { get; set; }
        public string[] Broadcast { get; set; }
        public string[] NetMask { get; set; }
        public string[] HostMin { get; set; }
        public string[] HostMax { get; set; }

        public string IpClass { get; set; }
        public string NetID { get; set; }
        public string HostID { get; set; }
        public int Hosts { get; set; }

        private int netMaskCIDR;

        public int NetMaskCIDR
        {
            get { return netMaskCIDR; }
            set
            {
                netMaskCIDR = value;
                this.ConvertCIDRToNetMask();
            }
        }


        private bool isValidIP;

        public bool IsValidIP
        {
            get { return isValidIP; }
            set
            {
                isValidIP = value;
                NotifyPropertyChanged("ValidIP");
            }
        }
        
        #endregion

        #region Métodos públicos

        public void SetNetAddress()
        {
            this.NetWorkAddress = this.OperationAND(this.ipNumbers, this.NetMask);
        }

        public void SetBroadCast()
        {
            this.Broadcast= this.OperationOR(this.ipNumbers, this.OperationNOT(this.NetMask));
        }

        public void SetIP(string ip)
        {
            this.IP = ip;
        }

        public void SetNetType()
        {
            if (ipNumbersByte[0].Substring(0,1)=="0")
            {
                this.IpClass = "A";
            }
            if (ipNumbersByte[0].Substring(0, 2) == "10")
            {
                this.IpClass = "B";
            }
            if (ipNumbersByte[0].Substring(0, 3) == "110")
            {
                this.IpClass = "C";
            }
            if (ipNumbersByte[0].Substring(0, 4) == "1110")
            {
                this.IpClass = "D";
            }
            if (ipNumbersByte[0].Substring(0, 4) == "1111")
            {
                this.IpClass = "E";
            }

        }

        public void SetHostMin()
        {
            this.NetWorkAddress.CopyTo(this.HostMin,0);
            this.HostMin[3]= (Convert.ToInt16(this.HostMin[3]) + 1).ToString();
        }

        public void SetHostMax()
        {
            this.Broadcast.CopyTo(this.HostMax, 0);
            this.HostMax[3] = (Convert.ToInt16(this.HostMax[3]) - 1).ToString();
        }
        
        public string GetIPToString(string [] ip)
        {
            string ipToString = "";

            foreach (var item in ip)
         {
                ipToString += item + ".";
         }

            return ipToString.Substring(0, ipToString.Length - 1);
        }

        public string GetIPBinaryToString(string[] ip)
        {
            string ipToString = "";

            foreach (var item in ip)
            {
                ipToString += this.DecimalToBinary(item) + "  ";
            }

            return ipToString.Substring(0, ipToString.Length - 1);
        }

        #endregion

        #region Métodos privados

        #region Métodos de Eventos
        
        private void NotifyPropertyChanged(string property)
        {
            var handler = this.PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(property));
            }
        }

        #endregion

        #region Operaciones Binarias

        private string[] BinaryToDecimal(string[] aByte)
        {
            string[] bytes = new string[4];

            for (int i = 0; i < aByte.Length; i++)
            {
                bytes[i] = BinaryToDecimal(aByte[i]);
            }

            return bytes;
        }

        private string BinaryToDecimal(string aByte)
        {
            double aux = 0;

            for (int i = 0; i < aByte.Length; i++)
            {
                double potencia = Math.Pow(2, i);
                double digito=Convert.ToInt16(aByte.Substring(aByte.Length-1-i,1));
                aux += (potencia * digito);
            }

            return aux.ToString();
        }

        private string[] DecimalToBinary(string[] aByte)
        {
            string[] bytes = new string[4];

            for (int i = 0; i < aByte.Length; i++)
            {
                bytes[i] = DecimalToBinary(aByte[i]);
            }

            return bytes;
        }

        private string DecimalToBinary(string aByte)
        {
            int entero=Convert.ToInt32(aByte);
            return Convert.ToString(entero,2).PadLeft(8,'0');
        }

        public string[] OperationOR(string[] ip1, string[] ip2)
        {
            string[] CalculoOR = new string[4];

            for (int i = 0; i < ip1.Length; i++)
            {
                int a= Convert.ToInt32(ip1[i]);
                int b= Convert.ToInt32(ip2[i]);
                string o = (a | b).ToString();
                CalculoOR[i] = o;
            }

            return CalculoOR;
        }

        public string[] OperationAND(string[] ip1, string[] ip2)
        {
            string[] CalculoAND = new string[4];

            for (int i = 0; i < ip1.Length; i++)
            {
                int a = Convert.ToInt32(ip1[i]);
                int b = Convert.ToInt32(ip2[i]);
                string o = (a & b).ToString();
                CalculoAND[i] = o;
            }

            return CalculoAND;
        }

        public string[] OperationNOT(string[] ip)
        {
            string[] CalculoNOT = new string[4];

            for (int i = 0; i < ip.Length; i++)
            {
                string number = this.DecimalToBinary(ip[i]);

                string notNumber = "";

                foreach (var item in number)
                {
                    notNumber += item == '0' ? '1' : '0';
                }

                CalculoNOT[i] = this.BinaryToDecimal(notNumber);
            }

            return CalculoNOT;
        }

        #endregion

        #region Cálculos con Direcciones

        private void ConvertCIDRToNetMask()
        {
            string unos = "";
            string ceros = "";
            int resto = 32 - this.NetMaskCIDR;
            string netmaskTemporal = unos.PadRight(this.NetMaskCIDR, '1') + ceros.PadRight(resto, '0');
            string a = netmaskTemporal.Substring(0, 8);
            string b = netmaskTemporal.Substring(8, 8);
            string c = netmaskTemporal.Substring(16, 8);
            string d = netmaskTemporal.Substring(24, 8);

            this.NetMask[0] = BinaryToDecimal(a);
            this.NetMask[1] = BinaryToDecimal(b);
            this.NetMask[2] = BinaryToDecimal(c);
            this.NetMask[3] = BinaryToDecimal(d);

            this.Hosts = (int)Math.Pow(2, resto) - 2;
        }

        #endregion

        #region Validaciones

        private bool ValidateIP()
        {
            return ValidateIP(this.IP);
        }

        private bool ValidateIP(string ip)
        {
            bool isValid = false;

            Regex regexip = new Regex(@"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b");
            MatchCollection result = regexip.Matches(ip);

            if (result.Count > 0)
            {
                isValid = true;
            }
            else
            {
                isValid = false;
            }

            return isValid;
        }

        #endregion

        #region Genéricas
        
        private void CreateArrays()
        {
            ipNumbers = new string[4];
            ipNumbersByte = new string[4];
            NetWorkAddress = new string[4];
            Broadcast = new string[4];
            NetMask = new string[4];
            HostMin = new string[4];
            HostMax = new string[4];
        }

        #endregion
        
        #endregion
    }

    public class IPData
    {
        public IPData(string texto, string data, string binary)
        {
            this.Texto = texto;
            this.Data = data;
            this.Binary = binary;
        }

        public string Texto { get; set; }
        public string Data { get; set; }
        public string Binary { get; set; }

    }
}

Saludos

2 comentarios:

  1. hola amigo una pregunta yo necesito hacer este proyecto en visual basic 2012 para la universidad usted me podría facilitar el código fuente???? te lo agrade seria con el alma amigo

    ResponderEliminar
  2. Hola Sarcas, el proyecto está desarrollado en WPF, con VS2013 y .NET 4.5 con una sola clase y sin ninguna complicación. Te adjunto el código en un enlace. Un saludo

    https://drive.google.com/open?id=0B0VEoGgb5cVcWHJlX28zNElKY2M

    ResponderEliminar