/* 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" #define get_pt(a) key.val(a%10,a/10) grandpre::grandpre(){ int i, j; valid_chars = "12345678"; length = 0; for(i = 0; i < 8; i++){ for(j = 0; j < 8; j++){ hist[i][j] = 0; } } key.init(9, 9); } int grandpre::execute_option(char option){ int valid = TRUE; switch(option){ case SUBSTITUTE: substitute(); break; case LOCATE: locate_tip(); break; case UNDO: undo(); break; default: valid = base_exec_option(option); break; } return valid; } void grandpre::init_cipher(){ int i; for(i = 0; i < length; i++){ sscanf(cipher + (i*2), "%2d", ocipher+i); hist[(ocipher[i]%10)-1][ocipher[i]/10-1]++; } length /= 2; } void grandpre::locate_tip(){ char temp_str[STRINGLENGTH], tip[STRINGLENGTH]; Key tkey; char *c; int startpos, i, j, valid = TRUE; key.duplicate(&tkey); /* Get the start position from the user */ prompt("At which group would you like to start the search? (ex: 12 23 21) "); read_line(temp_str); if( (c = strstr(cipher, temp_str)) == NULL){ msgerror("Position not found."); } /* Now get the tip */ else{ startpos = (int) (c - cipher); startpos /= 3; prompt("What is the tip? "); read_line(temp_str); strcpy(tip, temp_str); if(strlen(tip) > length - 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) <= length && valid != NEW_SUB; i++){ valid = NEW_SUB; tkey.duplicate(&key); for(j = 0; tip[j] && valid == NEW_SUB; j++){ valid = key.alter(tip[j], ocipher[i+j]%10, ocipher[i+j]/10); /* valid = alter_key(ocipher[i+j], tip[j]); */ } if(valid == NEW_SUB) msgerror("Location found!"); } if(valid != NEW_SUB){ tkey.duplicate(&key); } } } } void grandpre::substitute(){ int number; char tmp_str[STRINGLENGTH]; char pt_letter; prompt("What is the number? "); read_line(tmp_str); if(sscanf(tmp_str, "%d", &number) != 1){ msgerror("Bad input."); } if(number/10 < 1 || number%10 < 1 || number/10 > 8 || number%10 > 8){ msgerror("Bad position."); } else{ prompt("What is the new letter? "); pt_letter = get_char(); if(!isalpha(pt_letter)) msgerror("Bad letter."); else{ key.alter(pt_letter, number%10, number/10); /* alter_key(number, pt_letter); */ } } } void grandpre::undo(){ int number; char temp_str[STRINGLENGTH]; prompt("Undo which number? (* for all) "); read_line(temp_str); if(*temp_str == '*'){ key.clearkey(); } else if(sscanf(temp_str, "%d", &number) != 1){ msgerror("Bad number."); } else if(number/10 < 1 || number%10 < 1 || number/10 > 8 || number%10 > 8){ msgerror("Bad number."); } else{ key.clearkey(number%10, number/10); } } void grandpre::show_menu(){ menu(1, "Options: (S)ubstitute (U)ndo column (W)rite (Q)uit"); } void grandpre::show_cipher(){ int i, npl; npl = (int) (SCREENWIDTH * .8) / 3; for(i = 0; i < length; i++){ /* First the number... */ msgprint((i%npl)*3, (i/npl)*2 + 1, " %02d", ocipher[i]); /* Now the letter... */ msgprint((i%npl)*3, (i/npl)*2 + 0, " %c", get_pt(ocipher[i])); } } void grandpre::show_key(){ int i, j, x, y; for(i = 0; i < 8; i++){ put_char(i+'1', (i/4)*30+5, 17+i%4); put_char(i+'1', i*2+7, 16); put_char(i+'1', i*2+7+30, 16); for(j = 0; j < 8; j++){ x = (j/4)*30+i*2+6; y = (j%4+17); if(key.val(i+1, j+1) != BLANK){ msgprint(x, y, " %c", toupper(key.val(i+1, j+1))); } else{ msgprint(x, y, "%2d", hist[i][j]); } } } } void grandpre::decipher(char *string){ int i=0; while(i < length){ *string++ = get_pt(ocipher[i]); i++; } *string = (char) NULL; }