diff --git a/man/xor.1 b/man/xor.1 index bd69876..47d88f1 100644 --- a/man/xor.1 +++ b/man/xor.1 @@ -30,7 +30,10 @@ .Nm xor .Op Fl x .Ar MASKBYTE -.Op Ar MASKBYTES ... +.Op Ar MASKBYTE ... +.Nm xor +.Fl s +.Ar MASKSTRING . .Sh DESCRIPTION The basic concept for this utility is to apply a set of mask bytes, repeatedly, @@ -43,6 +46,8 @@ As a filter with the hexadecimal mask bytes applied to the input stream (i.e. .Bq 20 , 2f , 20 , 2f , ... Ns ) .D1 ... | Nm xor Fl x Ar 20 Ar 2f | Li ... +As a filter with a string of characters used as a mask +.D1 ... | Nm xor Fl s Qo Ar " key " Qc | Li ... . .Sh OPTIONS A summary of the options supported by @@ -56,8 +61,12 @@ usage information the program's version .It Fl x explicity interpret mask bytes as hexadecimal digits -.It Ar MASKBYTE Op Ar MASKBYTES ... +.It Fl s +use a string of characters as the mask +.It Ar MASKBYTE Op Ar MASKBYTE ... a list of mask bytes to apply to the input stream +.It Ar MASKSTRING +a string of characters .El . .Sh SEE ALSO diff --git a/src/xor.c b/src/xor.c index 5e2b18f..43738c0 100644 --- a/src/xor.c +++ b/src/xor.c @@ -9,6 +9,7 @@ * */ +#include #include #include #include @@ -26,20 +27,25 @@ int version(bool error) { int usage(bool error, char *prog) { int retval = version(error); - fprintf(WHICHOUT(error), "Usage: %s [-x] MASK [MASK]*\n", prog); + fprintf(WHICHOUT(error), "Usage:\t%s [-x] MASK [MASK]*\n", prog); + fprintf(WHICHOUT(error), "\t%s -s MASKSTRING\n", prog); fprintf(WHICHOUT(error), "\t-x\tmask bytes are hexadecimal\n"); - fprintf(WHICHOUT(error), "\tMASK\ta mask byte\n"); + fprintf(WHICHOUT(error), "\t-s\tuse a string of characters as a mask\n"); + fprintf(WHICHOUT(error), "\n\tMASK\t\ta mask byte\n"); + fprintf(WHICHOUT(error), "\tMASKSTRING\ta string of mask characters\n"); return retval; } void do_xor(uint8_t mask[], int len) { int i = 0; + while (true) { int c = getchar(); if (EOF == c) break; c ^= mask[i]; + putchar(c); i = (i + 1) % len; } @@ -52,11 +58,14 @@ int main(int argc, char *argv[]) { int i; /* option parsing */ - while ((opt = getopt(argc, argv, "hvx")) != -1) { + while ((opt = getopt(argc, argv, "xsvh")) != -1) { switch (opt) { - case 'x': + case 'x': /* hex */ base = 16; break; + case 's': /* string */ + base = -1; + break; case 'v': return version(false); case 'h': return usage(false, argv[0]); default: return usage(true, argv[0]); @@ -65,12 +74,21 @@ int main(int argc, char *argv[]) { if (optind >= argc) return usage(true, argv[0]); - masklen = argc - optind; - uint8_t mask[masklen]; - for (i = optind; i < argc; i++) - mask[i-optind] = (uint8_t)strtol(argv[i], NULL, base); + if (base != -1) { + masklen = argc - optind; + uint8_t mask[masklen]; + for (i = optind; i < argc; i++) + mask[i-optind] = (uint8_t)strtol(argv[i], NULL, base); - do_xor(mask, masklen); + do_xor(mask, masklen); + } else { /* string */ + masklen = strlen(argv[optind]); + uint8_t mask[masklen]; + for (i = 0; i < masklen; i++) + mask[i] = (uint8_t)argv[optind][i]; + + do_xor(mask, masklen); + } return EX_OK; }