C++ to C#



  • Habe hier ein kleines C++ Proggramm das eine Checksumme berechnet:

    unsigned char rawData[128] =
    {
    	0x08, 0x00, 0xCB, 0x47, 0x45, 0x0E, 0x01, 0x00, 0x45, 0xE0, 0xCF, 0x2E, 0xD9, 0xEF, 0x72, 0xE3, 0x08, 0x95, 0xF4, 0xF6, 0xF8, 0x0F, 0x70, 0x49, 0x8B, 0xBF, 0x7C,
    	0xAE, 0xE4, 0x23, 0x00, 0xAA, 0x57, 0x56, 0x31, 0x5A, 0x5A, 0x5A, 0x32, 0x48, 0x5A, 0x42, 0x38, 0x30, 0x33, 0x35, 0x34, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30,
    	0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x19, 0x80, 0x0C, 0x08, 0x00, 0x00, 0x00, 0xFB, 0xB6, 0xFF, 0x92, 0x3C, 0x5E, 0xF3, 0x77, 0xC8, 0xB4, 0x79,
    	0x96, 0xA4, 0x72, 0xE2, 0x0C, 0x09, 0xFC, 0x4C, 0x51, 0x6C, 0x4D, 0xDC, 0x27, 0xFC, 0x51, 0x8C, 0x49, 0x7A, 0xCB, 0xF2, 0xD9, 0x5C, 0xF8, 0xDA, 0xD4, 0x91, 0x00,
    	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x92, 0x30, 0x6C, 0x35
    };
    
    unsigned int cs(unsigned int cs, unsigned int *p, unsigned int sz)
    {
    	const unsigned int poly = 0xEDB88320;
    	unsigned int tmp1, tmp2;
    
    	while (sz--)
    	{
    		tmp1 = 0;
    		tmp2 = cs & poly;
    		for (int i = 0; i <= 31; i++)
    			tmp1 ^= ((tmp2 >> i) & 1);
    		cs = *p++ ^ ((cs << 1) | tmp1);
    	}
    	return cs;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	printf("CHECKSUM  -> %04X\n", 0xFFFF & cs((unsigned short)*(&rawData[0]), (unsigned int *)(&rawData[4]),0x7c /4));
    	while (1);
    	return 0;
    }
    

    beim versuch es in C# nachzubauen bin ich aber gescheitert:

    namespace cs_0424
    {
    
        public partial class Form1 : Form
        {
            private byte[] rawData = { 0x08, 0x00, 0xCB, 0x47, 0x45, 0x0E, 0x01, 0x00, 0x45, 0xE0, 0xCF, 0x2E, 0xD9, 0xEF, 0x72, 0xE3,
                                       0x08, 0x95, 0xF4, 0xF6, 0xF8, 0x0F, 0x70, 0x49, 0x8B, 0xBF, 0x7C, 0xAE, 0xE4, 0x23, 0x00, 0xAA,
                                       0x57, 0x56, 0x31, 0x5A, 0x5A, 0x5A, 0x32, 0x48, 0x5A, 0x42, 0x38, 0x30, 0x33, 0x35, 0x34, 0x31,
                                       0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x19,
                                       0x80, 0x0C, 0x08, 0x00, 0x00, 0x00, 0xFB, 0xB6, 0xFF, 0x92, 0x3C, 0x5E, 0xF3, 0x77, 0xC8, 0xB4,
                                       0x79, 0x96, 0xA4, 0x72, 0xE2, 0x0C, 0x09, 0xFC, 0x4C, 0x51, 0x6C, 0x4D, 0xDC, 0x27, 0xFC, 0x51,
                                       0x8C, 0x49, 0x7A, 0xCB, 0xF2, 0xD9, 0x5C, 0xF8, 0xDA, 0xD4, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x92, 0x30, 0x6C, 0x35 };
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private unsafe uint cs(uint cs, uint p, uint sz)
            {
                const uint poly = 0xEDB88320;
                uint tmp1;
                uint tmp2;
    
                while (sz-- != 0)
                {
                    tmp1 = 0;
                    tmp2 = cs & poly;
                    for (int i = 0; i <= 31; i++)
                    {
                        tmp1 ^= ((tmp2 >> i) & 1);
                    }
                    cs = p++ ^ ((cs << 1) | tmp1);
                }
                return cs;
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                textBox1.Text = Convert.ToString(0xFFFF & cs(Convert.ToUInt32((ushort) rawData[0]), (uint)(rawData[4]), 0x7C / 4));
            }
        }
    }
    

    Es wird zwar eine Checksumme ausgegeben aber die falsche 😕

    Evtl. hat jemand einen Tip für mich!

    Grüße



  • genome schrieb:

    Evtl. hat jemand einen Tip für mich!

    Ja. Und zwar würde ich Debuggen bzw. die Ergebnisse der Zwischenschritte ausgeben. Dann findest du bestimmt heraus, wo der Unterschied ist.



  • unsigned int *p
    

    vs.

    uint p
    

    sowie

    *p++
    

    vs.

    p++
    

    Und der Aufruf in deinem C#-Code von der Methode cs ist auch falsch.

    Weißt du überhaupt was Zeiger sind?



  • Das mit den Zeigern war mir mehr oder weniger klar habe ich auch schon vorher korrigiert!

    namespace cs_0424
    {
    
        public partial class Form1 : Form
        {
    
            private byte[] rawData = { 0x08, 0x00, 0xCB, 0x47, 0x45, 0x0E, 0x01, 0x00, 0x45, 0xE0, 0xCF, 0x2E, 0xD9, 0xEF, 0x72, 0xE3,
                                       0x08, 0x95, 0xF4, 0xF6, 0xF8, 0x0F, 0x70, 0x49, 0x8B, 0xBF, 0x7C, 0xAE, 0xE4, 0x23, 0x00, 0xAA,
                                       0x57, 0x56, 0x31, 0x5A, 0x5A, 0x5A, 0x32, 0x48, 0x5A, 0x42, 0x38, 0x30, 0x33, 0x35, 0x34, 0x31,
                                       0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x19,
                                       0x80, 0x0C, 0x08, 0x00, 0x00, 0x00, 0xFB, 0xB6, 0xFF, 0x92, 0x3C, 0x5E, 0xF3, 0x77, 0xC8, 0xB4,
                                       0x79, 0x96, 0xA4, 0x72, 0xE2, 0x0C, 0x09, 0xFC, 0x4C, 0x51, 0x6C, 0x4D, 0xDC, 0x27, 0xFC, 0x51,
                                       0x8C, 0x49, 0x7A, 0xCB, 0xF2, 0xD9, 0x5C, 0xF8, 0xDA, 0xD4, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x92, 0x30, 0x6C, 0x35 };
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private unsafe uint cks(uint cs, uint* p, uint sz)
            {
                const uint poly = 0xEDB88320;
                uint tmp1;
                uint tmp2;
    
                while (sz-- != 0)
                {
                    tmp1 = 0;
                    tmp2 = cs & poly;
                    for (int i = 0; i <= 31; i++)
                    {
                        tmp1 ^= ((tmp2 >> i) & 1);
                    }
                    cs = *p++ ^ ((cs << 1) | tmp1);
                 }
                return cs;
            }
    
            private unsafe void button1_Click(object sender, EventArgs e)
            {
                textBox1.Text = Convert.ToString(cks((ushort)rawData[0], (uint*)(rawData[4]), 0x7C / 4));
            }
        }
    }
    

    Der Hund liegt denke ich in dieser Zeile begraben:

    cs = *p++ ^ ((cs << 1) | tmp1); 😡



  • Nee, sondern

    (uint*)(&rawData[4]) // Adress-Operator (&) ist wichtig!
    


  • Ah genau danke!

    Aber dan bekomme ich folgenden Fehler:
    "Sie können nur die Adresse eines unfixed-Ausdrucks innerhalb eines fixed-Anweisungsinitialisierers abrufen."

    Wieso ist es hier nicht möglich den Zeiger auf das Element zu übergeben?

    Grüße



  • Erkunde dich mal nach den C#-Schlüsselwörtern unsafe und fixed.

    Aber anstatt den C++-Code 1:1 mittels Zeiger nachzubauen, wäre es wohl besser, einfach das Array zu übergeben und mittels eines Index darauf zuzugreifen:

    private uint cks(uint cs, byte[] rawData, uint sz)
            {
                const uint poly = 0xEDB88320;
                uint tmp1;
                uint tmp2;
                int i = 4; // edit: nicht 0, sondern soll ja bei 4 beginnen
    
                while (sz-- != 0)
                {
                    tmp1 = 0;
                    tmp2 = cs & poly;
                    for (int i = 0; i <= 31; i++)
                    {
                        tmp1 ^= ((tmp2 >> i) & 1);
                    }
                    cs = rawData[i] ^ ((cs << 1) | tmp1);
                    i++;
                 }
                return cs;
            }
    

    Da der Original C++-Code jedoch immer int-weise die Checksumme berechnet, müßtest du dies noch einarbeiten, d.h. innerhalb der Schleife jeweils 4 Byte aus dem Array lesen und zu einem int zusammenfügen, z.B. mittels BitConverter.



  • Th69 schrieb:

    int i = 4; // edit: nicht 0, sondern soll ja bei 4 beginnen
    

    Wäre vielleicht fesch wenn man das der Funktion als Parameter mitgeben könnte 😉



  • Wie, sowas geht? 🕶


Log in to reply