CRC-16Bit berechnung

Parrain

Cadet 3rd Year
Registriert
Sep. 2012
Beiträge
51
Hallo zusammen,

ich habe ein problem beim CRC wert berechnen. ich habe zwar in Internet verschieden codes gefunden..habe auch was geschrieben aber das ergebnins stimmt nicht!!!!!??????? :(


Code:
 private void button1_Click(object sender, EventArgs e)
        {
            byte[] bytesArray = new byte[] { 0x18,0x00,0x07,0xD2,0x02,0x58,0x02,0x58 };

            Crc16 crcclass = new Crc16();
            textBox1.Text = String.Format("{0}", crcclass.ComputeChecksum(bytesArray));
            byte[] result = crcclass.ComputeChecksumBytes(bytesArray);
            textBox2.Text = "";
            foreach (byte bit in result)
            {
                textBox2.Text += String.Format("{0:X}", bit);                       // Hexawert ausgabe
                textBox2.Text += Convert.ToString(1,2);                             //binär umwandlung
            }  
        }
    }


    public class Crc16
    {
        
        const int polynomial = 0x14EAB;
        int[] table = new int[256];

        public int ComputeChecksum(byte[] bytes)
        {
            int crc = 0;
            for (int i = 0; i < bytes.Length; ++i)
            {
                byte index = (byte)(crc ^ bytes[i]);
                crc = (int)((crc >> 8) ^ table[index]);
            }
            return crc;
        }

        public byte[] ComputeChecksumBytes(byte[] bytes)
        {
            int crc = ComputeChecksum(bytes);
            return BitConverter.GetBytes(crc);
        }

        public Crc16()
        {
            int value;
            int temp;
            for (int i = 0; i < table.Length; ++i)
            {
                value = 0;
                temp = i;
                for (byte j = 0; j < 8; ++j)
                {
                    if (((value ^ temp) & 0x0001) != 0)
                    {
                        value = (int)((value >> 1) ^ polynomial);
                    }
                    else
                    {
                        value >>= 1;
                    }
                    temp >>= 1;
                }
                table[i] = value;
            }
        }
    }

ergebnis sollte D0BD sein für den wert 180007D202580258
 
Zuletzt bearbeitet:
Hi,

1. Regeln lesen! Mehrfache Satzendzeichen sind nicht erlaubt!
2. Handbücher und API-Dokumentation lesen - die meisten deiner eröffneten C#-Threads liesen sich von vornherein vermeiden, wenn du vernünftig in den API-Dokumentation nachlesen oder die Beispiele korrekt lesen und umsetzen würdest ;)
3. Genauere Angaben machen - was heißt "das ergebnins stimmt nicht"? Das kann leider recht viel bedeuten, da musst du uns auf die Sprünge helfen, was genau nicht stimmt bzw was raus kommt ;) :)

VG,
Mad
 
Zuletzt bearbeitet: (Ergänzung bzgl. Polynom)
hi BIgNum,

der wert 0x14EAB ist von siemens als vorgabe bestimmt..das macht mich auch verrückt.
In Dokumenten steht es auch so, und stimmt auch für die ergebnisse die man erwartet für einen 16-Bit CRC!!

Genauer: diese Prüfwert (CRC) bestimmt man für die Safety des Profibus..

Ich habe die Rechnung per Hand gemacht und es klappt. der wert 180007D202580258(Hex) in Dual umgewandelt und dann mit XOR mit 0x14EAB berechnet..

im Programm nicht :-(
 
Zuletzt bearbeitet:
Das war mal wieder ein echter Parrain!

Ich hab's mit der in http://www.itk.ntnu.no/fag/TTK4545/TTK2/PDF/ProfiSafe-Profil-100e.pdf, Abschnitt 6.2 (Seite 51ff) beschriebenen "Runtime-optimized variant" in C# "quick'n dirty" reingehackt:
Code:
using System;

namespace CRC16
{
    class Program
    {
        static ushort[] crctab16 = new ushort[]
        {
            0x0000, 0x4EAB, 0x9D56, 0xD3FD, 0x7407, 0x3AAC, 0xE951, 0xA7FA, 0xE80E, 0xA6A5, 0x7558, 0x3BF3, 0x9C09, 0xD2A2, 0x015F, 0x4FF4,
            0x9EB7, 0xD01C, 0x03E1, 0x4D4A, 0xEAB0, 0xA41B, 0x77E6, 0x394D, 0x76B9, 0x3812, 0xEBEF, 0xA544, 0x02BE, 0x4C15, 0x9FE8, 0xD143,
            0x73C5, 0x3D6E, 0xEE93, 0xA038, 0x07C2, 0x4969, 0x9A94, 0xD43F, 0x9BCB, 0xD560, 0x069D, 0x4836, 0xEFCC, 0xA167, 0x729A, 0x3C31,
            0xED72, 0xA3D9, 0x7024, 0x3E8F, 0x9975, 0xD7DE, 0x0423, 0x4A88, 0x057C, 0x4BD7, 0x982A, 0xD681, 0x717B, 0x3FD0, 0xEC2D, 0xA286,
            0xE78A, 0xA921, 0x7ADC, 0x3477, 0x938D, 0xDD26, 0x0EDB, 0x4070, 0x0F84, 0x412F, 0x92D2, 0xDC79, 0x7B83, 0x3528, 0xE6D5, 0xA87E,
            0x793D, 0x3796, 0xE46B, 0xAAC0, 0x0D3A, 0x4391, 0x906C, 0xDEC7, 0x9133, 0xDF98, 0x0C65, 0x42CE, 0xE534, 0xAB9F, 0x7862, 0x36C9,
            0x944F, 0xDAE4, 0x0919, 0x47B2, 0xE048, 0xAEE3, 0x7D1E, 0x33B5, 0x7C41, 0x32EA, 0xE117, 0xAFBC, 0x0846, 0x46ED, 0x9510, 0xDBBB,
            0x0AF8, 0x4453, 0x97AE, 0xD905, 0x7EFF, 0x3054, 0xE3A9, 0xAD02, 0xE2F6, 0xAC5D, 0x7FA0, 0x310B, 0x96F1, 0xD85A, 0x0BA7, 0x450C,
            0x81BF, 0xCF14, 0x1CE9, 0x5242, 0xF5B8, 0xBB13, 0x68EE, 0x2645, 0x69B1, 0x271A, 0xF4E7, 0xBA4C, 0x1DB6, 0x531D, 0x80E0, 0xCE4B,
            0x1F08, 0x51A3, 0x825E, 0xCCF5, 0x6B0F, 0x25A4, 0xF659, 0xB8F2, 0xF706, 0xB9AD, 0x6A50, 0x24FB, 0x8301, 0xCDAA, 0x1E57, 0x50FC,
            0xF27A, 0xBCD1, 0x6F2C, 0x2187, 0x867D, 0xC8D6, 0x1B2B, 0x5580, 0x1A74, 0x54DF, 0x8722, 0xC989, 0x6E73, 0x20D8, 0xF325, 0xBD8E,
            0x6CCD, 0x2266, 0xF19B, 0xBF30, 0x18CA, 0x5661, 0x859C, 0xCB37, 0x84C3, 0xCA68, 0x1995, 0x573E, 0xF0C4, 0xBE6F, 0x6D92, 0x2339,
            0x6635, 0x289E, 0xFB63, 0xB5C8, 0x1232, 0x5C99, 0x8F64, 0xC1CF, 0x8E3B, 0xC090, 0x136D, 0x5DC6, 0xFA3C, 0xB497, 0x676A, 0x29C1,
            0xF882, 0xB629, 0x65D4, 0x2B7F, 0x8C85, 0xC22E, 0x11D3, 0x5F78, 0x108C, 0x5E27, 0x8DDA, 0xC371, 0x648B, 0x2A20, 0xF9DD, 0xB776,
            0x15F0, 0x5B5B, 0x88A6, 0xC60D, 0x61F7, 0x2F5C, 0xFCA1, 0xB20A, 0xFDFE, 0xB355, 0x60A8, 0x2E03, 0x89F9, 0xC752, 0x14AF, 0x5A04,
            0x8B47, 0xC5EC, 0x1611, 0x58BA, 0xFF40, 0xB1EB, 0x6216, 0x2CBD, 0x6349, 0x2DE2, 0xFE1F, 0xB0B4, 0x174E, 0x59E5, 0x8A18, 0xC4B3
        };

        static ushort CRC16(byte[] data)
        {
            ushort crc = 0;
            for (int i = 0; i < data.Length; i++)
                crc = (ushort)(crctab16[(crc >> 8) ^ data[i]] ^ (crc << 8));
            return crc;
        }

        static void Main(string[] args)
        {
            // byte[] bytesArray = new byte[] { 1, 8, 0, 0, 0, 7, 13, 2, 0, 2, 5, 8, 0, 2, 5, 8 };
            byte[] bytesArray = new byte[] { 0x18, 0x00, 0x07, 0xD2, 0x02, 0x58, 0x02, 0x58 };
            ushort crc = CRC16(bytesArray);
            Console.WriteLine("crc= 0x{0:X}", crc);
            Console.ReadKey();
        }
    }
}

Mit Deinen originalen Werten "1, 8, 0, 0, 0, 7, 13, 2, 0, 2, 5, 8, 0, 2, 5, 8" ging es natürlich nicht, aber man lässt sich ja was einfallen, um den Gegner zu verwirren ;)

Der Output ist:
crc= 0xD0BD (wie gewünscht!)


HTH

BigNum


P.S.: Du schuldest mir inzwischen schon 2 Bierchen (dunkles Weizen)!
Zu begleichen im Sommer nächsten Jahres im Biergarten!
 
Zurück
Oben