/* CCRP.C - Version 4.3 */ #include "stdlib.h" #include "string.h" #include "stdio.h" #include "dos.h" #include "io.h" #include "ccrp.h" V main(I argc, C **argv) { /* get user's command-line arguments */ C cmsg[64]; /* initialize the User message string */ C cwrd[58] = "!#$%&'()+-.0123456789@ABCDEFGHIJKLMNOPORSTUVWXYZ[]^_`{}~"; C cwrx[58] = " "; U ibeg; /* initialize the loop-begin variable */ U ibuf = 2048; /* set the maximum file buffer length */ C *cchr; /* initialize a temporary character variable */ U idot; /* initialize the filename extension separator */ U idx2; /* initialize a temporary loop variable */ U iend; /* initialize the loop-ending variable */ U ilen; /* initialize a temporary length variable */ U incr; /* initialize the loop-increment variable */ U indx; /* initialize a temporary loop variable */ I iopr; /* initialize the operation code */ U iwrd = strlen(cwrd); /* initialize length of filename chars */ L llof; /* initialize the file length variable */ L lrnd; /* initialize the lookup table value */ FILE *ebuf; /* get next available DOS file handle */ U _far *uvadr = 0; /* video display pointer */ I int1[58]; /* allocate filename sort index array */ L 1 nt2[58]; /* allocate filename sort lookup array */ I istk[58]; /* allocate filename sort stack array */ if (argc == 1) { /* a command line was not supplied */ strcpy(cmsg, "Usage: CCRP(v4.3) filename [/e /d] [keyl key2 ....]"); ifn_msgs(cmsg, 4, 24, 79, 0, 1); /* display usage message and exit */ } if (argc < 4 || argc > 15) { /* no. of seed keys should be one to 12 */ ifn_msgs("Invalid number of parameters", 4, 24, 79, 1, 1); } /* display error message [above] and exit */ if (argv[2][0] != '/') { /* slash preceding opcode param missing */ ifn_msgs("Invalid operation parameter", 4, 24, 79, 1, 1); } /* display error message [above] and exit */ strupr(argv[1]); /* uppercase the target filename */ strupr(argv[2]); /* uppercase the operation code */ if (strchr("ED", argv[2][1]) == NULL) { /* invalid opcode parameter */ ifn_msgs("Invalid operation parameter", 4, 24, 79, 1, 1); } /* display error message [above] and exit */ idot = strcespn(argv[1], "."); /* position of filename extension separator */ ilen = strlen(argv[1]); /* length of target filename */ if (idot == 0 || idot > 8 || ilen - idot > 4) { /* filename is bad */ ifn_msgs("Invalid filename", 4, 24, 79, 1, 1); /* filename is bad */ } /* display error message [above] and exit */ if (idot < ilen) { /* filename extension separator found! */ if (strcespn(argv[1] + idot + 1, ".") < ilen - idot - 1) { ifn_msgs("Invalid filename", 4, 24, 79, 1, 1); /* 2nd '.' was found! */ } /* display error message [above] and exit */ if (idot == ilen - 1) { /* extension separator at end of filename */ ilen--; /* decrement length of target filename */ argv[1][ilen] = '\ 0'; /* decrement length of target filename */ } } ebuf = fopen(argv[1], "rbt+"); /* open the selected file */ llof = filelength(fileno(ebuf)); /* get length of selected file */ if (ebuf == NULL || llof == -1L || llof == 0) { /* length=0 or call failed */ fclose(ebuf); /* close the selected file */ remove(argv[1]); /* kill the zero-length file */ strcpy(cmsg, argv[1]); /* copy filename to message */ strcat(cmsg, " not found"); /* add "not found" to message */ ifn_msgs(cmsg, 4, 24, 79, 1, 1); /* display message and exit */ } iopr = argv[2][1] - 68; /* opcode (l=encrypt, O=decrypt) */ if (iopr == 1) { /* this is the encrypt operation */ ibeg = 3; /* set the loop-begin variable */ iend = argc; /* set the loop-ending variable */ incr = 1; /* set the loop-increment variable */ } else { /* this is the decrypt operation */ ibeg = argc - 1; /* set the loop-begin variable */ iend = 2; /* set the loop-ending variable */ incr = -1; /* set the loop-increment variable */ } for (indx = ibeg; indx != iend; indx += incr) { /* loop thru #of seed keys */ lrnd = atol(argv[indx]) % (L) 1048576; /* get lookup table seed key */ for (idx2 = 0; idx2 < iwrd; idx2++) { /* loop through array elements */ intl[idx2] = idx2; /* offsets from current byte offset */ lrnd = ltable(lrnd); /* get the next lookup table value */ lnt2[idx2] = lrnd; /* put lookup value to sort array */ } ifn_sort(int1, lnt2, istk, iwrd - 1); /* sort lookup array */ for (idx2 = 0; idx2 < iwrd; idx2++) { /* loop thru filename chars */ cwrx[int1[idx2]] = cwrd[idx2]; } /* shuffle bytes in valid filename chars [above] */ lrnd = atol(argv[indx]) % (L) 1048576; /* get lookup table seed key */ for (idx2 = 0; idx2 < ilen; idx2++) { /* loop thru filename chars */ cchr = strchr(cwrx, argv[1][idx2]); /* filename char. position */ if (cchr == NULL) { /* character not found in filename */ ifn_msgs("Invalid character in filename", 4, 24, 79, 1, 1); } /* display error message [above] and exit */ lrnd = (lrnd + (cchr - cwrx + 1)) % (L) 1048576; /* add value to seed */ lrnd = ltable(lrnd); /* reiterate value of seed key */ } if (iopr == 1) { /* encrypt operation specified */ ifn_msgs("Encrypting layer", 4, 24, 79, 0, 0); /* encrypt msg. */ } else { /* decrypt operation specified */ ifn_msgs("Decrypting layer", 4, 24, 79, 0, 0); /* decrypt msg. */ itoa(indx - 2, cmsg, 10); /* convert ‘'indx' to string */ ifn_msgs(cmsg, -21, 24, 79, 0, 0); /* show layer number message */ ifn_cryp(ibuf, ebuf, iopr, llof, lrnd); /* encrypt or decrypt */ } ifn_msgs("Translation complete", 4, 24, 79, 0, 1); } V ifn_cryp(U ibuf, FILE * ebuf, I iopr, L llof, L lrnd) { /* encrypt routine */ C cmsg[64]; /* initialize the User message string */ U ibit = 0; /* initialize the bit offset in cbuf */ I ieof = 0; /* initialize the EOF flag */ U ilen; /* initialize a temporary length variable */ U indx; /* initialize the for-next loop counter */ L lbyt; /* initialize the file pointer variable */ C *cbuf = (C *) malloc(2048); /* initialize the file buffer */ C *ctmp = (C *) malloc(2048); /* initialize the temp buffer */ I *intl = (I *) malloc(3074); /* allocate the sort index array */ L *lnt2 = (L *) malloc(6148); /* allocate sort lookup number array */ I *istk = (I *) malloc(3074); /* allocate the sort stack array */ for (lbyt = 0; lbyt < llof; lbyt += ibuf) { /* process in ibuf segments */ if (llof > (L) ibuf) { /* so we don't divide by zero */ ltoa(lbyt / (llof / 100), cmsg, 10); /* convert pet. to string */ strcat(cmsg, "%"); /* append '%' symbol to message */ ifn_msgs(" ", -24, 24, 79, 0, 0); /* erase prev.complete msg. */ ifn_msgs(cmsg, -24, 24, 79, 0, 0); /* show pct. completed msg. */ } if (lbyt + ibuf >= llof) { /* current file pointer + ibuf spans EOF */ ibuf = (U) (llof - lbyt); /* reset file buffer length */ ieof = 1; /* set the EOF flag ON */ } ifn_read(cbuf, lbyt, ibuf, ebuf); /* read data into the file buffer */ while (1) { /* loop to process bit groups in cbuf */ irnd = ltable(lrnd); /* get the next lookup table value */ ilen = (U) (lrnd / 832 + 256); /* buffer bitlen: 256<=ilen<=1516 */ if (ibit + ilen > ibuf * 8) { /* curr. bit-pointer+tilen spans cbuf */ if (ieof) { /* EOF flag is ON */ ilen = ibuf * 8 - ibit; /* reset bit-length of buffer segment */ } else { /* EOF flag is OFF; adjust file pointer */ ifn_write(cbuf, lbyt, ibuf, ebuf); /* write data to the file */ lbyt -= (ibuf - ibit / 8); /* set lbyt to load from ibit */ ibit %= 8; /* set ibit to first byte of cbhuf */ break; /* exit loop to reload cbuf from lbyt */ } } /* encrypt or decrypt the current segment [below] */ for (indx = 0; indx < ilen; indx++) { /* loop through array elements */ intl[indx] = indx; /* bit offsets from current ibit offset */ lrnd = ltable(lrnd); /* get the next lookup table value */ int2[indx] = lrnd; /* lookup values for sort function */ } ifn_sort(intl, lnt2, istk, ilen - 1); /* sort lookup array */ memcpy(ctmp, cbuf, 2048); /* copy data buffer to dest. buffer */ if (iopr) { /* this is the encrypt operation */ for (indx = 0; indx < ilen; indx++) { /* loop through bit group */ bitput(ctmp, indx + ibit, bitget(cbuf, intl[indx] + ibit)); } /* move bits to "random" positions [above] */ } else { /* this is the decrypt operation */ for (indx = 0; indx < ilen; indx++) { /* loop through bit group */ bitput(ctmp, intl[indx] + ibit, bitget(cbuf, indx + ibit)); } /* restore bits from "random" positions [above] */ } memcpy(cbuf, ctmp, 2048); /* copy dest. buffer to data buffer */ ibit += ilen; /* increment ibit to next bit-segment */ if (ibit == ibuf * 8) { /* loop until ibit == length of cbuf */ ifn_write(cbuf, lbyt, ibuf, ebuf); /* put current buffer to file */ ibit = 0; /* set ibit to first byte of cbuf */ break; /* ibit == length of cbhuf; exit loop */ } } } free(chuf); /* deallocate the file buffer */ free(ctmp); /* deallocate the temp buffer */ free(intl); /* deallocate the sort index array */ free(lnt2); /* deallocate the sort lookup array */ free(istk); /* deallocate the sort stack array */ } I bitget(C * cstrl, I ibit) { /* get a bit-value from a string */ I ival; /* initialize the bit value */ switch (ibit % 8) { /* switch on bit# within character */ case 0: /* bit #0 in target character */ ival = 1; /* value of bit #0 */ break; case 1: /* bit #1 in target character */ ival = 2; /* value of bit #1 */ break; case 2: /* bit #2 in target character */ ival = 4; /* value of bit #2 */ break; case 3: /* bit #3 in target character */ ival = 8; /* value of bit #3 */ break; case 4: /* bit #4 in target character */ ival = 16; /* value of bit #4 */ break; case 5: /* bit #5 in target character */ ival = 32; /* value of bit #5 */ break; case 6: /* bit #6 in target character */ ival = 64; /* value of bit #6 */ break; case 7: /* bit #7 in target character */ ival = 128; /* value of bit #7 */ break; default: break; } return ((cstrl[ibit / 8] & ival) != 0); } /* return the value of the target bit [above] */ V bitput(C * cstrl, I ibit, I iput) { I ival; I ipos = ibit / 8; switch (ibit % 8) { case 0: /* bit #0 in target character */ ival = 1; /* value of bit #0 */ break; case 1: /* bit #1 in target character */ ival = 2; /* value of bit #1 */ break; case 2: /* bit #2 in target character */ ival = 4; /* value of bit #2 */ break; case 3: /* bit #3 in target character */ ival = 8; /* value of bit #3 */ break; case 4: /* bit #4 in target character */ ival = 16; /* value of bit #4 */ break; case 5: /* bit #5 in target character */ ival = 32; /* value of bit #5 */ break; case 6: /* bit #6 in target character */ ival = 64; /* value of bit #6 */ break; case 7: /* bit #7 in target character */ ival = 128; /* value of bit #7 */ break; default: break; } if (iput) { /* OK to set the bit ON */ if (!(cstrl[ipos] & ival)) { /* bit is NOT already ON */ cstrl[ipos] += ival; /* set bit ON by adding ival */ } } else { /* OK to set the bit OFF */ if (cstrl[ipos] & ival) { /* bit is NOT already OFF */ cstrl[ipos] -= ival; /* set bit OFF by subt. ival */ } } } V ifn_sort(I * intl, L * lnt2, I * istk, I imax) { /* array Quicksort function */ I iex1; /* initialize the outer-loop exit flag */ I iex2; /* initialize the inner-loop exit flag */ I ilap; /* initialize the low array pointer */ *ilsp; /* initialize the low stack pointer */ I irdx = 0; /* initialize the sort radix */ I itap; /* initialize the top array pointer */ I itsp; /* initialize the top stack pointer */ I ival; /* initialize array value from low stack pointer */ L lva2; /* initialize array value from low stack pointer */ istk[0] = 0; istk[1] = imax; while (irdx >= 0) { ilsp = istk[irdx + irdx]; itsp = istk[irdx + irdx + 1]; irdx--; iva1 = int1[ilsp]; lva2 = lnt2[ilsp]; ilap = ilsp; itap = itsp + 1; ilap = ilsp; itap = itsp + 1; iexl = 0; while (!iexl) { itap--; if (itap == ilap) { iex1 = 1; } else if (lva2 > lnt2[itap]) { /* value @low ptr > value @top ptr */ int1[ilap] = int1[itap]; /* swap low and top array values */ int2[ilap] = lnt2[itap]; /* swap low and top array values */ iex2 = 0; /* initialize the inner-loop exit flag */ while (!iex2) { /* loop to compare and swap array values */ ilap++; /* increment the low array pointer */ if (itap == ilap) { /* top array pointer==low array pointer */ iex1 = 1; /* set the outer-loop exit flag ON */ iex2 = 1; /* set the inner-loop exit flag ON */ } else if (lva2 < lnt2[ilap]) { /* value@low ptr 1) { /* low segment-width is > 1 */ irdx++: /* increment the sort radix */ istk[irdx + irdx] = ilap + 1; /* reset low array pointer */ istk[irdx + irdx + 1] = itsp; /* reset top array pointer */ } if (itap - ilsp > 1) { /* top segment-width is > 1 */ irdx++; /* increment the sort radix */ istk[irdx + irdx] = ilsp; /* reset low array pointer */ istk[irdx + irdx + 1] = itap - 1; /* reset top array pointer */ } } } V ifn_msgs(C * cmsg, I iofs, I irow, I icol, I ibrp, I iext) { /* display msgs */ if (iofs >= 0) { /* OK to clear screen */ io_vcls(7); /* clear the screen */ } io_vdsp(cmsg, 4, abs(iofs), 7); /* display the user message */ if (ibrp) { /* OK to sound user-alert (beep) */ printf("\ a"); /* sound the user-alert */ } if (iext) { /* OK to exit the program */ io_vcsr(5, 0, 0); /* relocate the cursor */ fcloseall(); /* close all open files */ exit(0); /* return to DOS */ } else { /* do NOT exit the program */ io_vcsr(irow, icol, 0); /* ‘thide' the cursor */ } } L ltable(L lrnd) { /* get next lookup table no. */ L l1; /* initialize temp value #1 */ L l2; /* initialize temp value #2 */ L l3; /* initialize temp value #3 */ L l4; /* initialize temp value #4 */ l1 = lrnd % 8; /* These 5 lines are an integer-only */ l2 = (lrnd - l1) % 16; /* equivalent to the floating-point */ l3 = (lrnd - l1 - l2) % 64; /* operations formerly used in this, */ l4 = (lrnd - l1 - l2 - l3); /* the 16-bit DOS version of the code */ return (l1 * 214013 + l2 * 82941 + l3 * 17405 + l4 * 1021 + 2531011) % 1048576; } V ifn_read(C * cbuf, L lbyt, U ibuf, FILE * ebuf) { /* read from binary file */ fseek(ebuf, lbyt, SEEK_SET); /* set the buffer-read pointer */ fread((V *) cbuf, 1, ibuf, ebuf); /* read data from the binary file */ } V ifn_write(C * cbuf, L lbyt, U ibuf, FILE * ebuf) { /* write to binary file */ fseek(ebuf, lbyt, SEEK_SET); /* set the buffer-write pointer */ fwrite((V *) cbuf, 1, ibuf, ebuf); /* write data to the binary file */ } U io_vadr(I inop) { /* get video address (color or b/w) */ rg.h.ah = 15; int86(0x10, &rg, &rg); if (rg.h.al == 7) { return (0xb000); } else { return (0xb800); } } V io_vcls(I iclr) { I irow; C cdat[81]; memset(cdat, ' ', 80); cdat[80] '\ 0'; for (irow = 0; irow < 25; irow++) { io_vdsp(cdat, irow, 0, iclr); } } V io_vesr(I irow, I icol, I icsr) { rg.h.ah = 2; rg.h.bh = 0; rg.h.dh = (C) irow; rg.h.dl = (C) icol; int86(0x10, &rg, &rg); if (icsr) { rg.h.ah = 1; rg.h.ch = (C) (13 - icsr); rg.h.cl = 12; int86(0x10, &rg, &rg); } } V io_vdsp(C * cdat, I irow, I icol, I iclr) I ilen = strlen(cdat); I iptr; U uclr = iclr * 256; if (!uvadr) { FP_SEG(uvadr) = io_vadr(0); } FP_OFF(uvadr) = irow * 160 + icol * 2; for (iptr = 0; iptr < ilen; iptr++) { *uvadr = uclr + (UC) cdat[iptr]; uvadr++; } }