C# FletcherChecksum16: Suma de comprobación CRC para tramas de datos

Introducción

El checksum de Fletcher es un algoritmo para implementar una suma de comprobación que permita detectar un error en alguno de los campos de un mensaje entre su emisión y recepción. Es muy común en protocolos de mensajería de bajo nivel, la máquina que genera el mensaje añade al final de la trama que envía otro campo con el CRC calculado con los bytes del cuerpo del mensaje. El receptor a su vez cuando recibe la trama calcula usando el mismo algoritmo el CRC del cuerpo del mensaje y lo compara con el campo que ha añadido el emisor, evidentemente si los resultados no son el mismo con toda probabilidad la trama se ha corrompido en algún momento de la transmisión.

Las NDCAN de Kimaldi son tarjetas de entradas salidas que permiten la interacción con una red sensores conectadas entre si en batería (fotocelulas de presencia como entradas digitales para detectar la presencia de un objeto por ejemplo) sobre un bus CAN industrial. Al final de la red de tarjetas un concentrador de comunicaciones del mismo fabricante recibe / envía los datos a las tarjetas conectado a un PC usando un protocolo sería basado en tramas con un CRC al final.

can1

El algoritmo empleado para generar el CRC de las tramas serie es muy sencillo y el resultado solo ocupa 1 byte. Las tramas son cadenas en representación hexadecimal (un valor de un byte se representa como dos hexadecimales). Mr Robot usa la aplicación Web ASCII to Hex para convertir entre diferentes bases numéricas, nosotros no vamos a ser menos, por el ejemplo el número decimal 255 se representa en base 16 o hexadecimal como 0xAA (la notación “0x” que precede es para indicar que es un número en hexadecimal):

can2

Ahora vamos a lo que realmente importa, ¿como calcula el CRC? Supongamos que recibimos la siguiente trama:

<STX>02015102000A<CRC><ETX>

Los valores <STX> y <ETX> son valores especiales para indicar donde debemos comenzar a leer la trama y donde finaliza (caracteres de control Start/End of transmission) y no forman parte del calculo del CRC (protocolo MAGSTRIPE usado en tarjetas de banda magnética), para calcular el CRC empleamos exclusivamente el cuerpo del mensaje, en este caso “02015102000A” se calcula de la siguiente forma:

 El valor de CRC se calcula sumando los valores Ascii del cuerpo de la trama:

  • El ascii del 0 es 48
  • El ascii del 2 es 50
  • El ascii del 0 es 48
  • El ascii del 1 es 49
  • El ascii del 5 es 53
  • El ascii del 1 es 49
  • El ascii del 0 es 48
  • El ascii del 2 es 50
  • El ascii del 0 es 48
  • El ascii del 0 es 48
  • El ascii del 0 es 48
  • El ascii del A es 65

Que suman: 604. Su equivalente hexadecimal es 0x25C. Tomando los dos últimos dígitos del resultado hexadecimal obtenemos el valor de la suma en módulo 256, es decir 0x5C.
Así púes la trama queda:

<STX>02015102000A5C<ETX>

Aplicación C# para calcular el CRC de una trama serie

Vamos a diseñar una aplicación super sencilla que permita calcular el CRC de una cadena en formato hexadecimal.

can3

Sólo usamos 3 tipos de controles: TextBox para los campos de edición (uno de ellos de solo lectura con el resultado CRC), Labels para las etiquetas de texto y Button para los 3 botones:

  • txtTrmHex: TextBox donde introducimos cadena hexadecimal.
  • btnAceptar: Button para realizar el cálculo y mostrar el resultado.
  • txtCRC: Campo de edición de solo lectura con el resultado.
  • btnReset: Botón con leyenda “Limpiar” para vaciar contenido de los campos de edición.
  • btnQuitApp: Botón para abandonar la aplicación.

Primero ajustamos el diseño de los controles a nuestro gusto (diseño plano, colores de texto, posicionamiento,…).

Lo primero es crear el método dentro de nuestra clase para calcular el CRC, recibe una cadena de caracteres y retorna como salida un byte:

can4

En el constructor del formulario vamos a poner el foco del cursor sobre el campo de edición para comenzar a introducir la cadena inmediatamente:

can5

Ahora vamos a programar el evento de pulsación del botón aceptar:

can6

También queremos realizar el mismo cálculo cuando pulsamos la tecla “Enter” en el cuadro de edición:

can7

El resto de los eventos ya no tienen ningún misterio:

can8

Aquí esta el código completo:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FletcherChecksum16
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
txtTrmHex.Focus();
}

private byte Calcula_CRC(string cmd)
{
ulong suma=0;
int i=0;
for (i = 0; i < cmd.Length; i++)
{
suma+=cmd[i];
}

return (byte)(suma & 0xFF);
}

private void btnAceptar_Click(object sender, EventArgs e)
{
if (txtTrmHex.Text.Equals(""))
{
MessageBox.Show(this, "No puedes dejar el campo vacio", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
txtCRC.Text = String.Format("{0,2:X}", Calcula_CRC(txtTrmHex.Text));
}
}

private void btnReset_Click(object sender, EventArgs e)
{
txtCRC.Text = "";
txtTrmHex.Text = "";

}

private void btnQuitApp_Click(object sender, EventArgs e)
{
this.Close();
}

private void txtTrmHex_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (txtTrmHex.Text.Equals(""))
{
MessageBox.Show(this, "No puedes dejar el campo vacio", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
txtCRC.Text = String.Format("{0,2:X}", Calcula_CRC(txtTrmHex.Text));
}

}
}

}
}

 

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s