/* 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" cadenus::cadenus(){ *cipher = (char) NULL; ocipher = NULL; clen = 25; period = 0; period_set = FALSE; } int cadenus::execute_option(char option){ int valid = TRUE; switch(option){ case ROTATE: rotate(); break; case MOVE: move_stuff(); break; case ALPHFIT: fit_columns(); break; case UNDO: undo(); key.init(); break; default: valid = base_exec_option(option); break; } return valid; } int cadenus::set_period(int newperiod){ length = strlen(cipher); clen = 25; if(period_set == FALSE || newperiod){ period = newperiod; if(!period){ if( length%clen != 0){ msgerror("Bad length for Cadenus cipher. Length must be a multiple of 25."); period_set = FALSE; } else{ length = strlen(cipher); period = length / clen; period_set = TRUE; } } else period_set = TRUE; setup_key(); } return period_set; } void cadenus::init_cipher(){ if(ocipher == NULL){ ocipher = strdup(cipher); length = strlen(cipher); clen = 25; } } void cadenus::setup_key(){ int i; key.init(period); for(i = 0; i < period; i++){ key.alter('a', i); } } void cadenus::rotate(){ int column, rot, i; char temp_str[STRINGLENGTH]; /* Get the column */ prompt("Rotate which column (* for all)? "); read_line(temp_str); if(*temp_str == '*') column = 0; else (void)sscanf(temp_str, "%d", &column); /* Get the amount to rotate */ prompt("Rotate down by how much? "); read_line(temp_str); if(sscanf(temp_str, "%d", &rot) != 1){ msgerror("Bad rotation value."); } else if(column == 0){ for(i = 0; i < period; i++){ _rotate_column(i, rot); } } else if(column > 0 && column <= period){ _rotate_column(column-1, rot%25); } else{ msgerror("Bad values."); } } void cadenus::_rotate_column(int column, int rot){ rot += 25; rot %= 25; rotate_column(column, rot); rot = 25 - rot; key.alter((key.intval(column)+rot+25)%25+'a', column); } void cadenus::move_stuff(){ char temp_str[STRINGLENGTH]; char i; int column1, column2; prompt("Interchange which two columns/rows? (ex: 1,2) "); read_line(temp_str); if(sscanf(temp_str, "%d,%d", &column1, &column2) != 2) msgerror("Bad input format."); else if(column1 <= period && column2 <= period && column1 > 0 && column2 > 0){ column1--, column2--; interchange_columns(column1, column2); i = key.val(column1); key.alter(key.val(column2), column1); key.alter(i, column2); } else{ msgerror("Bad column number."); } } void cadenus::fit_columns(){ char temp_str[STRINGLENGTH]; int col1, col2, i; prompt("Fit which two columns (eg. 1,2 or * for all)? "); read_line(temp_str); if(*temp_str == '*'){ for(i = 1; i < period; i++){ _fit_columns(i-1, i); } } else if(sscanf(temp_str, "%d,%d", &col1, &col2) != 2){ msgerror("Bad input."); } else if(col1 < 1 || col2 < 1 || col1 > period || col2 > period){ msgerror("Bad values."); } else{ col1--, col2--; _fit_columns(col1, col2); } } void cadenus::_fit_columns(int col1, int col2){ char *colstring1, *colstring2; int rot; colstring1 = strdup(get_column_string(col1)); colstring2 = strdup(get_column_string(col2)); rot = find_best_fit(colstring1, colstring2); rotate_column(col2, rot); rot = (rot+25)%25; rot = 25-rot; key.alter((key.intval(col2)+rot+25)%25+'a', col2); free(colstring1); free(colstring2); } void cadenus::show_menu(){ menu(1, "(R)otate column (A)lphabet fit (M)ove columns (U)ndo changes (W)rite (Q)uit"); } void cadenus::show_key(){ int i; char c; for(i = 0; i < period; i++){ c = key.val(i); if(isalpha(c)) c = cad_conv(c); else c = 'a'; put_char(toupper(c), 2*i+3, 1); put_char(toupper(c), 2*i+2*period+8, 1); } } void cadenus::show_cipher(){ int i; /* Print the row/column numbers */ for(i = 0; i < period; i++) (void)put_char((i+1)%10 + '0', 2*i+3, 0); if(clen > 17) for(i = 0; i < period; i++) (void)put_char((i+1)%10 + '0', 2*i+2*period+8, 0); /* Print the cipher */ for(i = 0; i < length; i++){ if(i < 17*period) (void)put_char(cipher[i], (i%period)*2+3, (i/period) + 2); else (void)put_char(cipher[i], (i%period)*2+8+2*period, (i/period) + 2-17); } } void cadenus::decipher(char *string){ strcpy(string, cipher); }