/* 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" keyphrase::keyphrase(){ ocipher = NULL; length = 0; num_lines = 0; key.init(26); valid_chars = "abcdefghijklmnopqrstuvwxyz -',.;"; } int keyphrase::execute_option(char option){ int valid = TRUE; switch(option){ case LOCATE: locate_tip(); break; case GROUPSUB: group_substitute(); break; case SUBSTITUTE: substitute(); break; case UNDO: undo(); break; default: valid = base_exec_option(option); break; } return valid; } void keyphrase::init_cipher(){ int pos=0, line = 0; int i, line_length; char *start, *end; line_length = (int) (.9*COLS); start = end = cipher; num_lines = (int) (length*2/line_length+1); ocipher = new char*[num_lines]; for(i = 0; i <= num_lines; i++){ ocipher[i] = new char[line_length+1]; } while(start - cipher < length){ while(*start == ' ') start++; end = start; while( (end - start < line_length) && (end < cipher+length) ) end++; if(end - start >= line_length){ while(*end-- != ' '); } for(pos = 0; start <= end;pos++, start++){ ocipher[line][pos] = *start; } ocipher[line][pos] = (char) NULL; line++; } for(i = line; i < num_lines; i++){ delete[] ocipher[i]; } ocipher[line] = NULL; num_lines = line; } int keyphrase::set_period(int newperiod){ return TRUE; } void keyphrase::show_menu(){ menu(1, "(S)ubstitute (G)roup sub (U)ndo (L)ocate tip (W)rite (Q)uit"); } void keyphrase::locate_tip(){ char temp_str[STRINGLENGTH], tip[STRINGLENGTH]; char *c; char tcipher[CLENGTH]; int startpos, i, j, valid = TRUE, tlen=0; Key tkey; key.duplicate(&tkey); for(i = 0; cipher[i]; i++){ if(isalpha(cipher[i])) tcipher[tlen++] = cipher[i]; } tcipher[tlen++] = (char) NULL; /* Get the start position from the user */ prompt("At which group would you like to start the search? "); read_line(temp_str); if( (c = strstr(tcipher, temp_str)) == NULL){ msgerror("Group %s does not exist.", temp_str); valid = FALSE; } /* Now get the tip */ else{ startpos = (int) (c - tcipher); prompt("What is the tip? "); read_line(temp_str); strcpy(tip, temp_str); if(strlen(tip) > tlen - startpos){ msgerror("Tip too long for that starting position."); valid = FALSE; } else{ /* Ok, we have a valid tip. Try to match it to every position ** until we find one that works. Start off with valid being FALSE ** so that the loop doesn't terminate right away. */ valid = BAD_SUB; for(i = startpos; i + strlen(tip) <= tlen && valid != NEW_SUB; i++){ tkey.duplicate(&key); for(j = 0, valid=NEW_SUB; tip[j] && valid == NEW_SUB; j++){ valid = key.alter(cipher[i+j], key.index(tip[j])); } if(valid == NEW_SUB) msgerror("Location found!"); } if(valid != NEW_SUB){ tkey.duplicate(&key); } } } } void keyphrase::group_substitute(){ char word[STRINGLENGTH]; char dword[STRINGLENGTH]; Key tkey; int i, valid=TRUE; key.duplicate(&tkey); prompt("What is the ciphertext? "); read_line(dword); prompt("What is the plaintext? "); read_line(word); /* Are the strings the same length? */ if(strlen(word) != strlen(dword)){ valid = FALSE; } /* Convert the letters to lowercase and check for non-alphabetic ** characters */ for(i = 0; i < strlen(word); i++){ if(!isalpha(word[i]) || !isalpha(dword[i])){ valid = FALSE; } else{ word[i] |= ' '; dword[i] |= ' '; } } for(i = 0; i < strlen(word) && valid == TRUE; i++){ if(key.alter(dword[i], key.index(word[i])) != NEW_SUB) valid = FALSE; } if(valid == FALSE){ msgerror("Bad substitution."); tkey.duplicate(&key); } } void keyphrase::substitute(){ char ct_letter, pt_letter; /* Get the encoded letter */ prompt("What is the encoded letter? "); ct_letter = get_char(); prompt("What is the decoded letter? "); pt_letter = get_char(); if(!isalpha(ct_letter) || !isalpha(pt_letter)){ msgerror("Bad letter."); } else if(key.alter(ct_letter, key.index(pt_letter)) != NEW_SUB){ msgerror("Bad substitution."); } } void keyphrase::undo(){ char pt_letter; prompt("What is the decoded letter? "); pt_letter = get_char(); if(pt_letter == '*'){ key.clearkey(); } else key.clearkey(pt_letter); } void keyphrase::show_cipher(){ char c, j, lets[26]; int line, i; for(line = 0; line < num_lines; line++){ for(i = 0; i < strlen(ocipher[line]); i++){ c = ocipher[line][i]; put_char(toupper(c), i, (line+1)*7); get_letters(c, lets); for(j = 0; j < 6 && lets[j]; j++){ put_char(lets[j], i, (line+1)*7-1-j); } for(;j < 6; j++){ put_char(BLANK, i, (line+1)*7-1-j); } } } } void keyphrase::get_letters(char letter, char *array){ char i; if(isalpha(letter)){ for(i = 'a'; i <= 'z'; i++){ if(key.val(i) == letter){ *array++ = i; } } } *array = (char) NULL; } void keyphrase::show_key(){ int i; msgprint(0, num_lines*7+2, "Pt: "); msgprint(0, num_lines*7+3, "Ct: "); for(i = 0; i < 26; i++){ put_char(i+'a', i*2+5, num_lines*7+2); put_char(toupper(key.val(i)), i*2+5, num_lines*7+3); } } void keyphrase::decipher(char *string){ char lets[8]; int i, j; *string = (char) NULL; for(i = 0; i < length; i++){ get_letters(cipher[i], lets); for(j = 0; lets[j]; j++){ *string++ = lets[j]; } *string++ = '\n'; } *string = (char) NULL; }