/*
  fichier positif.c
  fonction : étudier les formes des "faux positifs"
    avec les configurations de Fibonacci et de Galois
  compilation :
    gcc -Wall -Os -o positif positif.c
  Attention : Ne marche correctement
       que sur machine Little Endian !
*/

#include <stdio.h>

char message[]="GNU/Linux Magazine France";

#define CRC16_Galois(registre, data_in)   \
  registre = (registre+registre) ^ (0x8005 & \
    (((signed short int) (registre ^ ((data_in & 1) << 15))) >> 15));

#define CRC16_Fibonacci(registre, data_in) \
  registre = (registre+registre)           \
           ^ (1 &  (data_in                \
                   ^ (registre >> 1)       \
                   ^ (registre >> 14)      \
                   ^ (registre >> 15)  ));

#define SEED 12345

void calcul_CRC() {
  int i, j;
  unsigned short int
    lfsr_galois=SEED,
    lfsr_fibonacci=SEED;
  char c;

  for (i=0; i<sizeof(message)-1; i++) {
    c=message[i];

    for (j=0; j<8; j++) {
      CRC16_Galois(lfsr_galois,c)
      CRC16_Fibonacci(lfsr_fibonacci,c)
      c>>=1;
    }
  }

  printf("CRC Galois : 0x%04X, CRC Fibo : 0x%04X\n",
       lfsr_galois, lfsr_fibonacci);
}

int main(void) {
  /* calcul du CRC normal */
  calcul_CRC();

  /* modification du message (! little endian !) */
  *(long int *)message ^= 9 *
/*     ((1 << 16) | (1 << 14) | (1 << 1) | (1 << 0)); */
     ((1 << 16) | (1 << 15) | (1 << 2) | (1 << 0));

  /* calcul du nouveau CRC */
  calcul_CRC();

  return 0;
}
