/* -*- Mode: c++ -*- * @(#) CryptoGram.java 1.0 6/10/97 Ralph Morelli * * Classes: CryptoGram * Author: Ralph Morelli, Trinity College (ralph.morelli@trincoll.edu) * * Copyright (c) 2000 Ralph Morelli. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL purposes and * without fee is hereby granted provided that this copyright * notice appears in all copies. */ /** * A class to support making and breaking of simple * substitution cryptograms. * @version 1.0 6/10/97 * @author Ralph Morelli */ public class CryptoGram { public static final char NULL_CHAR = '*'; private char theKey[] = new char[26]; // key for 'a' to 'z' private String cipherText; // remains unchanged private String plainText = "DIRECTIONS: Type substitutions into the above keys.\n " + "To undo a substitution, just type '*'.\n" + "Use the mouse or arrow keys to navigate the keypad.\n" + "For a hint, type the key and the letter you want to know."; private String hintString; public int gCurX = 0; // Current mouse locations in terms of block number public int gCurY = 0; public CryptoGram ( ) { // Default Constructor cipherText = new String("") ; initKey(); } /** * Construct the initial cryptogram from a String. * @param s the String */ public CryptoGram (String s) { hintString = new String (s.substring(0,26).toLowerCase()); cipherText = new String(s.substring(26, s.length())); initKey(); } /** * initKey() initializes the key to the null character ('*') */ private void initKey() { for (int k = 0; k < 26; k++) theKey[k] = NULL_CHAR; } /** * setKeyChar() sets the current key character to its parameter. * This method is invoked whenever the user proposes a substitution. * For example, substitite 'a' for 'f'. The updated substitution key * is then used to retranslate the cryptogram. * @param key a char in the range 'a' to 'z' */ public void setKeyChar(char key) { int m = gCurX + 13 * gCurY; // Find the current key on the keypad theKey[m] = (char)key; // and store the lower case version of letter plainText = translate(); // Then retranslate the cryptogram. } /** * keyIsValid() maintains the consistency of the key. It prevents the * same letter from being substituted more than once. * @param key an integer array storing the key * @return true if the key is consistent and false otherwise */ public boolean keyIsValid (char key) { // Works just for 'a' to 'z' if (key >= 'a' && key <= 'z') { // If key is a valid letter int k; for (k = 0; k < 26 && theKey[k] != key; k++) ; // and not a duplicate if (k < 26) return(false); else return(true); } else if (key == '*') return true; else return false; } // keyIsValid() /** * Returns the mapping from a key on the keypad to a given character in theKey. * @param ch the character to be mapped * @return the character's mapping. */ public char getCellContents(int x, int y) { // x is col y is the row int m = x + 13 * y; // Use x, y to compute what cell this is return(theKey[m]); // and return its key } public boolean inActiveBlock(int x, int y) { return x == gCurX && y == gCurY; } // InActiveBlock public void setActiveBlock(int x, int y) { gCurX = x; // reset current mouse locations gCurY = y; } //SetActiveBlock /** * Gets the current plaintext for this cryptogram. * The key is first applied to generate an up-to-date * plaintext. * @return the updated plaintext. */ public String getPlainText( ) { translate(); return plainText; } /** * Gets the current ciphertext for this cryptogram. * @return the current cipherText. */ public String getCipherText( ) { return cipherText; } /** * translate() uses the key to generate the plaintext from the cryptogram */ public String translate() { StringBuffer sb = new StringBuffer(); for (int k = 0; k < cipherText.length(); k++) sb.append( encode(cipherText.charAt(k)) ); return sb.toString(); } // translate() /** * encode() substitutes the input char to another char using the key. * @param inChar the char to be encoded */ char encode(char inChar){ char outChar; if (inChar == '*') return inChar; // Asterisk is special case if (inChar >= 'A' && inChar <= 'Z') { inChar = (char)((int)inChar + 32); // convert to lowercase outChar = theKey[(int)inChar - (int)'a']; // get its substitute if (outChar == NULL_CHAR) // return null if there's no key value return outChar; else return (char) ((int)'A' + (int)outChar - (int)'a'); // else return the substitute } else if (inChar >= 'a' && inChar <= 'z') return theKey[(int)inChar - (int)'a']; return inChar; } // encode() /** * getHint() returns the requested character from the key * @param s -- the requested character * @return a char from the key */ public char getHint(char ch) { if (ch >= 'A' && ch <= 'Z') // convert to lower case if necessary ch = (char) ((int) ch + 32); if (ch >= 'a' && ch <= 'z') { // if it's a valid letter char hint = 'A'; int index = 0; while (ch != hintString.charAt(index) && index <= 25) { index++; } return (char) ((int) hint + index); } return ('?'); } // getHint() } // CryptoGram