/* This is one of the cipher files for the cipher interface written ** by wart@ugcs.caltech.edu ** ** Please don't steal my code without my permission. ** */ #include #include #include #include #include "term.h" #include "types.h" #include "ctypes.h" checker::checker(){ int i, j; /* set the keys to zero and fill the block here. */ for(i = 0; i < 5; i++){ for(j = 0; j < 5; j++){ block[i][j] = i*5+j+'a'; if(block[i][j] > 'i') block[i][j]++; /* key[i*5+j] = BLANK; */ } /* key1[i] = key2[i] = key3[i] = key4[i] = (char) NULL; */ } key.init(25); keywords.init(5, 4); /* key[25] = BLANK; key[26] = (char) NULL; key1[5] = key2[5] = key3[5] = key4[5] = (char) NULL; */ num_keys = 2; } int checker::execute_option(char option){ int valid = TRUE; switch(option){ case SUBSTITUTE: sub(); break; case UNDO: undo(); break; default: valid = base_exec_option(option); break; } return valid; } int checker::set_period(int newperiod){ period_set = TRUE; return TRUE; } void checker::show_menu(){ menu(1, "(S)ubstitute (U)ndo (W)rite (Q)uit"); } void checker::show_cipher(){ int i, x, y; for(i = 0; i < length/2; i++){ x = (i*3)%72; y = (int) (i/(72/3))*3; put_char(toupper(key.val(newcipher[i]-'a')), x, y); put_char(newcipher[i], x, y+1); put_char(cipher[i*2], x, y+2); if(cipher[i*2+1]) put_char(cipher[i*2+1], x+1, y+2); } } void checker::show_key(){ int i, j, index; /* Print the border keywords */ for(i = 0; i < 5; i++){ if(num_keys == 4){ put_char(toupper(keywords.val(i, 3)), i*2+5, 10); put_char(toupper(keywords.val(i, 2)), 2, 11+i); } put_char(toupper(keywords.val(i, 1)), i*2+5, 10); put_char(toupper(keywords.val(i, 0)), 3, 11+i); } for(i = 0; i < 5; i++){ for(j = 0; j < 5; j++){ index = i*5+j; if(index > 9) index++; if(key.val(index) == BLANK){ put_char(block[i][j], j*2+5, 11+i); } else{ put_char(toupper(key.val(index)), j*2+5, 11+i); } } } } void checker::init_cipher(){ int i, j=0/*, index1, index2*/; int valid = TRUE; if(length%2){ msgerror("Checkerboard must have an even number of letters."); valid = FALSE; } else{ /* There should be no more than 5 unique letters in the odd positions ** and 5 unique letters in the even positions */ for(i = 0; i < length; i+=2){ /* is this letter a new one? */ for(j = 0; keywords.val(j, 0) && keywords.val(j, 0) != cipher[i] && j < 5; j++); if(j == 5){ valid = FALSE; } else if(cipher[i] != keywords.val(j, 0)){ keywords.alter(cipher[i], j, 0); } } for(i = 1; i < length; i+=2){ /* is this letter a new one? */ for(j = 0; keywords.val(j, 1) && keywords.val(j, 1) != cipher[i] && j < 5; j++); if(j == 5){ valid = FALSE; } else if(cipher[i] != keywords.val(j, 1)){ keywords.alter(cipher[i], j, 1); } } } /* If we have a valid cipher, then let the user rearrange the letters ** to form the key. */ /* if(valid){ *temp_str = (char) NULL; do{ prompt("What is the first keyword (%s)? ", key1); read_line(temp_str); if(strlen(temp_str) == 5){ for(i=0, j=0; i < 5 && j < 5; i++){ for(j = 0; j < 5 && temp_str[i]!=key1[j]; j++); } } if(j != 5){ for(i=0, j=0; i < 5 && j < 5; i++){ for(j = 0; j < 5 && temp_str[j]!=key1[i]; j++); } } } while(j == 5); strcpy(key1, temp_str); *temp_str = (char) NULL; do{ prompt("What is the second keyword (%s)? ", key2); read_line(temp_str); if(strlen(temp_str) == 5){ for(i=0, j=0; i < 5 && j < 5; i++){ for(j = 0; j < 5 && temp_str[i]!=key2[j]; j++); } } if(j != 5){ for(i=0, j=0; i < 5 && j < 5; i++){ for(j = 0; j < 5 && temp_str[j]!=key2[i]; j++); } } } while(j == 5); strcpy(key2, temp_str); } */ /* Now create a new cipher by substituting the digraphs with ** their corresponding block letters */ /* for(i = 0; i < length; i+=2){ index1 = (int) (strchr(key1, cipher[i]) - key1); index2 = (int) (strchr(key2, cipher[i+1]) - key2); newcipher[i/2] = block[index1][index2]; } */ } void checker::sub(){ char ct, pt; /* Get the substitution from the user */ prompt("What is the encoded letter? "); ct = get_char(); prompt("What is the plaintext letter? "); pt = get_char(); /* Is it a vaild sub? */ if(!isalpha(ct) || !isalpha(pt) || ct == 'j'){ msgerror("Bad letter."); } else{ ct |= ' '; pt |= ' '; key.alter(pt, ct); } } void checker::undo(){ char ct; /* Get the letter from the user */ prompt("What is the encoded letter? "); ct = get_char(); /* Is it a vaild letter? */ if(!isalpha(ct) && ct != '*'){ msgerror("Bad letter."); } if(ct == '*'){ key.clearkey(); } else{ ct |= ' '; key.clearkey(ct); } } /* void checker::copy_key(char *string){ keywords.string(string); key.string(string); } void checker::read_key(char *string){ keywords.restore(string); key.restore(string); } */ void checker::decipher(char *string){ int i; for(i = 0; i < length/2; i++){ string[i] = key.val(newcipher[i]); } string[length/2] = (char) NULL; }