[Résolu] Check sum

ancrouancrou Membre
avril 2008 modifié dans Vos applications #1
Bonjour,
Je ne trouve pas l'erreur. vous la voyez ?
//Calcule du Check sum<br />static BOOL calc(NSData* data, UI16_ crc) {<br />	UI08_ a, b,c;<br />	UI08_ crcL = crc &amp; 0x00ff;			//Low byte (least significant) of the 16-bit CRC<br />	UI08_ crcH = (crc &gt;&gt; 8) &amp; 0x00ff;	//High byte (most significant) of the 16-bit CRC<br />	UI16_ loop;<br />	for (loop = 0;loop &lt; [data length]; loop++) {		<br />		a=a ^ crcH;<br />		crcH=a;<br />		a&gt;&gt;=4;<br />		a=a ^ crcH;<br />		crcH=crcL;<br />		crcL=a;<br />		<br />		//ROTATE a LEFT 4 TIMES<br />		c=a;<br />		c&gt;&gt;=4;<br />		a&lt;&lt;=4;<br />		a|=c;<br />		<br />		b=a;	//{ temp save}<br />		<br />		//ROTATE a LEFT ONCE<br />		c=a;<br />		c&gt;&gt;=7;<br />		a&lt;&lt;=1;<br />		a|=c;<br />		<br />		a= a &amp; 0x1f;<br />		crcH=a ^ crcH;<br />		a=b &amp; 0xf0;<br />		crcH=a ^ crcH;<br />				<br />		//ROTATE b LEFT ONCE<br />		c=b;<br />		c&gt;&gt;=7;<br />		b&lt;&lt;=1;<br />		b|=c;<br />		<br />		b=b &amp; 0xe0;<br />		crcL=b ^ crcL;<br />	}<br />	printf(&quot;crcH %X &#092;t&quot;,crcH);<br />	printf(&quot;crcL %X &#092;n&quot;,crcL);<br />	printf(&quot;crc %X &#092;n&quot;,crc);<br /><br />	return (crcL ==(crc &amp; 0x00ff) &amp;&amp; crcH ==(crc &gt;&gt; 8) &amp; 0x00ff);<br />}


L'algo de la norme
NOTES:
A = new byte
B = temp byte
CRCHI = High byte (most significant) of the 16-bit CRC
CRCLO = Low byte (least significant) of the 16-bit CRC
START:
FOR A = FIRST_BYTE TO LAST_BYTE IN BLOCK DO:
A = A XOR CRCHI
CRCHI = A
SHIFT A RIGHT FOUR TIMES (ZERO FILL)
A = A XOR CRCHI { I J K L M N O P }
CRCHI = CRCLO { swap CRCHI, CRCLO }
CRCLO = A
ROTATE A LEFT 4 TIMES { M N O P I J K L }
B = A { temp save }
ROTATE A LEFT ONCE { N O P I J K L M }
A = A AND $1F { 0 0 0 I J L L M }
CRCHI = A XOR CRCHI
A = B AND $F0 { M N O P 0 0 0 0 }
CRCHI = A XOR CRCHI { CRCHI complete }
ROTATE B LEFT ONCE { N O P 0 0 0 0 M }
B = B AND $ E0 { N O P 0 0 0 0 0 }
CRCLO = B XOR CRCLO ( CRCLO complete }
DOEND;

Le CRC calculé doit être égal au CRC donné
Et j'ai :
crcH B3 crcL BD
crc 8A3F


Réponses

  • CéroceCéroce Membre, Modérateur
    avril 2008 modifié #2
    "a" n'est pas initialisé.

    P.S.: Evite le [data length] à  chaque passage dans la boucle; ça doit doubler le temps d'exécution de ta méthode.
    Remarque aussi que le calcul ne peut pas porter sur plus de 64 Ko de données (je ne sais pas si ça pose problème).
  • ancrouancrou Membre
    16:57 modifié #3
    dans 1208169670:

    "a" n'est pas initialisé.

    P.S.: Evite le [data length] à  chaque passage dans la boucle; ça doit doubler le temps d'exécution de ta méthode.
    Remarque aussi que le calcul ne peut pas porter sur plus de 64 Ko de données (je ne sais pas si ça pose problème).


    Merci, j'ai donc une 2ème version. malheureusement, elle ne marche pas  :(
    /***************************************************************<br />Calcule du Check sum<br />***************************************************************/<br />static BOOL calc(UI32_ length, UI16_ crc) {<br />	printf(&quot;----------------------------------&#092;n&quot;);<br />	printf(&quot;lentgh hex, %lX&#092;n&quot;,length);<br />	printf(&quot;crc %X&#092;n&quot;,crc);<br />	UI08_ a, b,c;<br />	a = 0x00;<br />	UI08_ crcL = crc &amp; 0x00FF;			//Low byte (least significant) of the 16-bit CRC<br />	UI08_ crcH = (crc &gt;&gt; 8) &amp; 0x00FF;	//High byte (most significant) of the 16-bit CRC<br />	UI32_ loop;<br />	for (loop = 0x00000001; loop &lt;= length; loop++) {		<br />		a = a ^ crcH;<br />		crcH = a;<br />		a &gt;&gt;= 4;			//SHIFT a RIGHT FOUR TIMES (ZERO FILL) <br />		a = a ^ crcH;		//{ I J K L M N O P }<br />		crcH = crcL;		//{ swap CRCHI, CRCLO } <br />		crcL = a;<br />		<br />		//ROTATE a LEFT 4 TIMES<br />		c = a;<br />		c &gt;&gt;= 4;<br />		a &lt;&lt;= 4;<br />		a |= c;			//{ M N O P I J K L } <br />		<br />		b = a;			//{ temp save}<br />		<br />		//ROTATE a LEFT ONCE<br />		c = a;<br />		c &gt;&gt;= 7;<br />		a &lt;&lt;= 1;<br />		a |= c;			//{ N O P I J K L M }<br />		<br />		a = a &amp; 0x1F;	//{ 0 0 0 I J L L M } <br />		crcH = a ^ crcH;<br />		a = b &amp; 0xF0;		//{ M N O P 0 0 0 0 } <br />		crcH = a ^ crcH;	//{ CRCHI complete }<br />		<br />		//ROTATE b LEFT ONCE<br />		c = b;<br />		c &gt;&gt;= 7;<br />		b &lt;&lt;= 1;<br />		b |= c;			// N O P 0 0 0 0 M } <br />		<br />		b = b &amp; 0xE0;		//{ N O P 0 0 0 0 0 } <br />		crcL = b ^ crcL;	//( CRCLO complete }<br />	}<br />	printf(&quot;crcH %X &#092;t&quot;,crcH);<br />	printf(&quot;crcL %X &#092;n&quot;,crcL);<br />	/*Calculating the CRC of the resulting data stream shall result in a <br />		zero CRC if the data was correctly received.*/<br />	return (crcL ==(crc &amp; 0x00FF) &amp;&amp; crcH ==(crc &gt;&gt; 8) &amp; 0x00FF);<br />}
    


    Mes printf du CRC calculés et le CRC donnée sont différents. Avec tous mes fichiers testés.
    La limite à  64ko ne me pose pas de problème.


  • CéroceCéroce Membre, Modérateur
    16:57 modifié #4
    Ca m'avait complètement échappé la 1ère fois, mais: "A quoi sert ta fonction" ?
    Un calcul de checksum sert à  calculer une empreinte caractéristique d'un ensemble de données.

    Or dans le 1er exemple: les données de data ne sont pas utilisés.
    Dans le 2ème, data n'apparaà®t même plus.

    FOR A = FIRST_BYTE TO LAST_BYTE IN BLOCK
    n'est pas écrit pour rien.


    Il faut que tu arrêtes de bidouiller ton code jusqu'à  ce qu'il marche et que tu réfléchisses au rôle de ta fonction, et quelles sont ses entrées et ses sorties. Là , ça marchera tout seul.
  • ancrouancrou Membre
    16:57 modifié #5
    dans 1208327383:

    Or dans le 1er exemple: les données de data ne sont pas utilisés.
    Dans le 2ème, data n'apparaà®t même plus.

    FOR A = FIRST_BYTE TO LAST_BYTE IN BLOCK
    n'est pas écrit pour rien.


    Je comprends mieux l'histoire du
    "a" n'est pas initialisé.
      :crackboom:- Merci pour m'avoir corrigé cette grosse erreur.

    Mais ça ne marche toujours pas  :'(
    /***************************************************************<br />Calcule du Check sum<br />***************************************************************/<br />static BOOL calc(NSData* data, UI16_ crc) {<br />	UI32_ length = [data length] ;<br />	printf(&quot;----------------------------------&#092;n&quot;);<br />	printf(&quot;lentgh hex, %lX&#092;n&quot;,length);<br />	printf(&quot;crc %X&#092;n&quot;,crc);<br />	UI08_ a, b,c;<br />	UI08_ crcL = crc &amp; 0x00FF;			//Low byte (least significant) of the 16-bit CRC<br />	UI08_ crcH = (crc &gt;&gt; 8) &amp; 0x00FF;	//High byte (most significant) of the 16-bit CRC<br />	UI32_ loop;<br />	/*is calculated over the entire range starting with the first byte following the CRC<br />	and ending with the last byte in the record.*/<br />	for (loop = 0x00000002; loop &lt; length; loop++) { <br />		[data getBytes:&amp;a range:NSMakeRange(loop, sizeof(a))];<br />		a = a ^ crcH;<br />		crcH = a;<br />		a &gt;&gt;= 4;			//SHIFT a RIGHT FOUR TIMES (ZERO FILL) <br />		a = a ^ crcH;		//{ I J K L M N O P }<br />		crcH = crcL;		//{ swap CRCHI, CRCLO } <br />		crcL = a;<br />		<br />		//ROTATE a LEFT 4 TIMES<br />		c = a;<br />		c &gt;&gt;= 4;<br />		a &lt;&lt;= 4;<br />		a |= c;			//{ M N O P I J K L } <br />		<br />		b = a;			//{ temp save}<br />		<br />		//ROTATE a LEFT ONCE<br />		c = a;<br />		c &gt;&gt;= 7;<br />		a &lt;&lt;= 1;<br />		a |= c;			//{ N O P I J K L M }<br />		<br />		a = a &amp; 0x1F;	//{ 0 0 0 I J L L M } <br />		crcH = a ^ crcH;<br />		a = b &amp; 0xF0;		//{ M N O P 0 0 0 0 } <br />		crcH = a ^ crcH;	//{ CRCHI complete }<br />		<br />		//ROTATE b LEFT ONCE<br />		c = b;<br />		c &gt;&gt;= 7;<br />		b &lt;&lt;= 1;<br />		b |= c;			// N O P 0 0 0 0 M } <br />		<br />		b = b &amp; 0xE0;		//{ N O P 0 0 0 0 0 } <br />		crcL = b ^ crcL;	//( CRCLO complete }<br />	}<br />	printf(&quot;crcH %X &#092;t&quot;,crcH);<br />	printf(&quot;crcL %X &#092;n&quot;,crcL);<br />	/*Calculating the CRC of the resulting data stream shall result in a <br />		zero CRC if the data was correctly received.*/<br />	return (crcL ==(crc &amp; 0x00ff) &amp;&amp; crcH ==(crc &gt;&gt; 8) &amp; 0x00ff);<br />}
    


    J'ai fait un printf de a, les valeurs semblent bonnes (les 1er et les dernières).
    J'ai essayé en incluent le CRC dans les données; mais non !
    De ne pas faire le swap avec l'histoire de G5 ou Intel, mais non !
    ...
    Mes calculs semblent bon quand je regarde bit à  bit
    ...  :why?:
  • CéroceCéroce Membre, Modérateur
    16:57 modifié #6
    J'ai essayé de le coder moi-même pour voir les différences:

    UI_16 ComputeCRC16(NSData * data)<br />{<br />&nbsp; &nbsp; UI_08*&nbsp; bytes_Ptr;&nbsp; &nbsp; <br />&nbsp; &nbsp; UI_32&nbsp;  length;<br />&nbsp; &nbsp; UI_08&nbsp;  crcHi = 0xFF;&nbsp; &nbsp; &nbsp;  // Polynome initialise a 0xFFFF<br />&nbsp; &nbsp; UI_08&nbsp;  crcLo = 0xFF;<br /><br />&nbsp; &nbsp; UI_08&nbsp;  a;<br />&nbsp; &nbsp; UI_08&nbsp;  b;<br />&nbsp; &nbsp; UI_08&nbsp;  temp_a;<br />&nbsp; &nbsp; UI_08&nbsp;  temp_b;<br /><br />&nbsp; &nbsp; length = [data length];<br />&nbsp; &nbsp; bytes_Ptr = (UI_08*) [data bytes];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; while (length-- &gt; 0)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; a = *bytes_Ptr;<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; a = a ^crcHi;<br />&nbsp; &nbsp; &nbsp; &nbsp; crcHi = a;<br />&nbsp; &nbsp; &nbsp; &nbsp; a = a &gt;&gt; 4;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  // Zero fill<br />&nbsp; &nbsp; &nbsp; &nbsp; a = a ^ crcHi;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // IJKLMNOP<br />&nbsp; &nbsp; &nbsp; &nbsp; crcHi = crcLo;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Swap crcHi, crcLo<br />&nbsp; &nbsp; &nbsp; &nbsp; crcLo = a;<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; temp_a = a;<br />&nbsp; &nbsp; &nbsp; &nbsp; a = (a &lt;&lt; 4) + (temp_a &gt;&gt; 4);&nbsp;  // Rotate A Left 4 times<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // MNOPIJKL<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; b = a;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Temp save<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; temp_a = a;<br />&nbsp; &nbsp; &nbsp; &nbsp; a = (a &lt;&lt; 1) + (temp_a &gt;&gt; 7);&nbsp;  // Rotate A Left once<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // NOPIJKLM<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; a = a &amp; 0x1F;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  // 000IJKLM<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; crcHi = a ^ crcHi;<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; a = b &amp; 0xF0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  // MNOP0000<br />&nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; crcHi = a ^ crcHi;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // crcHi complete<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; temp_b = b;<br />&nbsp; &nbsp; &nbsp; &nbsp; b = (b &lt;&lt; 1) + (temp_b &gt;&gt; 7);&nbsp;  // Rotate B Left once<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // NOP0000M<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; b = b &amp; 0xE0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  // NOP00000<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; crcLo = b ^crcLo;<br /><br /><br />&nbsp; &nbsp; &nbsp; &nbsp; bytes_Ptr++;<br />&nbsp; &nbsp; }<br /><br /><br />&nbsp; &nbsp; return ((UI16)crcHi) &lt;&lt; 8 + crcLo;<br />}<br />
    


    Tu n'es pas très loin, cependant, quelques erreurs:

    <br />		c &gt;&gt;= 7;<br />		a &lt;&lt;= 1;
    

    Ca fait une rotation à  droite de 7 bits  :P
    Pareil pour b.

    <br />loop = 0x00000002
    

    Pourquoi ça? La doc veut dire que le calcul de CRC ne porte pas sur le champ CRC de la trame.

  • ancrouancrou Membre
    16:57 modifié #7
    Merci beaucoup Céroce
    Grâce à  votre programme qui marche nickel, j'ai pu trouver l'erreur.
    UI08_ crcL = 0xFF;<br />UI08_ crcH = 0xFF;
    


    Le 0x0002 c'était pour faire sauter le block CRC de la frame à  analyser.
    On peut aussi le faire, avant de le transmettre à  la fonction CalculCRC,

    Mes c >>= 7 sont correctes c'est comme c = c >> 7


    Si vous passez à  Nancy, je vous paye un coup à  boire  :p (Je suis pas souvent à  Paris  ;) )
  • CéroceCéroce Membre, Modérateur
    16:57 modifié #8
    Y'a pas de quoi, ce sont des choses que je connais bien et ça m'intéressait...
    Je suis d'heureux d'avoir pu te rendre service; et j'espère pouvoir visiter un de ces jours cette très belle ville qu'est Nancy...
Connectez-vous ou Inscrivez-vous pour répondre.