c 我如何 return 从二进制文件中读取字符的奇偶校验

c How can i return a parity of char read from binary file

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;
}

这个函数return效果不错,下一个例子:

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

对于下一个示例,结果不好:

    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
      //.......
    }

当我从文件中读取时,我看到 strlen(msg) 在每一步(192,80,200...等)都是可变的。我必须为第二个示例更改 "parity" 函数。有什么建议吗?

我会完全避免 feof() - fread() 告诉您它读取了多少字节。你还说它是一个二进制文件,但你正在使用字符串函数 - 它们不会起作用。

#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;
}

除了奇偶校验之外还有其他问题,但让我们专注于那个。

查找所有字节的奇偶校验,一次 1 个字节而不是一次 1 个位。接下来:char的奇偶校验。如果 char 是 8 位,则需要 3 次迭代。 (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);

如果数组的长度是sizeof(unsigned)的倍数。速度提高了 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);