28 sept 2016

Calcular un hash MD5 y devolverlo en formato leíble

El uso de hashes es bastante común en programación, se puede utilizar para guardar una contraseña, (en este caso ya no es recomendable recurrir al MD5), se puede usar para guardar una cadena de verificación o firma e incluso para comparar archivos.

El framework .Net nos presenta una gran variedad de herramientas para calcular un hash, en este caso usaremos la clase MD5CryptoServiceProvider del namespace using System.Security.Cryptography.

Una duda que muchas veces aparece al intentar usar estos CryptoServiceProviders es cómo mostrar el hash para que sea leíble, ya que la función que utilizamos nos devuelveun Array de bytes.

Pues eso es sencillo, recurrimos a la función ToString() y como argumento pasamos "x2" con lo que por cada ítem del array obtendremos un valor hexadecimal de 2 dígitos.

Entonces la función se vería así:

public string MD5Hash(string texto)
{
 var resultado = new StringBuilder();
 using (var md5 = new MD5CryptoServiceProvider())
 {
  var hash = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(texto);
  foreach (byte b in hash)
  {
   resultado.Append(b.ToString("x2"));
  }
 }
 return resultado.ToString();
}

2 jun 2016

Password prompt en aplicación de consola de .Net

Muchas veces utilizo aplicaciones de consola, principalmente cuando desarrollo un cliente para alguna API y necesito crear una aplicación de test para mi librería... pero algo que siempre me molestó es no poder enmascarar el password mientras se lo ingresa en la consola... así fue que un día decidí investigar y me encontré con una solución que tenía algunas fallas y le faltaba trabajo... pero recuerdo que lo tomé como base y luego de una buena edición lo uso en todos mis proyectos de aplicación de consola en los que se ingresa un password.

Creo que una de las formas más seguras de enmascarar un password es el que se usa en GNU/Linux, no mostrar nada al ingresar el password, de esa forma no sólo se ocultan los caracteres que conforman el password, pero también se oculta el largo de la cadena, pero hay quienes prefieren ver un asterisco por cada caracter, así que eso es configurable.



Veamos la función que lee y devuelve el password:

static string LeerPassword()
{
    // Caracter a mostrar en pantalla 
    const string mascara = "*";

    ConsoleKeyInfo key;
    var passwd = string.Empty;
    do
    {
        // Leer una tecla a la vez
        key = Console.ReadKey(true);

        if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter)
        {
            // Agrego el caracter a la cadena
            passwd += key.KeyChar;
            Console.Write(mascara);
        }
        else if (key.Key == ConsoleKey.Backspace)
        {
            if (mascara.Length > 0)
            {
                // Si la máscara se imprime hay que borrarla
                Console.Write("\b \b");
            }
            if (!string.IsNullOrEmpty(passwd))
            {
                // Quitar el último caracter de la cadena
                passwd = passwd.Substring(0, passwd.Length - 1);
            }
        }
    }
    while (key.Key != ConsoleKey.Enter);

    return passwd;
}


Con esta simple función ya tenemos esta funcionalidad implementada, resta invocarla desde el punto donde queremos leer el password y listo!

static void Main(string[] args)
{
    Console.Clear();

    Console.WriteLine("Aprendiendo.Net - Enmascarar password");
    Console.WriteLine();
    Console.Write("Usuario: ");
    var usuario = Console.ReadLine();
    Console.Write("Password: ");
    var passwd = LeerPassword();

    /*
     * Validación y resto del código
     */

    Console.ReadLine();
}


Modificando el valor de la constante mascara en nuestra función LeerCodigo() podremos variar el caracter que se mostrará en pantalla al ingresar el password, incluso podemos usar un string vacío para lograr el efecto que nombraba respecto a las aplicaciones en GNU/Linux.

4 ago 2015

Entendiendo la estructura TimeSpan en C#

Una instancia de la estructura TimeSpan representa un periodo de tiempo pero también nos brinda una serie de propiedades y métodos útiles.

Para crear una instancia de TimeSpan tenemos varios constructores, por lo que deberemos buscar el más adecuado a nuestra necesidad.... podemos crear un TimeSpan a partir de ticks, o usando el constructor que más parámetros acepta, podemos crearlo a partir de un número de días, horas, minutos, segundos y milisegundos.

Otra forma de inicializar un TimeSpan es a partir se alguno de sus métodos estáticos cuyo nombre comienza con From, (Desde o A partir de en inglés), entonces podríamos inicializar untimeSpan a partir de un número de minutos usando TimeSpan.FromMinutes(double).

También podemos sumar y restar instancias de TimeSpan, pero como cada instancia es inmutable, el resultado de la operación lo asignaremos a otra variable.

Para realizar estas operaciones recurriremos al los métodos de instancia Add y Subtract los cuales aceptan un único parámetro de tipo TimeSpan, vamos un ejemplo de cada operación:

TimeSpan periodo1 = TimeSpan.FromHours(1);
TimeSpan periodo2 = TimeSpan.FromHours(3);

TimeSpan suma = periodo1.Add(periodo2); // suma representa un TimeSpan de 4 horas: 1 + 3

TimeSpan resta = periodo2.Subtract(periodo1); // resta representa un TimeSpan de 2 horas, 3 - 1



Algunas propiedades de TimeSpan son tan importantes como útiles a la hora de trabajar con intervalos de tiempo, me refiero a las propiedades que nos devuelven el valor de ese intervalo en cierta unidad, por ejemplo la cantidad de segundos totales correspondientes a ese periodo.
Estas propiedades son nombradas como TotalUnidadDeTiempo, por ejemplo TotalSeconds o TotalMinutes, veamos un ejemplo:

TimeSpan foo = TimeStamp.FromMinutes(2);
Console.WriteLine(foo.TotalSeconds.ToString()); // Se imprimirá 120



No debemos confundir estas propiedades con las que sólo reciben el nombre de la unidad de tiempo a la que representan, por ejemplo Hours o MilliSeconds, ya que éstas representan el valor de esa unidad, no la representación total del periodo en esa unidad.

Por ejemplo:

TimeSpan foo = TimeStamp.FromSeconds(70);
Console.WriteLine(foo.TotalSeconds.ToString()); // Se imprimirá 70
Console.WriteLine(foo.Seconds.ToString()); // Se imprimirá 10, ya que el TimeSpan representa un periodo de 1 minuto y 10 segundos



7 abr 2015

Convertir Ticks en Fecha y viceversa

Hoy quisiera publicar un tip que es prácticamente tonto, pero dado que he recibido la consulta y la solución puede no resultar de lo más intuitiva, aquí dejo una función para convertir Ticks en Fecha y Fecha en Ticks.


Antes que nada, qué son Ticks?

Un tick es el mínimo valor que representa un paso, equivalente a 100 nanosegundos, o sea en un mili segundo hay 10.000 ticks.



Public Function TicksToDateTime(ticks As Long) As DateTime
   ' Intuitivo sería tener una función DateTime.FromTicks(Long)
   Return New DateTime(ticks) 
End Function

Public Function DateTimeToTicks(date As DateTime) As Long
   Return date.Ticks
End Function


Como había anticipado, la solución es muy tonta!

En cuanto a tener una forma más intuitiva, podríamos crear un Método de Extensión, (Extension Method), que afecte la clase DateTime, de esa manera tener DateTime.FromTicks(Long).


19 nov 2013

Trace, la herramienta versátil para crear logs

Algo que siempre necesitamos es llevar líneas de log para saber qué está ocurriendo con nuestras aplicaciones y esto se vuelve prácticamente indispensable al trabajar con Windows Services o Servicios de Windows ya que al no tener UI se hace muy difícil saber qué ocurre...

Afortunadamente encontramos la clase Trace en el namespace System.Diagnostics, la cual nos permite de manera muy sencilla ir dejando líneas de log en nuestro código, veamos un ejemplo simple:


   Public Sub New()
      System.Diagnostics.Trace.WriteLine("Inicio de constructor")
      ' Proceso de datos
      System.Diagnostics.Trace.WriteLine("Fin de constructor")
   End Sub

Entonces para el propósito de este post lo que nos interesa es básicamente la capacidad de escribir de esta clase, para lo cual utilizaremos 2 métodos: Write() y WriteLine() cuya principal diferencia, como lo indica su nombre, es que uno escribe y el otro escribe y termina la línea.

Entonces ya sabemos como utilizar esta herramienta para escribir líneas de log, nos resta leer nuestro log, para lo cual Visual Studio cuenta con una ventana llamada Output o Salida (CTRL + W + O) en la cual se van imprimiendo las líneas de nuestro log... impecable si estamos trabajando en nuestro entorno de desarrollo, pero si debemos leer nuestro log desde una aplicación ya compilada (en modo Debug) podemos utilizar la herramienta Debug View que nos permite tener una ventana con nuestro log en la cual podremos usar filtros, resaltado de colores, etc.