miércoles, 15 de julio de 2015

Receta C# No. 5-11: Cómo Comparar Dos Archivos

Índice

0. Introducción
1. Problema
2. Solución
3. Discusión de la Solución
3.1 Algoritmo hash
3.2 Clase HashAlgorithm
3.2.1 Método Create
3.2.2 Método ComputeHash
4. Práctica: Código C#
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

Comparar dos archivos en determinación de su igualdad es una de las tareas más comunes en la manipulación de archivos. Existen distintas técnicas para la determinación de igualdad: comparación de byte por byte, o la examinación de porciones de datos; sin embargo, en esta receta C# recurriremos a un enfoque más simple y directo, además de eficiente: algoritmo de código hash.

1. Problema

Determinar la igualdad de dos archivos usando un método rápido y al mismo tiempo efectivo.

2. Solución

En el namespace System.Security.Cryptography, .NET ofrece la clase HashAlgorithm para la generación de código hash para un archivo. Los códigos hash generados nos servirán para determinar la igualdad de dos archivos.

3. Discusión de la Solución

3.1 Algoritmo de hash

Aunque es posible comparar dos archivos usando cualquiera de estos dos enfoques [1, 2], i.e.:
  • examinación de una porción de datos, o
  • la lectura del archivo byte a byte.
Sin embargo, como advierten en [2]:
"...may miss systematic corruptions which occur to both files."
El enfoque más rápido, simple, y eficiente es recurrir a un algoritmo de generación de código hash. Este código hash es una cadena de caracteres producto de un algoritmo de hash.

Este algoritmo de hash [3] podría generar el mismo código hash para dos archivos, pero estadísticamente es improbable que esto llegue a suceder [1]. Evento poco probable debido a [1]:
"..., even a minor change (for example, modifying a single bit in the source file) has an approximately 50 percent chance of independently changing each bit in the hash code."

 3.2 Clase HashAlgorithm

La clase abstracta HashAlgorithm [4] (namespace System.Security.Cryptography) es la clase base para todas las imlementaciones particulares de algoritmos hash. Esta clase tiene declarado el método static Create para la creación de un objeto HashAlgorithm; y el método HashAlgorithm.ComputeHash para crear un arreglo de bytes con los datos del código hash.

3.2.1 Método Create

El método Create ofrece dos versiones sobrecargadas para la creación de un objeto de la jerarquía HashAlgorithm. La primera versión sobrecargada [6] crea un objeto con la implementación predeterminada de un algorithm hash.

Mientras que la segunda versión [7] recibe como argumento una cadena de caracteres que indica la implementación del algorithmo hash a usar. En la Tabla 1 se muestran los valores válidos para este argumento.
Implementaciones particulares de HashAlgorithm
Tabla 1. Implementaciones particulares de HashAlgorithm [7].

3.2.2 Método ComputeHash

Una vez obtenido el objeto HashAlgorithm con cualquiera de las versiones del método Create, debemos invocar una de las versiones sobrecargadas del método ComputeHash para computar/calcular el valor hash para el dato de entrada. En la siguiente tabla, Tabla 2, se describen las versiones sobrecargadas de este método.
Versiones sobrecargadas de ComputeHash
Tabla 2. Versiones sobrecargadas de ComputeHash [8].
El valor de retorno es un arreglo de bytes con los datos del cómputo del código o valor hash de la entrada.

4. Práctica: Código C#

Escribiremos una aplicación basada en consola para pedir al usuario las rutas y los nombres de los archivos para determinar su igualdad.

En la línea 26 obtenemos un objeto HashAlgorithm con la implementación por defecto. Sobre la línea 28 creamos dos objetos FileStream para referenciar los archivos a comparar. Con ComputeHash, líneas 32-33, creamos dos arreglos de bytes para contener el cómputo de los códigos hash. Con la sentencia if, línea 36, comparamos los códigos hash con la representación de cadena de caracteres generada con la invocación de BitConverter.ToString.

Compilación:


  1. csc /target:exe CompararArchivos.cs

Ejecución assembly:


  1. .\CompararArchivos.exe CompararArchivos.cs.1.txt CompararArchivos.cs.2.txt

> Prueba de ejecución:
Ejecución assembly CompararArchivos.exe
Figura 1. Ejecución assembly CompararArchivos.exe.

5. Conclusiones

Aprendimos a usar varios de los artefactos de la clase HashAlgorithm para computar el código hash; código que nos es de utilidad para comparar dos archivos y determinar su igualdad. Aunque existen otros enfoques para la comparación de archivos, el que hemos aprendido en esta receta es más fácil de usar y más efectivo.


En la próxima receta C# aprenderemos a manipular las cadenas de nombres de archivos para efectuar ciertas operaciones interesantes.

6. Glosario

  • Algoritmo
  • Archivo
  • Byte
  • Código hash
  • Ruta

7. Literatura & Enlaces

[1]: Visual C# 2010 Recipes by Allen Jones and Adam Freeman. Copyright 2010 Allen Jones and Adam Freeman, 978-1-4302-2525-6.
[2]: File verification - Wikipedia, the free encyclopedia - https://en.wikipedia.org/wiki/File_verification
[3]: Hash Algorithms - https://technet.microsoft.com/en-us/library/cc726061.aspx
[4]: HashAlgorithm Class (System.Security.Cryptography) - https://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm(v=vs.110).aspx
[5]: HashAlgorithm.Create Method (System.Security.Cryptography) - https://msdn.microsoft.com/en-us/library/System.Security.Cryptography.HashAlgorithm.Create(v=vs.110).aspx
[6]: HashAlgorithm.Create Method (System.Security.Cryptography) - https://msdn.microsoft.com/en-us/library/b0ky3sbb(v=vs.110).aspx
[7]: HashAlgorithm.Create Method (String) (System.Security.Cryptography) - https://msdn.microsoft.com/en-us/library/wet69s13(v=vs.110).aspx
[8]: HashAlgorithm.ComputeHash Method (System.Security.Cryptography) - https://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm.computehash(v=vs.110).aspx


M

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.