Archive for agosto, 2012

Android: Hash calculator

Para seguir con la temática de moda, y después de leer por ahí que me pico por estar en el lado de la luz… voy a poner en práctica, con un ejemplo de calculadora de hash, lo tratado en post anteriores.

Yo trabajo con eclipse pero voy a intentar poner las explicaciones sin entrar en el detalle de las acciones del entorno de trabajo que yo utilizo.

Creamos un proyecto nuevo de Android y creamos en el layout principal los objetos tal que la imagen siguiente o como nos resulte más usable.

Hash Calculator

Hash Calculator

Lo más relevante del archivo main.xml son los nombres de los campos:

[…]
    <EditText
        android:id="@+id/editTextString"
        android:inputType="text" >
[…]
        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/buttonCalculate"
[…]
        android:onClick="calculateHash"
        android:text="@string/buttonCalculate" />
[…]

Al botón le indicamos qué debe de hacer en la acción onClick, en este caso calculateHash.

5 TextView con los nombres siguientes:

            android:id="@+id/textViewMD5Hash"
            android:id="@+id/textViewSHA1Hash"
            android:id="@+id/textViewSHA256Hash"
            android:id="@+id/textViewSHA384Hash"
            android:id="@+id/textViewSHA512Hash"
Nota: los nombres, textos y demás están en inglés por la costumbre de programar en inglés.

 

Veamos como ha quedado nuestra clase encrypt después de arreglarla un poco para poder usarla en una App.

import java.security.MessageDigest;
import android.text.Editable;
public class encrypt {
      public static String hashStr(Editable str, String type) throws Exception {
            String result = "Impossible!";
            if (type == "MD5" || type == "SHA-1" || type == "SHA-256" || type == "SHA-384" || type == "SHA-512" ) {
                        MessageDigest md = MessageDigest.getInstance(type);
                        md.update(str.toString().getBytes());
                        StringBuilder sb = new StringBuilder();
                        for (byte b : md.digest())
                             sb.append(Integer.toHexString(0x100 + (b & 0xff)).substring(1));
                        result = sb.toString();
            };          
            return      result;    
      }
}

Hemos puesto un control para que el tipo de Hash corresponda con lo que podemos hacer.

La Activity de la App tiene el siguiente método para crearse, donde tomamos los campos del layout que van a interactuar de forma activa.

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        stringValue=(EditText)findViewById(R.id.editTextString);
        tvMd5Hash=(TextView)findViewById(R.id.textViewMD5Hash);
        tvSha1Hash=(TextView)findViewById(R.id.textViewSHA1Hash);
        tvSha256Hash=(TextView)findViewById(R.id.textViewSHA256Hash);
        tvSha384Hash=(TextView)findViewById(R.id.textViewSHA384Hash);
        tvSha512Hash=(TextView)findViewById(R.id.textViewSHA512Hash); 
    }

Como hemos comentado, el botón genera una acción onClick que llama al siguiente método:

    public void calculateHash(View view) throws Exception {
      Editable str = stringValue.getText();
      if ( str.toString() == "" ) {
            // do nothing or show a Toast message
      }else {
            tvMd5Hash.setText(encrypt.hashStr(str, "MD5"));
            tvSha1Hash.setText(encrypt.hashStr(str, "SHA-1"));
            tvSha256Hash.setText(encrypt.hashStr(str, "SHA-256"));
            tvSha384Hash.setText(encrypt.hashStr(str, "SHA-384"));
            tvSha512Hash.setText(encrypt.hashStr(str, "SHA-512"));
      }
    }

El resultado de la ejecución de la App es el siguiente:

Hash Calculator Result

Hash Calculator Result

Debido a que el resultado no se veía completo puse el contenido en un Scrollview.

Podeis encontrar el ejemplo  completo aquí: https://github.com/davidrojasdominguez/hash-calculator.git

 

Share

Java: Calcular hash

Como ya nos instruyó Josep Rivas en un post anterior Generación de Hashes en Objective-C, el concepto de Hash debe de usarse para comprobaciones y no para almacenar datos por los motivos que ya se mencionaron.

Tanto como si queremos usar un hash para comprobar como para almacenar datos, en Java lo podemos hacer utilizando lo que se conoce como Clases Motor, como por ejemplo la clase MessageDigest. Las clases motor en criptografía Java se deben al concepto de Independencia y extensibilidad de los algoritmos (uno de los 2 conceptos básicos en que se basa la Arquitectura Criptográfica de Java (JCA), más información aquí). Esto significa que JCA nos ofrece unas clases que proporcionan la funcionalidad de servicios criptográficos.

En resumen, Java no proporciona las funciones MD5 o SHA-256 de forma directa (como lo hace php por ejemplo), sino que hay que tomar una clase que ofrece servicios e implementar las funciones o métodos usando los servicios de encriptación que nos ofrece esa clase.

Vemos un ejemplo para aclarar estos conceptos. Tomaremos como clase motor la clase MessageDigest. Crearemos una clase “encrypt” en la que implementaremos nuestros métodos de hash. Luego esta clase la podremos usar en nuestros proyectos Java, Android, etc. Para empezar crearemos un método para calcular el Hash de una cadena en MD5.

/** Import MessageDigest Motor Class **/
import java.security.MessageDigest;
public class encrypt {
/**
 * Public Method md5Str
 * ARG: String
 * RETURN: Hash of String
 */
      public static String md5Str(String str) throws Exception
      {
            // Create a MessageDigest with MD5 criptographic services
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            // Load values to MessageDigest
            md5.update(str.getBytes());           
            // Get Encrypted value and show it in hexadecimal
            StringBuilder sb = new StringBuilder();
            for (byte b : md5.digest())
                  sb.append(Integer.toHexString(0x100 + (b & 0xff)).substring(1));
            return sb.toString();       
      }
 }

Obtenemos de la cadena “Hello World” el siguiente hash MD5: b10a8db164e0754105b7a99be72e3fe5

La JCA permite los siguientes algoritmos en sus clases motor

  • MD2
  • MD5
  • SHA-1
  • SHA-256
  • SHA-384
  • SHA-512

Por lo tanto, rápidamente pasando un parámetro más a nuestra método, podemos obtener un método que nos muestre el hash de una cadena en función del algoritmo deseado:

      public static String hashStr(String str, String type) throws Exception
      {
            MessageDigest md= MessageDigest.getInstance(type);
            md.update(str.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : md.digest())
                  sb.append(Integer.toHexString(0x100 + (b & 0xff)).substring(1));
            return sb.toString();       
      }

IMPORTANTE: Hay que afinar el método para verificar que los valores de type son los esperados y no generemos errores o excepciones inesperadas.

Estos son los HASH generados con este último método para la cadena “Hello World”

  • encrypt.hashStr(“Hello World”, “MD2″));

MD2: 27454d000b8f9aaa97da6de8b394d986

  • encrypt.hashStr(“Hello World”, “MD5″));

MD5: b10a8db164e0754105b7a99be72e3fe5

  • encrypt.hashStr(“Hello World”, “SHA-1″));

SHA-1: 0a4d55a8d778e5022fab701977c5d840bbc486d0

  • encrypt.hashStr(“Hello World”, “SHA-256″));

SHA-256: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

  • encrypt.hashStr(“Hello World”, “SHA-384″));

SHA-384: 99514329186b2f6ae4a1329e7ee6c610a729636335174ac6b740f9028396fcc803d0e93863a7c3d90f86beee782f4f3f

  • encrypt.hashStr(“Hello World”, “SHA-512″));

SHA-512: 2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b

Podeis comprobar los valores aquí.

Espero que esto nos ayude un poco más en el mundo de la encriptación.

Share

Android: Class Activity

Después de hablar con unos colegas de varios temas e intentar explicar como funcionan las aplicaciones se me ocurrió dedicarle un tiempo a reordenar todos esos conceptos que uno va adquiriendo. De la misma forma que en el trabajo documentamos todo aquello que hacemos, también lo deberiamos de hacer cuando son cosas para uno mismo. Siempre puedes necesitarlo o como mínimo compartirlo. Para empezar por el principio trataré de resumir la clase Activity.

Class Activity

Una Activity es un componente de aplicación que ofrece una pantalla con la que los usuarios pueden interactuar con el fin de hacer algo. A cada actividad se le da una ventana en la que se puede dibujar una interfaz de usuario. Por lo general la Activity llena la pantalla, pero puede ser menor que la pantalla y quedar flotando por encima de otras ventanas o aplicaciones.

Una aplicación generalmente se compone de varias actividades que están enlazadas entre sí. Siempre hay que definir una Activity como la principal y a partir de aquí crear las actividades necesarias para la navegación por la aplicación.

La navegación se realiza utilizando un sistema de “Pila” llamado Back Stack (Pila de Retorno). La primera Activity de la Pila es la que se define como la principal. Al pasar a una nueva Activity, la anterior pasa a un estado de suspensión y se coloca la nueva en la Pila. La pila funciona con la modalidad LIFO (Last In First Out). Al presionar el botón Atrás, la Activity actual se destruye y se reactiva la Activity que está encima de la pila.

Existen diferentes sub clases de Activities:

-       AccountAuthenticatorActivity: Clase base para la implementación de una actividad que se utiliza para ayudar a implementar un AbstractAccountAuthenticator.

-       ActivityGroup: Clase que crea una Activity que contiene y ejecuta múltiples actividades integradas.

-       AliasActivity: Clase que crea una Activity que permite lanzar otra actividad y luego se destruye en lugar de quedarse en la Pila. Es una manera senzilla de implementar un mecanismo de alias.

-       BasicDream: Clase que se utiliza para implementar Dreams

-       ExpandableListActivity: Clase que crea una Activity que permite mostrar una lista extensible (ExpandableListView).

-       FragmentActivity: Clase de Activity para utilizar con las APIs Fragment y Loader.

-       ListActivity: Clase que crea una Activity para mostrar una lista de elementos des de un origen de datos (ListView, etc).

-       NativeActivity: Este tipo de Activity se utiliza para utilizar exclusivamente código nativo. Por ejemplo para crear juegos y cosas similares.

Estas otras sub clases indirectas:

-       LauncherActivity (Sub clase de ListActivity): Muestra una lista de todas las actividades que se pueden realizar para un propósito determinado.

-       PreferenceActivity (Sub clase de ListActivity): Esta clase se usa para mostrar un Activity con la jerarquía de preferencias del usuario.

-       TabActivity (Sub clase de ActivityGroup): Esta clase está obsoleta.

 

Share

Vb.net: AutoComplete

Una de las cosas que más quebraderos de cabeza nos puede llegar a dar es la forma en que los usuarios introducen los datos, ya que para una misma referencia podemos llegar a tener variaciones que a la hora de extraer los datos. Por ejemplo, no será lo mismo entrar nombre-apellido que nombre_apellido.

¿Qué podemos hacer? Limitar la imaginación de los usuarios o sugerirles la forma correcta de hacerlo. Una buena manera es utilizar los Auto Complete, que nos permiten sugerir a los usuarios contenido ya entrado que puede corresponder con lo que quieren introducir.

Aquí tenemos un ejemplo para cargar unos datos des de una base de datos.

 DBConnection = New OleDbConnection(DBCONNECTION_STR)
 DBConnection.Open()
 DBCommand = DBConnection.CreateCommand()
 DBCommand.CommandText = SQL_SELECT_STR
 DBCommand.Connection = DBConnection
 DBDataReader = DBCommand.ExecuteReader()
 ' Cargamos los valores
 While (DBDataReader.Read())
    TextBox.AutoCompleteCustomSource.Add(DBDataReader(0)) ' En este caso los datos de la primera columna del resultado devuelto
 End While
 DBConnection.Close()

En el objeto TextBox hay que modificar las propiedades

AutoCompleteMode con el valor Suggest, Append o SuggestAppend (Sugerir, Añadir o Sugerir+Añadir)

AutoCompleteSource con el valor CustomSource, para este caso. Existen otros tipos de fuente para rellenar la colección de auto completado.

Si los valores que queremos poner como sugerencias de AutoComplete los vamos a utilizar en más de un objeto, podemos utilizar una variable de tipo AutoCompleteStringCollection.

Dim stringCollection As New AutoCompleteStringCollection

Cargamos los valores en la colección

While city_reader.Read()
     stringCollection .AddRange(New String() {DBDataReader(0)})
End While

Cargamos la colección en los diferentes objetos en los que queremos sugerir contenido.

TextBox1.AutoCompleteCustomSource = stringCollection 
TextBox2.AutoCompleteCustomSource = stringCollection

 

 

Share