Question

me crois que je l'ai essayé de coder cela, essayé Google, et ne l'ai pas eu de chance. Je suis en train de mettre en œuvre un CRC16 en utilisant ce poly

x^16 + x^10 + x^8 + x^7 + x^3 + 1

en utilisant le langage C. Depuis que je comprends PHP mieux, je suis en train d'obtenir une fonction aller, mais je ne reçois pas la bonne réponse de 28713. Ce code génère un CRC de 32713.

function crc16($string,$crc=0) {

for ( $x=0; $x<strlen( $string ); $x++ ) {

    $crc = $crc ^ ord( $string[$x] );
    echo $crc.'<br />';
    for ($y = 0; $y < 8 ; $y++) {

        if ( ($crc & 0x0001) == 0x0001 ) $crc = ( ($crc >> 1 ) ^ 0x10589  );
        else                             $crc =    $crc >> 1;
    }
}

    return $crc;
}


echo 'CRC:'.crc16('10100011');

S'il vous plaît je vous demande à quiconque de donner un coup de main avec this..thanks à l'avance.

Était-ce utile?

La solution

  1. Certains CRC sont définis pour traiter les bits de chaque octet de MSB à LSB, et certains sont définis à des bits de processus de LSB MSB (celui-ci est généralement de l'ordre qui est décrit comme « réfléchie » et utilise un inversé polynomiale). Votre code met de nouveaux bits dans au LSB fin de la CRC et décalages vers la droite, ce qui convient à un CRC réfléchi, mais CRC-16-DECT semble être l'un des plus de non-réfléchie.

  2. Votre entrée "10100011" suggère binaire, mais est traitée comme une chaîne ASCII à 8 octets.

Pour voir ce qui se passe lors du traitement de 10.100.011 comme lieu binaire et le travail à MSB d'abord, voici un calcul à la main (comme 8 bits d'entrée ne nécessitent pas beaucoup d'effort très):

polynomial coefficients
        |
        |            10100010  <--- quotient (irrelevant)
        v          __________
 10000010110001001 ) 10100011  <-------- input
                   ^ 10000010110001001
                     -----------------
                   =   100001110001001
                     ^ 10000010110001001
                       -----------------
                     =      101110101101
                          ^ 10000010110001001
                            -----------------
   remainder (CRC) -----> =   111000000101001
     = 0x7029 = 28713

traiter donc l'entrée comme binaire et travail MSB premier est la bonne chose à faire.

Voici un code C pour faire le travail (comme je ne suis pas vraiment en PHP, et en fin de compte que vous voulez que du code C de toute façon):

#include <stdio.h>
#include <stdint.h>

static uint16_t crc16(const uint8_t *data, size_t len)
{
    size_t i, j;
    uint16_t crc = 0;

    for (i = 0; i < len; i++) {
        crc ^= (data[i] << 8);              /* data at top end, not bottom */
        for (j = 0; j < 8; j++) {
            if ((crc & 0x8000) == 0x8000)   /* top bit, not bottom */
                crc = (crc << 1) ^ 0x0589;  /* shift left, not right */
            else
                crc <<= 1;                  /* shift left, not right */
        }
    }

    return crc;
}

int main(void)
{
    const uint8_t in[] = { 0xa3 };          /* = 10100011 in binary */
    uint16_t crc = crc16(in, sizeof(in));

    printf("%u (0x%x)\n", crc, crc);
    return 0;
}

Résultat:

$ gcc -Wall -o crc16 crc16.c
$ ./crc16  
28713 (0x7029)
$ 

Autres conseils

Essayez de changer 0x10589 à 0xA001:

function crc16($string,$crc=0) {

    for ( $x=0; $x<strlen( $string ); $x++ ) {

        $crc = $crc ^ ord( $string[$x] );
        for ($y = 0; $y < 8; $y++) {

            if ( ($crc & 0x0001) == 0x0001 ) $crc = ( ($crc >> 1 ) ^ 0xA001 );
            else                             $crc =    $crc >> 1;
        }
    }

    return $crc;
}

Ce code fonctionne à chaque fois, mais je ne comprends pas exactement ce qui se passe.

  char *MakeCRC(char *BitString)
   {
  static char Res[17];                                 // CRC Result
  char CRC[16];
    int  i;
  char DoInvert;

   for (i=0; i<16; ++i)  CRC[i] = 0;                    // Init before calculation

   for (i=0; i<strlen(BitString); ++i)
    {
   DoInvert = ('1'==BitString[i]) ^ CRC[15];         // XOR required?

  CRC[15] = CRC[14];
  CRC[14] = CRC[13];
  CRC[13] = CRC[12];
  CRC[12] = CRC[11];
  CRC[11] = CRC[10];
  CRC[10] = CRC[9] ^ DoInvert;
  CRC[9] = CRC[8]; 
  CRC[8] = CRC[7] ^ DoInvert;
  CRC[7] = CRC[6] ^ DoInvert;
  CRC[6] = CRC[5];
  CRC[5] = CRC[4];
  CRC[4] = CRC[3];
  CRC[3] = CRC[2] ^ DoInvert;
  CRC[2] = CRC[1];
  CRC[1] = CRC[0];
  CRC[0] = DoInvert;
  }

  for (i=0; i<16; ++i)  Res[15-i] = CRC[i] ? '1' : '0'; // Convert binary to ASCII
  Res[16] = 0;                                         // Set string terminator

    return(Res);
    }


     // A simple test driver:

    #include <stdio.h>

   int main()
    {
    char *Data, *Result;                                       // Declare two strings

    Data = "1101000101000111";
    Result = MakeCRC(Data);                                    // Calculate CRC

    printf("CRC of [%s] is [%s] with P=[10000010110001001]\n", Data, Result);

     return(0);
      }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top