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