/* 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 "term.h" #include "types.h" #include "ctypes.h" quag::quag(){ period = 0; period_set = FALSE; *cipher = (char) NULL; clen = 0; length = 0; } int quag::execute_option(char option){ int valid = TRUE; switch(option){ case SUBSTITUTE: substitute(); break; case CHANGEPERIOD: change_period(); break; case UNDO: undo(); break; default: valid = base_exec_option(option); break; } return valid; } void quag::change_period(){ set_period(); setup_key(); } void quag::substitute(){ char ct_letter, pt_letter; char tmp_str[STRINGLENGTH]; int column; prompt("What column is the letter in? "); read_line(tmp_str); if(sscanf(tmp_str, "%d", &column) != 1){ msgerror("Bad position."); } else if(column < 1 || column > period){ msgerror("Bad position."); } else{ prompt("What is the new letter? (ct,pt) "); read_line(tmp_str); if(sscanf(tmp_str, "%c,%c", &ct_letter, &pt_letter) != 2){ msgerror("Bad format."); } else if(!isalpha(ct_letter) || !isalpha(pt_letter)){ msgerror("Bad letter."); } else{ if(key.alter(pt_letter, key.index(ct_letter), column-1) == BAD_SUB){ msgerror("Bad substitution."); } } } } void quag::undo(){ int column, i; char ct_letter, ccolumn; char temp_str[STRINGLENGTH]; prompt("Which column? (* for all) "); read_line(temp_str); ccolumn = (char) *temp_str; sscanf(temp_str, "%d", &column); prompt("Undo which letter? (* for all) "); ct_letter = get_char(); if(ct_letter == '*' && ccolumn == '*'){ key.clearkey(); } else if(ct_letter == '*' && (column <= period && column > 0)){ for(i = 'a'; i < 'z'; i++){ key.clearkey(key.index(i), column-1); } } else if(ccolumn == '*' && isalpha(ct_letter)){ for(i = 0; i < period; i++){ key.clearkey(ct_letter, i); } } else if((column <= period && column > 0) && isalpha(ct_letter)){ key.clearkey(key.index(ct_letter), column - 1); } else if(column < 1 || column > period){ msgerror("Bad column."); } else if(!isalpha(ct_letter)){ msgerror("Bad letter."); } } void quag::show_menu(){ menu(1, "Options: (S)ubstitute (U)ndo letter (W)rite (Q)uit"); } void quag::show_cipher(){ int i, line_length; char tmp_str[20]; line_length = COLS / (period+1); i = 0; while(i < length){ strncpy(tmp_str, cipher+i, period); tmp_str[period] = (char) NULL; msgprint((i*(period+1)/period)%(line_length*(period+1)), (i/(line_length*period))*2 + 1, tmp_str); decode(tmp_str); msgprint((i*(period+1)/period)%(line_length*(period+1)), (i/(line_length*period))*2 + 0, tmp_str); i += period; } } void quag::decode(char *message){ int i; for(i = 0; i < strlen(message); i++){ message[i] = key.val(key.index(message[i%period]), i%period); } } void quag::show_key(){ register int i, j, k /*,l, m, n*/; int letter_found; /* register char c, d; */ /* The first step is to combine the separate keys so that if there ** is a repetition in two keys the data will be combined. */ /* key.duplicate(&okey); */ /* Make period passes for each key so that second order repetitions ** will be taken into account. */ /* for(j = 0; j < period; j++){ */ /* Loop through each of the 'period' keys. */ /* for(i = 0; i < period; i++){ */ /* For each key, loop through each of the other 'period' keys. */ /* for(k = 0; k < period; k++){ for(l = 0; l < 26; l++){ if(okey[i][l] != BLANK){ for(m = 0; m < 26; m++){ */ /* do the keys overlap? */ /* if(okey[k][m] == okey[i][l]){ for(n = 0; n < 26; n++){ c = okey[i][(l+n)%26]; d = okey[k][(m+n)%26]; if(c != BLANK && d != BLANK && c!=d){ msgerror("Caution: Bad substitution."); } if(d != BLANK){ okey[i][(l+n)%26] = okey[k][(m+n)%26]; okey[k][(m+n)%26] = okey[k][(m+n)%26]; } else if(c != BLANK){ okey[k][(m+n)%26] = okey[i][(l+n)%26]; okey[i][(l+n)%26] = okey[i][(l+n)%26]; } } } } } } } } } */ msgprint(0, 9, "Pt: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"); for(i = 0; i < period; i++){ msgprint(0, i+10, "%2d", i+1); for(j = 0; j < 26; j++){ for(k = 0, letter_found = FALSE; k < 26 && !letter_found; k++){ if(key.intval(k, i) == j){ put_char(k+'a', j*2+4, i+10); letter_found = TRUE; } } if(!letter_found){ put_char(BLANK, j*2+4, i+10); } } } } void quag::setup_key(){ key.init(26, period); okey.init(26, period); } void quag::decipher(char *string){ int i; char temp_str[STRINGLENGTH]; *string = (char) NULL; for(i = 0; i < length; i+=period){ strncpy(temp_str, cipher+i, period); temp_str[period] = (char) NULL; decode(temp_str); strcat(string, temp_str); } }