: To unbundle, sh this file echo Makefile 1>&2 cat >Makefile <<'End of Makefile' O_FILES = xor.o usage.o help.o CFLAGS = CC = gcc xor: $(O_FILES) $(CC) $(CFLAGS) -o xor $(O_FILES) End of Makefile echo Test 1>&2 cat >Test <<'End of Test' # echo "xor -s 11111 -f test.txt -k KEY > test_encrypted.txt" xor -s 11111 -f test.txt -k KEY > test_encrypted.bin # echo "uuencode test_encrypted.bin test_encrypted.bin > test_encrypted.bin.uu.txt" uuencode test_encrypted.bin test_encrypted.bin > test_encrypted.bin.uu.txt # echo "rm test_encrypted.bin" rm test_encrypted.bin # echo "uudecode test_encrypted.bin.uu.txt" uudecode test_encrypted.bin.uu.txt # echo "xor -s 11111 -f test_encrypted.bin -k KEY > test_unencrypted.txt" xor -s 11111 -f test_encrypted.bin -k KEY > test_unencrypted.txt # echo "diff test_unencrypted.txt test.txt" diff test_unencrypted.txt test.txt End of Test echo test.txt 1>&2 cat >test.txt <<'End of test.txt' Gettysburg Address Delivered on the 19th Day of November, 1863 Cemetery Hill, Gettysburg, Pennsylvania Fourscore and seven years ago, our fathers brought forth upon this continent a new Nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now, we are engaged in a great Civil War, testing whether that Nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war. We have come to dedicate a portion of that field as a final resting-place for those who gave their lives that that Nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we cannot dedicate, we cannot consecrate, we cannot hallow this ground. The brave men, living and dead, who struggled here, have consecrated it far above our power to add or detract. The world will little note nor long remember what we say here, but it can never forget what they did here. It is for us, the living, rather to be dedicated to the great task remaining before us; that from these honored dead, we take increased devotion to that cause for which they gave the last full measure of devotion; that this Nation, under GOd, shall have a new birth of freedom; and that government of the People by the People and for the People shall not perish from the earth." Abraham Lincoln End of test.txt echo help.c 1>&2 cat >help.c <<'End of help.c' /* * help - give program help */ #include help(argv) char** argv; { fprintf(stderr, "%s: HELP:\n", argv[0]); fprintf(stderr, "\n"); fprintf(stderr, " xor - perform \"exclusive or\" on two files byte-at-a-time\n"); fprintf(stderr, "\n"); fprintf(stderr, " This program takes an input file and a key file and performs\n"); fprintf(stderr, " an \"exclusive or\" on them byte-at-a-time, and writes the result\n"); fprintf(stderr, " to standard output. Optionally, a number of bytes may be skipped\n"); fprintf(stderr, " first in the key file.\n"); fprintf(stderr, "\n"); fprintf(stderr, " This operation can be used to both encrypt and decrypt plain text\n"); fprintf(stderr, " or other data using the \"one time pad\" method, which employs an\n"); fprintf(stderr, " extremely long key (longer than the plain text message) and is\n"); fprintf(stderr, " theoretically unbreakbale if the key is truly random.\n"); fprintf(stderr, "\n"); } /* end of help */ End of help.c echo usage.c 1>&2 cat >usage.c <<'End of usage.c' /* * usage - give program usage */ #include usage(argv) char** argv; { fprintf(stderr, "%s: USAGE: %s [flags] > outfile\n", argv[0], argv[0]); fprintf(stderr, "\n"); fprintf(stderr, " flag meaning default\n"); fprintf(stderr, " ------------- ------------------------------------ -------\n"); fprintf(stderr, " -f input file (plain text or encrypted) [none]\n"); fprintf(stderr, " -k key filename [none]\n"); fprintf(stderr, " -s number of bytes to skip in key file 0\n"); fprintf(stderr, "\n"); fprintf(stderr, " -D debug FALSE \n"); fprintf(stderr, " -h help on this program \n"); fprintf(stderr, " -u usage (this message) \n"); fprintf(stderr, "\n"); } /* end of usage */ End of usage.c echo xor.c 1>&2 cat >xor.c <<'End of xor.c' /** ** xor - exclusive or two files ** ** CREATED: 99.08.23 ABS copied from simple_diff ** MODIFIED: 99.09.01 ABS got working ** MODIFIED: 99.09.04 ABS added skip and self-doc ** **/ #include "xor.h" main(argc, argv) int argc; char** argv; { /* declare functions */ double atof(); char xor(); /* declare local variables */ FILE *stream1; FILE *stream2; char c1, c2; int s; int stillReading = TRUE; int j = 0; int n1, n2; /* initialize global variables (including parameters) */ defaultParms(); parseArgs(argc, argv); /* initialize local variables */ /* open */ if (Debug != FALSE) { fprintf(stdout, "%s: DEBUG: Filename1 = %s\n", argv[0], Filename1); fprintf(stdout, "%s: DEBUG: Filename2 = %s\n", argv[0], Filename2); } stream1 = fopen (Filename1, "r+b"); if (stream1 == 0) { fprintf(stdout, "%s: ERROR opening file %s\n", argv[0], Filename1); exit(-1); } stream2 = fopen (Filename2, "r+b"); if (stream2 == 0) { fprintf(stdout, "%s: ERROR opening file %s\n", argv[0], Filename2); exit(-1); } for (s = 0; s < Skip; s++) { #ifdef NT n2 = fread(&c2, 1, 1, stream2); #else c2 = (char)getc(stream2); #endif NT if (feof(stream2)) { fprintf(stdout, "%s: ERROR skip value is longer thsn key file %s\n", argv[0], Filename2); exit(-1); } } /* read & write */ while (stillReading) { j++; #ifdef NT n1 = fread(&c1, 1, 1, stream1); n2 = fread(&c2, 1, 1, stream2); #else c1 = (char)getc(stream1); c2 = (char)getc(stream2); #endif NT if (feof(stream1) || feof(stream2)) { exit(0); } #ifdef NT else if (n1 != 1) { fprintf(stdout, "%s: ERROR reading file %s on character %d\n", argv[0], Filename1, j); exit(-1); } else if (n2 != 1) { fprintf(stdout, "%s: ERROR reading file %s on character %d\n", argv[0], Filename2, j); exit(-1); } #endif NT putchar(xor(c1, c2)); if (Debug != FALSE && j < 55) { fprintf(stdout, "%s: DEBUG: c1 = %c = %d\n", argv[0], (char)c1, c1); fprintf(stdout, "%s: DEBUG: c2 = %c = %d\n", argv[0], (char)c2, c2); } } /* end while */ if (Debug != FALSE) { fprintf(stdout, "%s: DEBUG: j = %d\n", argv[0], j); } } /* end main */ /* * defaultParms - initialize global variables */ defaultParms() { Debug = FALSE; Skip = 0; } /* end defaultParms() */ /* * parseArgs - parse arguments into global variables */ parseArgs(argc, argv) int argc; char** argv; { int i; for (i = 0; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'f' : strcpy(Filename1, (char *)&argv[++i][0]); break; case 'k' : strcpy(Filename2, (char *)&argv[++i][0]); break; case 'D' : Debug = TRUE; break; case 'h' : help(argv); exit(0); break; case 's' : Skip = atoi(&argv[++i][0]); break; case 'u' : usage(argv); exit(0); break; default: fprintf(stdout, "%s: ERROR: illegal flag: %s\n", argv[0], argv[i]); usage(argv); exit(0); break; } /* end switch */ } /* end if */ } /* end for(i) */ } /* end parseArgs() */ char xor(c1, c2) char c1; char c2; { int i; char c3; char masks[8]; masks[0] = (char)0x01; /* bit 0 */ masks[1] = (char)0x02; /* bit 1 */ masks[2] = (char)0x04; /* bit 2 */ masks[3] = (char)0x08; /* bit 3 */ masks[4] = (char)0x10; /* bit 4 */ masks[5] = (char)0x20; /* bit 5 */ masks[6] = (char)0x40; /* bit 6 */ masks[7] = (char)0x80; /* bit 7 */ c3 = (char)0; for (i = 0; i < 8; i++) { if (((masks[i] & c1) && !(masks[i] & c2)) || (!(masks[i] & c1) && (masks[i] & c2))) { c3 += masks[i]; } } return c3; } End of xor.c echo xor.h 1>&2 cat >xor.h <<'End of xor.h' /* * xor.h -- include file for xor.c */ /* includes */ #include #include #include /* constants */ #define TRUE (1) #define FALSE (0) /* global variables */ float FloatGlobal; /* float: a real number */ int IntGlobal; /* integer: a signed whole number */ char Filename1[255]; char Filename2[255]; /* flag-settable parameters (global variables) */ int Debug; /* Boolean: TRUE = debug writes */ int Skip; /* integer: number of bytes to skip in key */ End of xor.h