home *** CD-ROM | disk | FTP | other *** search
- (*$R-,V-,S-*)
- PROGRAM Decrypt( Input , Output );
-
- (*----------------------------------------------------------------------*)
- (* Decrypt --- Vigenere decryption program *)
- (*----------------------------------------------------------------------*)
- (* *)
- (* Author: Philip R. Burns. *)
- (* *)
- (* Date: January, 1989 *)
- (* Version: 1.0 (January, 1989) *)
- (* 1.1 (April, 1989) *)
- (* *)
- (* Systems: VAX/VMS and IBM PC Turbo Pascal. *)
- (* *)
- (* Usage: On the Vax: *)
- (* *)
- (* Prepare a file called DEC.COM with the following *)
- (* DCL statements: *)
- (* *)
- (* $ assign/user 'p1' pas$input *)
- (* $ assign/user 'p2' pas$output *)
- (* $ run decrypt *)
- (* *)
- (* Define an appropriate DCL command like the following: *)
- (* *)
- (* Decrypt == "@DEC" *)
- (* *)
- (* Then to decrypt a file, enter: *)
- (* *)
- (* Decrypt source result *)
- (* *)
- (* source --- name of source file to be decrypted *)
- (* result --- name of result file after decryption *)
- (* *)
- (* Example: *)
- (* *)
- (* Decrypt mymess.enc mymess.let *)
- (* *)
- (* On the PC: *)
- (* *)
- (* Decrypt <source >result *)
- (* *)
- (* Example: *)
- (* *)
- (* Decrypt <mymess.enc >mymess.let *)
- (* *)
- (* Remarks: This program decrypts a text file which has been *)
- (* encrypted using a variation of the Vigenere substitution *)
- (* cipher by the companion program "encrypt." *)
- (* *)
- (* "/*" and "*/" are used in place of the usual comment *)
- (* delimeters in the nested comments for the "other" *)
- (* machine, since the Vax doesn't like nested comments. *)
- (* *)
- (* I am contributing this program to the public domain. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- { ===== START VAX/VMS CODE ===== }
- { }
- { TYPE }
- { AnyStr = VARYING[255] OF CHAR /* Varying length string */; }
- { LongInteger = INTEGER /* 32-bit integer type */; }
- { }
- { ===== END VAX/VMS CODE ===== }
-
- { ===== START PC TURBO PASCAL CODE ===== }
-
- TYPE
- AnyStr = STRING[255] (* Varying length string *);
- LongInteger = LONGINT (* 32-bit integer type *);
-
- { ===== END PC TURBO PASCAL CODE ===== }
-
- CONST
- First_Char = 0 (* First ascii character = NUL *);
- Last_Char = 127 (* Last ascii character = DEL *);
- Control_End = 31 (* Last ascii control character *);
- Blank_Char = 32 (* Ascii blank *);
-
- (* # of non-control characters *)
-
- Span = ( Last_Char - Blank_Char );
-
- VAR
- MsgLine : AnyStr (* One line of message *);
- StringKey : AnyStr (* Decryption string *);
- RanSeed : LongInteger (* Random number seed *);
-
- (*----------------------------------------------------------------------*)
- (* Portable random-number generator routines. *)
- (*----------------------------------------------------------------------*)
- (* *)
- (* These routines provide a portable way of producing uniformly *)
- (* distributed random numbers between 0 and 1. The reason for *)
- (* using these routines rather than the standard system routines *)
- (* is so that files may be encrypted on one machine, e.g., the Vax, *)
- (* and then decrypted on the PC, or vice versa. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- CONST
- M = 714025;
- IA = 1366;
- IC = 150889;
- RM = 1.400512E-6;
-
- VAR
- Y : LongInteger;
- R : ARRAY[1..97] OF LongInteger;
-
- (*----------------------------------------------------------------------*)
- (* SetRandom --- Set the seed for the random number generator *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE SetRandom( VAR Seed : LongInteger );
-
- VAR
- J : INTEGER;
-
- BEGIN (* SetRandom *)
-
- IF ( Seed > 0 ) THEN
- Seed := -Seed;
-
- Seed := ( IC - Seed ) MOD M;
-
- FOR J := 1 TO 97 DO
- BEGIN
- Seed := ( IA * Seed + IC ) MOD M;
- R[ J ] := Seed;
- END;
-
- Seed := ( IA * Seed + IC ) MOD M;
- Y := Seed;
-
- END (* SetRandom *);
-
- (*----------------------------------------------------------------------*)
- (* Random --- Get a uniform random number between 0 and 1 *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Random( VAR Seed : LongInteger ) : REAL;
-
- VAR
- J : INTEGER;
-
- BEGIN (* Random *)
-
- J := 1 + ( 97 * Y ) DIV M;
-
- IF ( J < 1 ) THEN
- J := 1
- ELSE IF ( J > 97 ) THEN
- J := 97;
-
- Y := R[ J ];
- Random := Y * RM;
-
- Seed := ( IA * Seed + IC ) MOD M;
- R[ J ] := Seed;
-
- END (* Random *);
-
- (*----------------------------------------------------------------------*)
- (* Decode --- Decryption of text using Vigenere algorithm *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Decode( VAR Message : AnyStr );
-
- VAR
- Index : INTEGER;
-
- BEGIN (* Decode *)
-
- FOR Index := 1 TO LENGTH( Message ) DO
- IF ( ( ORD( Message[ Index ] ) > Control_End ) AND
- ( ORD( Message[ Index ] ) < Last_Char ) ) THEN
- Message[ Index ] := CHR( ( ORD( Message[ Index ] ) - Blank_Char + Span -
- TRUNC( Random( RanSeed ) * Span ) ) MOD Span +
- Blank_Char );
-
- END (* Decode *);
-
- (*----------------------------------------------------------------------*)
- (* LXOR --- Find logical exclusive OR of two integers *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION LXOR( I , J : LongInteger ) : LongInteger;
-
- VAR
- BXOR : LongInteger;
-
- BEGIN (* LXOR *)
-
- { ===== START VAX/VMS CODE ===== }
- { }
- { BXOR :: BOOLEAN := XOR( I :: BOOLEAN , J :: BOOLEAN ); }
- { LXOR := BXOR; }
- { }
- { ===== END VAX/VMS CODE ===== }
-
- { ===== START PC TURBO PASCAL CODE ===== }
-
- LXOR := I XOR J;
-
- { ===== END PC TURBO PASCAL CODE ===== }
-
- END (* LXOR *);
-
- (*----------------------------------------------------------------------*)
- (* LSHL --- Perform left shift of integer by specified # of bits *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION LSHL( I : LongInteger; NBits : INTEGER ) : LongInteger;
-
- BEGIN (* LSHL *)
-
- { ===== START VAX/VMS CODE ===== }
- { }
- { LSHL := I * ( 2 ** NBits ); }
- { }
- { ===== END VAX/VMS CODE ===== }
-
- { ===== START PC TURBO PASCAL CODE ===== }
-
- LSHL := I SHL NBits;
-
- { ===== END PC TURBO PASCAL CODE ===== }
-
- END (* LSHL *);
-
- (*----------------------------------------------------------------------*)
- (* Calc_Hash --- Hash key string to find seed for random number *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Calc_Hash( Key : AnyStr ) : LongInteger;
-
- VAR
- Index : INTEGER;
- Sum : LongInteger;
-
- BEGIN (* Calc_Hash *)
-
- Sum := 0;
- (* Exclusive OR characters together *)
-
- FOR Index := 1 TO LENGTH( Key ) DO
- Sum := LXOR( LSHL( Sum , 1 ) , ORD( Key[ Index ] ) );
-
- (* Square result and subtract 31 to *)
- (* produce initial seed. *)
- Calc_Hash := Sum * Sum - 31;
-
- END (* Calc_Hash *);
-
- (*****************************************************************************)
-
- BEGIN (* Decrypt *)
- (* ASSIGN KEY HERE!!! *)
-
- StringKey := 'Veni, Vidi, Vici';
-
- (* Initialize random number from key *)
-
- RanSeed := Calc_Hash( StringKey );
-
- SetRandom( RanSeed );
- (* Decrypt all lines in input file *)
- REPEAT
- (* Read next line of input *)
- READLN ( MsgLine );
- (* Decrypt text *)
- Decode ( MsgLine );
- (* Write decrypted text to output file *)
- WRITELN( MsgLine );
- (* Until no more input lines left *)
- UNTIL ( EOF );
-
- END (* Decrypt *).
-