2
int parity (char msg[1400]) {

  int parity = 0;
  int i,j;
  char c;

  for(i=0;i<strlen(msg);i++) {
    for(j=0;j<8;j++) {
      c = msg[i];
      int bit = (c>>j)&1;
      parity ^= bit;
    }
  }

  return parity;
}

This function return a good result, for the next example:

char* msg = malloc(sizeof(char*)*1400);
strcpy(msg,"some string");
int parity = parity(msg);

For next example the result isn't good:

    char* msg = malloc(sizeof(char*)*1400);
    FILE *fp;
    fp = fopen(filename,"r");  //filename is a binary file
    while( !feof(fp) ){
      fread(msg,1399,sizeof(char),fp);
      int parity = parity(msg); //--> the result isn't well
      //.......
    }

I saw strlen(msg) is variable at each step (192,80,200...etc) when i read from file in while. I have to change the "parity" function for second example. Any suggestions?

Alex Petre
  • 37
  • 4
  • 2
    In your last snippet you should define `parity` outside the loop and XOR it with itself at every iteration, like you do inside the function `parity()`. – lodo Mar 27 '15 at 20:21
  • I declare "int parity" because a had an another loop in while, and "int parity" isn't the problem... – Alex Petre Mar 27 '15 at 20:26
  • Then what is the problem? – lodo Mar 27 '15 at 20:27
  • parity is not correct, the result, because i read that char from binary file, i need another function for parity, 1400 are Bytes which are read from binary file and if i do strlen(msg) is far away from 1400 Bytes – Alex Petre Mar 27 '15 at 20:30
  • Your other problem, apart from discarding the parity from earlier reads (as @lodo said), is using `feof()`. http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong?s=2|3.1298 – Weather Vane Mar 27 '15 at 20:31
  • 1
    Another problem can be the presence of null bytes in the file. They put an early end to the string. – lodo Mar 27 '15 at 20:32
  • yes, can be the presence of null bytes in the file, the file is create with dd if=/dev/urandom of=2/5 bs=1024 count=1024 &> /dev/null – Alex Petre Mar 27 '15 at 20:38
  • i need to read first 1400 Bytes and do parity for all – Alex Petre Mar 27 '15 at 20:40

2 Answers2

1

There are other issues besides parity, but let us focus on that one.

Find parity of all bytes, 1 byte at a time rather than 1 bit at a time. Next: the parity of the char. If char is 8 bits, the takes 3 iterations. (log2(CHAR_BIT))

int parity(const char msg[], size_t len) {
  // XOR all bytes together
  unsigned par = 0;
  while (len > 0) {
    par ^= msg[--len];
  }

  // Find char parity 
  unsigned width = CHAR_BIT;
  do {
    par ^= par >> (width/2);  
    width -= width/2;
  } while (width > 1);

  // Only return Least Significant Bit
  return parity % 2;
}

#define Width 1400
char msg[Width];
fread(msg, Width, sizeof *msg, fp);
int par = parity(msg, Width);

If the length of the array is a multiple of sizeof(unsigned). This is a speed improvement by a factor of maybe 4 (sizeof unsigned/sizeof char).

int parity_u(const unsigned msg[], size_t unsigned_len) {
  // XOR all unsigned together
  unsigned par = 0;
  while (len > 0) {
    par ^= msg[--len];
  }

  // Find unsigned parity 
  unsigned width = sizeof *msg * CHAR_BIT;
  do {
    par ^= par >> (width/2);  
    width -= width/2;
  } while (width > 1);

  // Only return Least Significant Bit
  return parity % 2;
}

#define Width (1400/sizeof(unsigned))
unsigned msg[Width];
fread(msg, Width, sizeof *msg, fp);
int par = parity_u(msg, Width);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

I would avoid feof() entirely - fread() tells you how many bytes it read. Also you say it's a binary file, yet you are using string functions - they ain't going to work.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#define BUFMAX 1400

int main(void){
    unsigned char buffer[BUFMAX];
    int i, bit, len, parity = 0;
    FILE *fp;
    if ((fp = fopen("myfile.dat", "rb")) == NULL) {
        printf("Cannot open file\n");
        return 1;
    }
    while ((len = fread(buffer, 1, BUFMAX, fp))) {
        for (i=0; i<len; i++) {
            for (bit=0; bit<CHAR_BIT; bit++) {
                parity ^= (buffer[i] & 1);
                buffer[i] >>= 1;
            }
        }
    }
    fclose (fp);
    printf ("Parity = %d\n", parity);
    return 0;
}
Weather Vane
  • 33,872
  • 7
  • 36
  • 56