/* Seal Revision: 1-OCT-1994 Open the input file for reading. Open the output file for writing. Get the initial rotor setting and step size keys. Initialize the transform and the output buffer. Loop over all lines (records). Loop over all the characters in this line (record). For each character: IF the character has a decimal value 32:126 then transform it and put it in the output buffer. Rotate the rotor wheels. ELSE just copy the character to the output buffer. Write the output buffer to the output file and clear the output buffer. EndLoop EndLoop Close all files. ASCII Code Values Character Decimal Hex Character Decimal Hex --------- ------- --- --------- ------- --- line feed = 10 0a : = 58 3a form feed = 12 0c ; = 59 3b return = 13 0d < = 60 3c space = 32 20 = = 61 3d > = 62 3e ! = 33 21 ? = 63 3f " = 34 22 @ = 64 40 # = 35 23 $ = 36 24 A:Z = 65:90 41:5a % = 37 25 & = 38 26 [ = 91 5b ' = 39 27 \ = 92 5c ] = 93 5d ( = 40 28 ^ = 94 5e ) = 41 29 _ = 95 5f * = 42 2a ` = 96 60 + = 43 2b , = 44 2c a:z = 97:122 61:7a - = 45 2d . = 46 2e { = 123 7b / = 47 2f | = 124 7c } = 125 7d 0:9 = 48:57 30:39 ~ = 126 7e Now we make a two dimensional array of integers called, rotor. The first dimension (i.e. the number of rows) is 95. This gives one row to describe each character that we may want to map. Recall that the array subscript always starts at zero. The second dimension (i.e. the number of columns) is 4. This gives us 4 pieces of information about each character that we may want to map. The first piece of information in each row is just an index 0:94 to help us keep track of what is going on. The next piece of information in each row is the rotor #1 "reflective" wiring. This can take on values from 0:94. It is "reflective", i.e. if entry 40 has a value of 75, then entry 75 will have a value of 40. The 3rd and 4th and 5th pieces of information in each row are the reflective wiring for rotor #2 and rotor #3. This array is written in decimal values. */ #include #define MAXBUFF 5000 #define MAXLINE 80 struct param_dat { int rotor_one_fixed_increment ; int rotor_two_fixed_increment ; int rotor_three_fixed_increment ; int rotor_one_position ; int rotor_two_position ; int rotor_three_position ; } ; void Get_Parameters(struct param_dat *pointer_to_parameters ) ; FILE *Get_In_File( ) ; FILE *Get_Out_File( ) ; void exit ( int location ) ; void clear_buf ( char character_buffer[] ) ; void proc_line( char linebuf[], struct param_dat *pointer_to_parameters ) ; void map_chars( int *loc_char, int rotor_number,int rotor_position ) ; void Rotate_Rotors(struct param_dat *pointer_to_parameters ) ; main () { char workbuf[MAXBUFF] ; FILE *fpin, *fpout ; struct param_dat parameters ; printf(" \n") ; fpin = Get_In_File( ) ; /* Get the input and */ fpout = Get_Out_File( ) ; /* out put files. */ Get_Parameters( ¶meters ) ; /* Get the rotor parameters. */ clear_buf(workbuf) ; /* Clear the line work buffer. */ fgets(workbuf, MAXLINE, fpin) ; /* Read the 1st line into buff. */ while (workbuf[0] != '\0') { proc_line( workbuf, ¶meters ) ; fputs(workbuf, fpout) ; clear_buf(workbuf) ; fgets(workbuf, MAXLINE, fpin) ; } fclose(fpin) ; fclose(fpout) ; } /* These are the Get_File functions. It opens the input and output files for this program. It sets up the file pointers and returns then to the calling routine. */ FILE *Get_In_File( ) { char filename[MAXLINE] ; FILE *fpin_loc ; printf(" Enter the filename of the file to be MAPPED: "); gets(filename); if ((fpin_loc = fopen(filename, "r")) == NULL) { printf("\nERROR: Can't open input file %s\n", filename); exit (1); } return(fpin_loc) ; } FILE *Get_Out_File( ) { char filename[MAXLINE] ; FILE *fpout_loc ; printf("Enter the filename of the file to receive MAPPED output: "); gets(filename); if ((fpout_loc = fopen(filename, "w", "rat=cr", "rfm=var")) == NULL) { printf("\nERROR: Can't open output file %s\n", filename); exit (2); } return(fpout_loc) ; } /* This is the CLEAR_BUF function. It is used to set all elements of the workbuf to '\0'. Note that because the arguments passed to this function are the names of two arrays, this function works on the actual arrays, not on temporary local copies of the arrays */ void clear_buf( char linebuf[] ) { int local_index = 0 ; while (local_index < MAXLINE) { linebuf[local_index] = '\0' ; ++local_index ; } } /* This is the routine to setup the rotor parameters. It is passed a pointer to the data structure that holds the rotor parameters. It then askes the operator to specify the 6 rotor parameters. Nothing is returned to the calling program. */ void Get_Parameters( struct param_dat *pt_params ) { int value ; printf(" \n") ; printf("Enter rotor_number_ONE fixed increment 0-93 : "); scanf("%d", &value ); pt_params->rotor_one_fixed_increment = value ; printf("Enter rotor_number_TWO fixed increment 0-93 : "); scanf("%d", &value ); pt_params->rotor_two_fixed_increment = value ; printf("Enter rotor_number_THREE fixed increment 0-93 : "); scanf("%d", &value ); pt_params->rotor_three_fixed_increment = value ; printf(" \n") ; printf("Enter rotor_number_ONE starting position 0-94 : "); scanf("%d", &value ); pt_params->rotor_one_position = value ; printf("Enter rotor_number_TWO starting position 0-94 : "); scanf("%d", &value ); pt_params->rotor_two_position = value ; printf("Enter rotor_number_THREE starting position 0-94 : "); scanf("%d", &value ); pt_params->rotor_three_position = value ; printf(" \n") ; } /* This is the Process Line function. It receives the line working buffer and a pointer to the structure that holds the rotor parameters. For each "normal" character in the line buffer it calles the rotor function 5 time. The character passes through rotors #1 and #2 then is reflected off rotor #3 and then passes back through rotor #2 and #1. Rotor #3 is allowed to increment based both on its "fixed" increment and on the random increment that is based on which character just passed through it. Rotors #2 and #1 increment based only upon their fixed increment as the characters pass back through them after reflecting off of rotor #3. After the line is processes this function returns to the calling program. */ void proc_line( char linebuf[], struct param_dat *pt_params ) { int local_index = 0 ; int this_char ; const int rotor_number_one = 1 ; const int rotor_number_two = 2 ; const int rotor_number_three = 3 ; local_index = 0; while (linebuf[local_index] != '\0') { if (linebuf[local_index] >= 32 && linebuf[local_index] <= 126) { this_char = linebuf[local_index] - 32 ; map_chars( &this_char, rotor_number_one, pt_params->rotor_one_position ) ; map_chars( &this_char, rotor_number_two, pt_params->rotor_two_position ) ; map_chars( &this_char, rotor_number_three, pt_params->rotor_three_position ) ; map_chars( &this_char, rotor_number_two, pt_params->rotor_two_position ) ; map_chars( &this_char, rotor_number_one, pt_params->rotor_one_position ) ; /**** printf(" %6d %6d %6d \n ", pt_params->rotor_one_position, pt_params->rotor_two_position, pt_params->rotor_three_position ); ****/ linebuf[local_index] = this_char + 32 ; ++local_index; Rotate_Rotors( pt_params) ; } else { ++local_index; } } } /* This is the MAP_CHARS function. It maps the characters in the line buffer using the patterns in the rotor wheels. This function processes one character through one rotor wheel. */ void map_chars( int *loc_char, int rotor_number,int rotor_position ) { const int rotor_array[95][4] = { { 0, 58, 45, 41 }, { 1, 24, 33, 10 }, { 2, 27, 37, 9 }, { 3, 46, 67, 4 }, { 4, 35, 13, 3 }, { 5, 25, 14, 13 }, { 6, 9, 86, 37 }, { 7, 54, 66, 35 }, { 8, 84, 48, 72 }, { 9, 6, 32, 2 }, { 10, 62, 25, 1 }, { 11, 73, 84, 74 }, { 12, 34, 19, 27 }, { 13, 88, 4, 5 }, { 14, 63, 5, 47 }, { 15, 28, 15, 45 }, { 16, 87, 16, 92 }, { 17, 67, 83, 31 }, { 18, 69, 26, 39 }, { 19, 33, 12, 82 }, { 20, 72, 42, 58 }, { 21, 83, 57, 60 }, { 22, 91, 23, 32 }, { 23, 47, 22, 64 }, { 24, 1, 92, 38 }, { 25, 5, 10, 86 }, { 26, 75, 18, 62 }, { 27, 2, 30, 12 }, { 28, 15, 49, 94 }, { 29, 76, 38, 83 }, { 30, 51, 27, 81 }, { 31, 36, 60, 17 }, { 32, 79, 9, 22 }, { 33, 19, 1, 52 }, { 34, 12, 72, 75 }, { 35, 4, 40, 7 }, { 36, 31, 68, 70 }, { 37, 65, 2, 6 }, { 38, 85, 29, 24 }, { 39, 64, 90, 18 }, { 40, 66, 35, 85 }, { 41, 45, 76, 0 }, { 42, 68, 20, 89 }, { 43, 70, 93, 61 }, { 44, 74, 80, 50 }, { 45, 41, 0, 15 }, { 46, 3, 94, 68 }, { 47, 23, 79, 14 }, { 48, 60, 8, 54 }, { 49, 82, 28, 73 }, { 50, 61, 71, 44 }, { 51, 30, 58, 59 }, { 52, 78, 56, 33 }, { 53, 86, 73, 84 }, { 54, 7, 62, 48 }, { 55, 59, 81, 66 }, { 56, 81, 52, 91 }, { 57, 77, 21, 63 }, { 58, 0, 51, 20 }, { 59, 55, 87, 51 }, { 60, 48, 31, 21 }, { 61, 50, 64, 43 }, { 62, 10, 54, 26 }, { 63, 14, 77, 57 }, { 64, 39, 61, 23 }, { 65, 37, 78, 80 }, { 66, 40, 7, 55 }, { 67, 17, 3, 71 }, { 68, 42, 36, 46 }, { 69, 18, 74, 90 }, { 70, 43, 85, 36 }, { 71, 93, 50, 67 }, { 72, 20, 34, 8 }, { 73, 11, 53, 49 }, { 74, 44, 69, 11 }, { 75, 26, 75, 34 }, { 76, 29, 41, 79 }, { 77, 57, 63, 88 }, { 78, 52, 65, 87 }, { 79, 32, 47, 76 }, { 80, 92, 44, 65 }, { 81, 56, 55, 30 }, { 82, 49, 91, 19 }, { 83, 21, 17, 29 }, { 84, 8, 11, 53 }, { 85, 38, 70, 40 }, { 86, 53, 6, 25 }, { 87, 16, 59, 78 }, { 88, 13, 88, 77 }, { 89, 94, 89, 42 }, { 90, 90, 39, 69 }, { 91, 22, 82, 56 }, { 92, 80, 24, 16 }, { 93, 71, 43, 93 }, { 94, 89, 46, 28 }, } ; int work_char ; int temp_char ; work_char = *loc_char + rotor_position ; if (work_char > 94) { work_char = work_char - 95 ; } temp_char = rotor_array[work_char][rotor_number] ; temp_char = temp_char - rotor_position ; if (temp_char < 0) { *loc_char = temp_char + 95 ; } else { *loc_char = temp_char ; } } /* This is the function that rotates the rotors after a character has been processed. 1. Always rotate rotor #3 using the fixed increment value for rotor #3. 2. If rotor #3 moves past position 94 then bring it back into the 0:94 range and increment rotor #2 based on the fixed increment value for rotor #2. Rotor #2 is incremented only of rotor #3 "caries". 3. If rotor #2 moves past position 94 then bring it back into the 0:94 range and increment rotor #1 based on the fixed increment value for rotor #1. Rotor #1 is incremented only of rotor #2 "caries". */ void Rotate_Rotors(struct param_dat *pt_params ) { pt_params->rotor_three_position = pt_params->rotor_three_position + pt_params->rotor_three_fixed_increment ; if (pt_params->rotor_three_position > 94) { pt_params->rotor_three_position = pt_params->rotor_three_position -95 ; pt_params->rotor_two_position = pt_params->rotor_two_position + pt_params->rotor_two_fixed_increment ; if (pt_params->rotor_two_position > 94) { pt_params->rotor_two_position = pt_params->rotor_two_position -95 ; pt_params->rotor_one_position = pt_params->rotor_one_position + pt_params->rotor_one_fixed_increment ; if (pt_params->rotor_one_position > 94) { pt_params->rotor_one_position = pt_params->rotor_one_position -95 ; } } } }