/* 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" slidefair_base::slidefair_base(){ period = 0; period_set = FALSE; length = 0; } int slidefair_base::execute_option(char option){ int valid = TRUE; switch(option){ case CHANGEPERIOD: change_period(); break; case SUBSTITUTE: substitute(); break; case UNDO: undo(); break; case ALPHFIT: alphfit(); break; default: valid = base_exec_option(option); break; } return valid; } void slidefair_base::change_period(){ period_set = FALSE; set_period(); clear_to_prompt(); } void slidefair_base::setup_key(){ key.init(period); } void slidefair_base::substitute(){ int column; char tmp_str[STRINGLENGTH]; char ct_1, ct_2, pt_1, pt_2; prompt("What column is the digraph in? "); read_line(tmp_str); if(sscanf(tmp_str, "%d", &column) != 1) msgerror("Bad input."); else if(column < 1 || column > period) msgerror("Bad position."); else{ prompt("What is the substitution? (ct,pt) "); read_line(tmp_str); if(sscanf(tmp_str, "%c%c,%c%c", &ct_1, &ct_2, &pt_1, &pt_2) != 4){ msgerror("Bad format."); } else if(!isalpha(ct_1) || !isalpha(ct_2) || !isalpha(pt_1) || !isalpha(pt_2) ){ msgerror("Bad pairs."); } else{ sub_digraph(ct_1, ct_2, pt_1, pt_2, column-1); } } } void slidefair_base::alphfit(){ char tmp_str[STRINGLENGTH]; int i, column; prompt("Fit which column? (* for all) "); read_line(tmp_str); if(*tmp_str == '*'){ for(i = 0; i < period; i++){ fit_column(i); } } else if(sscanf(tmp_str, "%d", &column) != 1){ msgerror("Bad column."); } else if(column < 1 || column > period){ msgerror("Column out of range."); } else{ fit_column(column-1); } } void slidefair_base::undo(){ int column, i; prompt("Which column? (* for all) "); column = get_char(); if(column == '*'){ for(i = 0; i < period; i++) key.clearkey(); } else{ column--; key.clearkey(column); } } void slidefair_base::show_menu(){ menu(2, "Options: (S)ubstitute (A)pply fit (U)ndo (C)hange period"); menu(1, " (W)rite (Q)uit"); } void slidefair_base::show_cipher(){ int i, line_length; char tmp_str[STRINGLENGTH]; line_length = COLS / (period*2+1); i = 0; while(i < length){ strncpy(tmp_str, cipher+i, period*2); tmp_str[period*2] = (char) NULL; msgprint((i*(period*2+1)/(period*2))%(line_length*(period*2+1)), (i/(line_length*period*2))*3 + 1, tmp_str); decode(tmp_str); msgprint((i*(period*2+1)/(period*2))%(line_length*(period*2+1)), (i/(line_length*period*2))*3 + 0, tmp_str); i += period*2; } } void slidefair_base::decode(char *message){ int i; for(i = 0; i < strlen(message); i+=2){ if(key.val(i/2) == BLANK){ message[i] = BLANK; message[i+1] = BLANK; } else{ strncpy(message+i, slide_get_pt(message[i], message[i+1], key.val(i/2)), 2); } } } void slidefair_base::show_key(){ int i; for(i = 0; i < period; i++){ if(key.val(i) != BLANK){ msgprint(3*i+4, 15, "%2d", key.val(i)-'a'); msgprint(3*i+4, 16, " %c", key.val(i)); } else{ msgprint(3*i+4, 15, " ."); msgprint(3*i+4, 16, " "); } /* put_char(BLANK, 3*i + 5, 16); */ } } char slidefair_base::slide_get_key_letter(char ct_1, char ct_2, char pt_1, char pt_2){ char key_letter=(char) NULL; ct_1 |= ' '; pt_1 |= ' '; ct_2 |= ' '; pt_2 |= ' '; if(isalpha(ct_1) && isalpha(pt_1) && isalpha(ct_2) && isalpha(pt_2)){ key_letter = get_key_letter(ct_1, pt_2); if(key_letter != get_key_letter(pt_1, ct_2)){ key_letter = (char) NULL; } } return key_letter; } char *slidefair_base::slide_get_pt(char ct_1, char ct_2, char key_letter){ char pt[2]; pt[0] = pt[1] = (char) NULL; ct_1 |= ' '; ct_2 |= ' '; if(isalpha(key_letter)){ key_letter |= ' '; pt[0] = get_pt(ct_2, key_letter); pt[1] = get_pt(ct_1, key_letter); /* Is this one of those cases where we have to take the pair ** to the right of the encoded letters? */ if(pt[0] == ct_1){ pt[0] = ct_1+1; pt[1] = get_ct(pt[0], key_letter); if(pt[1] > 'z') pt[1] -= 26; if(pt[0] > 'z') pt[0] -= 26; } } return pt; } char *slidefair_base::slide_get_ct(char pt_1, char pt_2, char key_letter){ char ct[2]; ct[0] = ct[1] = (char) NULL; pt_1 |= ' '; pt_2 |= ' '; if(isalpha(key_letter)){ key_letter |= ' '; ct[0] = get_ct(pt_1, key_letter); ct[1] = get_pt(pt_2, key_letter); /* Is this one of those cases where we have to take the pair ** to the right of the encoded letters? */ if(ct[0] == pt_1){ ct[0] = pt_1+1; ct[1] = get_pt(ct[0], key_letter); if(ct[0] > 'z') ct[0] -= 26; if(ct[1] > 'z') ct[1] -= 26; } } return ct; } void slidefair_base::sub_digraph(char ct_1, char ct_2, char pt_1, char pt_2, int column){ char key_letter; key_letter = slide_get_key_letter(ct_1, ct_2, pt_1, pt_2); if(key_letter){ key.alter(key_letter, column); } } void slidefair_base::fit_column(int column){ int i, k, fweights[26]; int maxweight=0, maxpos=0; char digraph[2]; for(i = 0; i < 26; i++) fweights[i] = 0; /* Rotate through the 26 possible keys */ for(k = 0; k < 26; k++){ /* Rotate each letter in the column */ for(i = column*2; i < length; i+=period*2){ strncpy(digraph, slide_get_pt(cipher[i], cipher[i+1], k+'a'), 2); fweights[k] += get_digram_value(digraph[0], digraph[1]); } } /* Find the largest weight and make that substitution. */ for(i = 0; i < 26; i++){ if(maxweight < fweights[i]){ maxweight = fweights[i]; maxpos = i; } } key.alter(maxpos+'a', column); } void slidefair_base::decipher(char *string){ int i=0; while(i < length){ strncpy(string+i, slide_get_pt(cipher[i], cipher[i+1], key.val((i/2)%(period))), 2); i+=2; } string[length] = (char) NULL; }