Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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 --;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement