Calcul du CRC 16

Résolu/Fermé
cocodu67... Messages postés 3153 Date d'inscription jeudi 28 janvier 2010 Statut Membre Dernière intervention 4 avril 2024 - Modifié par irongege le 25/12/2013 à 18:13
cocodu67... Messages postés 3153 Date d'inscription jeudi 28 janvier 2010 Statut Membre Dernière intervention 4 avril 2024 - 26 déc. 2013 à 15:25
Bonjour

Je dois coder un programme en C# qui calcul le CRC16 d'une valeur hexadécimale qu'on marque dans une textbox et qui affiche le CRC16 dans un label lors de l'appuie sur un bouton.

J'ai déjà lus plein de choses sur internet mais je ne comprend vraiment pas comment faire ...

Par exemple le CRC16 de 3A (en hexa) est égal à 70D5 (en hexa) (donné sur l'énoncé)

Avez vous des idées ?

Merci
A voir également:

2 réponses

ElementW Messages postés 4816 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021 1 225
Modifié par gravgun le 25/12/2013 à 20:40
Salut, le hic dès le début c'est qu'il existe plusieurs CRC-16... Après vérif ici c'est du CRC-16 Modbus que tu parles.
Deuxièmement,
CRC16(0x16) = 0x533F
, c'est pas ce que tu cherches: c'est
3A
en hexa certes, mais tu parles d'une chaîne de caractère, donc les données en hexa sont
0x33 0x41
, et là
CRC16("3A") = 0x70D5
.
Après une petite recherche Google je tombe sur ça, et un tout petit algo qui fait ce qu'on veut, mais il est en C.
Vite fait traduit en C#:
static class CRC {
	static uint CRC16(byte[] buf)
	{
		uint crc = 0xFFFF;
		for (int pos = 0; pos < buf.Length; pos++)
		{
			crc ^= (uint)buf[pos];    // XOR byte into least sig. byte of crc

			for (int i = 8; i != 0; i--) {    // Loop over each bit
				if ((crc & 0x0001) != 0) {      // If the LSB is set
					crc >>= 1;                    // Shift right and XOR 0xA001
					crc ^= 0xA001;
				}
			else                            // Else LSB is not set
				crc >>= 1;                    // Just shift right
			}
		}

		return crc;
	}

	static void Main(string[] args) {
		byte[] data = System.Text.Encoding.ASCII.GetBytes("3A");
		System.Console.WriteLine(CRC16(data).ToString("X"));
	}
}


from human import idiocy
del idiocy
1
cocodu67... Messages postés 3153 Date d'inscription jeudi 28 janvier 2010 Statut Membre Dernière intervention 4 avril 2024 145
25 déc. 2013 à 23:17
Merci, dès demain je vais voir si j'arrive à adapter cela au mode graphique mais c'est pas compliqué je pense, le plus dur vous l'avez écris.

Cependant, je ne comprend pas à quoi sert le .ToString("X")
Cela sert simplement à dire que c'est une valeur hexadécimale ?

Bonne soirée :)
0
ElementW Messages postés 4816 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021 1 225
Modifié par gravgun le 25/12/2013 à 23:35
Oui le
Main()
n'est que pour illustrer l'exemple donné dans l'exo, et le
.ToString("X")
convertit un nombre en format hexadécimal, car les CRC sont représentés en hexa.
(Et pourquoi j'ai mis
CRC16(0x16) = 0x533F
moi? Je voulais dire
CRC16(0x3A) = 0x533F
)
0
cocodu67... Messages postés 3153 Date d'inscription jeudi 28 janvier 2010 Statut Membre Dernière intervention 4 avril 2024 145
25 déc. 2013 à 23:44
Heu ... .ToString convertit quelque chose en chaîne de caractères d'après ce dont je ne souviens.
0
cocodu67... Messages postés 3153 Date d'inscription jeudi 28 janvier 2010 Statut Membre Dernière intervention 4 avril 2024 145
26 déc. 2013 à 15:25
C'est parfait, ça fonctionne.

Pour ceux que ça intéresse, ma fenêtre est composée d'une textBoxSaisie, d'un labelAffichage et d'un buttonCalcul

Voici le code entier :

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

namespace WindowsFormsApplicationCRC
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void buttonCalcul_Click(object sender, EventArgs e)
{


byte[] data = System.Text.Encoding.ASCII.GetBytes(textBoxSaisie.Text);
labelAffichage.Text = (CRC16(data).ToString("X"));


}

static uint CRC16(byte[] buf)
{
uint crc = 0xFFFF;
for (int pos = 0; pos < buf.Length; pos++)
{
crc ^= (uint)buf[pos];

for (int i = 8; i != 0; i--)
{
if ((crc & 0x0001) != 0)
{
crc >>= 1;
crc ^= 0xA001;
}
else
crc >>= 1;
}
}

return crc;
}

}


}




Merci à toi gravgun, j'ai enfin compris comment ça fonctionne pour calculer le CRC 16.

Bonne journée
0