aaaaaa123456789 icon

xorfiles

aaaaaa123456789 | PRO | 10/18/14 02:40:33 AM UTC | 0 ⭐ | 727 👁️ | Never ⏰ | []
C |

2.36 KB

|

None

|

0 👍

/

0 👎

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
 
void compute_xor(FILE *, FILE **, unsigned);
inline void xor(void *, const void *, unsigned);
 
int main (int argc, char ** argv) {
  if (argc < 3) {
    fprintf(stderr, "usage: %s outfile infile1 [infile2 [infile3 [... ]]]\n", *argv);
    return 1;
  }
  FILE ** infiles = malloc(sizeof(FILE *) * (argc - 2));
  int fileno;
  for (fileno = 0; fileno < (argc - 2); fileno ++) {
    infiles[fileno] = fopen(argv[fileno + 2], "rb");
    if (!infiles[fileno]) {
      fprintf(stderr, "%s: could not open file %s for reading\n", *argv, argv[fileno + 2]);
      for (fileno --; fileno >= 0; fileno --) fclose(infiles[fileno]);
      return 2;
    }
  }
  FILE * outfile = fopen(argv[1], "wb");
  if (!outfile) {
    fprintf(stderr, "%s: could not open file %s for writing\n", *argv, argv[1]);
    for (fileno --; fileno >= 0; fileno --) fclose(infiles[fileno]);
    return 2;
  }
  compute_xor(outfile, infiles, fileno);
  free(infiles);
  return 0;
}
 
void compute_xor (FILE * out, FILE ** in, unsigned count) {
  unsigned buffer_size = 2 << 20;
  char * buffer = NULL;
  while (!buffer) {
    buffer = malloc(buffer_size);
    buffer_size >>= 1;
    if (!buffer_size) abort();
  }
  unsigned last_read, current_file;
  int rv;
  while (1) {
    memset(buffer, 0, buffer_size);
    last_read = 0;
    for (current_file = 0; current_file < count; current_file ++) {
      if (!in[current_file]) continue;
      rv = fread(buffer + buffer_size, 1, buffer_size, in[current_file]);
      if (rv < buffer_size) {
        fclose(in[current_file]);
        in[current_file] = NULL;
      }
      if (rv) xor(buffer, buffer + buffer_size, rv);
      if (rv > last_read) last_read = rv;
    }
    if (!last_read) break;
    fwrite(buffer, 1, last_read, out);
  }
  fclose(out);
  free(buffer);
}
 
inline void xor (void * destination, const void * source, unsigned length) {
  uint_fast8_t * dstfast = destination;
  const uint_fast8_t * srcfast = source;
  while (length > sizeof(uint_fast8_t)) {
    *(dstfast ++) ^= *(srcfast ++);
    length -= sizeof(uint_fast8_t);
  }
  unsigned char * dstbyte = (unsigned char *) dstfast;
  const unsigned char * srcbyte = (const unsigned char *) srcfast;
  while (length) {
    *(dstbyte ++) ^= *(srcbyte ++);
    length --;
  }
}

Comments