gt: 		for (int k = 0; k < alphabet.getSize(); k++)
context: /*
   * File: HistoricalKey.java
   *
   * Copyright (C) 2009 R. Morelli and R. Walde
   * 
   * This file is part of HcryptoJ.
   *
   * HcryptoJ is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by 
   * the Free Software Foundation; either version 3.0 of the License, or (at
   * your option) any later version.
   * 
   * This program is distributed in the hope that it will be useful, 
   * but WITHOUT ANY WARRANTY; without even the implied warranty of 
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * General Public License for more details.
   * 
   * You should have received a copy of the GNU General Public License
   * along with this program; if not visit http://www.gnu.org/licenses/gpl.html.
   */
  
  package hcrypto.cipher;
  import hcrypto.provider.*;
  
  import java.util.StringTokenizer;
  
  /**
   * Provides a partial implementation of the
   * HistoricalKey interface by providing default implementations
   * of the <tt>getKeyword()</tt>, <tt>getAlphabet()</tt>, and
   * <tt>getBlocksize()</tt> methods. 
   *
   * <P>The <tt>HistoricalKey()</tt> constructor should be
   * invoked by the subclass. It extracts the <tt>keyspec</tt>, 
   * which provides algorithm-specific data as well as a specification
   * of the <a href="Alphabet.html">Alphabet</a> used by the particular key.
   * These are stored in instance variables. 
   *
   * <P>The <i>key specification</i> is comprised of two parts:
   * <i>keydata/alphabetspec</i>, separated by a forward slash "/".
   * The <i>keydata</i> provides material that used to construct
   * an algorithm-specific key. Here are some examples.
   *
   * <TABLE>
   * <TR><TH>Algorithm</TH><TH>Keydata</TH><TH>AlphabetSpec</TH></TR>
   * <TR><TD>Caesar</TD><TD>shift</TD><TD>azAZ09</TD></TR>
   * <TR><TD>Substitution</TD><TD>keyword</TD><TD>printable</TD></TR>
   * <TR><TD>Affine</TD><TD>a,b</TD><TD>az</TD></TR>
   * </TABLE>
   *
   * <P> Here are some examples of key instantiations:
   * <PRE>
   *      CaesarKey key = new CaesarKey("55/printable");
   *      SubstitutionKey sKey = new SubstitutionKey("76TrombonesLEDTHEPARADE/azAZ09");
   *      AffineKey aKey = new AffineKey("3,3/azAZ09");
   * </PRE>
   */
  public abstract class HistoricalKey {
  
  	/**
  	 *  A keyspec takes the form <i>keydata/plainalphabetspec/cipheralphabetspec</i>,
  	 *  where <i>plainalphabetspec</i> is a sepcification for the plaintext
  	 *  alphabet, and  <i>cipheralphabetspec</i> is a specification for the
  	 *  ciphertext alphabet.  The spec for the ciphertext alphabet may be 
  	 *  omitted, in which case the spec for the plaintext alphabet will 
  	 *  be used for both alphabets. 
  	 *  
  	 *  <P>An example would be <tt>xylophone/az/AZ</tt> where the keydata
  	 *  in this case is the keyword "xylophone", the plaintext alphabet consists
  	 *  of the lowercase letters a..z, and the ciphertext alphabet consists of
  	 *  the uppercase letters A..Z.  In this case, the encryption algorithm 
  	 *  will map letters from a..z to A..Z, and the decryption algorithm
  	 *  will perform the reverse mapping.
  	 *
  	 *  <P>Another example would be <tt>xylophone/az</tt>. In this case the
  	 *  keyword is "xylophone" and both the plaintext and ciphertext alphabets
  	 *  are the lowercase letters a..z. In this case both encryption and decryption
  	 *  are performed by mapping from the set of characters a..z onto itself.
  	 */ 
  	protected String keyspec;
  
  	/**
  	 *  Many historical ciphers use a keyword as part (or all) of
  	 *  the key. For example, substitution and Vigenere ciphers use
  	 *  the keyword to initialize the cipher alphabet. 
  	 */ 
  	protected String keyword;     // e.g., "xylophone";
  
  	/**
  	 *  This instance variable stores a reference to the particular
  	 *  plaintext characters for which this cipher is defined.
  	 */
  	protected Alphabet alphabet;  // Reference to plaintext alphabet.
  
  	/**
  	 *  This instance variable stores a reference to the particular
  	 *  ciphertext characters for which this cipher is defined.
  	 */
  	protected Alphabet cipherAlphabet;  // Reference to ciphertext alphabet.
  
  
  	/**
  	 *  The plain key represented as a contiguous array of char.
  	 */
  	protected char[] plainKey;    // Stores the plain key
  
  	/**
  	 *  The cipher key represented as a contiguous array of char.
  	 */
  	protected char[] cipherKey;   // Stores the cipher key
  
  	/**
  	 * Stores the blocksize. Character ciphers (such as Vigenere, Caesar)
  	 * have a blocksize of 1. Block ciphers (such as Playfair) have
  	 * a blocksize that is greater than 1. 
  	 */ 
  	protected int blocksize = 1;  // Blocksize = 1, for char ciphers (DEFAULT)
  
  	/**
  	 * Stores a prompt that can be used by the interface to describes the
  	 *  type of key that would be used for a particular cipher. For example,
  	 *  Caesar cipher would prompt with "positive integer"
  	 */ 
  	protected String keyDescriptorPrompt;
  
  	/**
  	 * searches for the provider named in the second parameter
  	 *  for an implementation of the algorithm named in its first parameter.
  	 * @param algorithm, a String giving the algorithm name
  	 * @param provider, a String giving the provider name
  	 */
  	public static final HistoricalKey getInstance(String algorithm, String provider) {
  		//       System.out.println("Getting key instance " + algorithm + " " + provider);
  		Provider p = new Provider();
  		HistoricalKey key = null;
  		try {
  			String className = p.getCipherKeyName(algorithm, provider);
  			//           System.out.println("Using KEY: " + className);
  			key = (HistoricalKey) Class.forName(className).newInstance();           
  			//           System.out.println("Using Provider: " + p.getName());
  		} catch (Exception e) {
  			System.err.println("Exception getting key instance: " + e.getMessage());
  			e.printStackTrace();
  		}
  		return key;
  	}
  
  	/**
  	 *  Initializes the keyspec, keyword and alphabet instance variables
  	 *  given a specification of the form <i>keydata/plainspec/cipherspec</i>.
  	 *  It also initializes the char arrays.
  	 * @param keyspec is a String specifying algorithm-specific key data
  	 * -- for example the shift value for a Caesar cipher -- and an
  	 * specification of the set of characters used in encryption.
  	 */ 
  	public void initKey(String keyspec, boolean removeDuplicates) throws Exception {
  		this.keyspec = keyspec;
  		if (keyspec.indexOf("/") == -1)
  			throw new Exception("Invalid key specification: " + keyspec);
  		if (keyspec.indexOf("/") == 0)
  			throw new Exception("Keyword missing in key specification: " + keyspec);
  
  		StringTokenizer st = new StringTokenizer(keyspec, "/");
  		if (removeDuplicates)
  			keyword = removeDuplicateChars(st.nextToken()); // e.g., "xylophone" or "5,15"
  		else
  			keyword = st.nextToken();                   // e.g., "xylophone" or "5,15"
  		alphabet = AlphabetFactory.getInstance(st.nextToken());  // e.g., "az"
  
  		if (st.hasMoreTokens())              
  			cipherAlphabet = AlphabetFactory.getInstance(st.nextToken());
  		else 
  			cipherAlphabet = alphabet;
  
  		initKeyArrays();
  	}
  
  	/**
  	 *  ADDED: 4/5/03 by RAM
  	 *  Initializes the key given the keyword and preexisting alphabete.
  	 * @param keyword is a String specifying algorithm-specific key data
  	 * @param alpha1, alpha2 are references to alphabets, alpha2 may identical to alpha1
  	 */ 
  	public void initKey(String keyword, Alphabet alpha1, Alphabet alpha2) throws Exception {
  		alphabet = alpha1;
  		cipherAlphabet = alpha2;
  		this.keyword = keyword;
  		initKeyArrays();
  	}
  
  	/**
  	 *  ADDED: 4/5/03 by RAM
  	 *  This should be implemented in the subclass.
  	 */
  	public abstract void init(String keyword, Alphabet alpha1, Alphabet alpha2) throws Exception;
  
  	/**
  	 * This abstract method should be implemented in the algorithm-specific subclass.
  	 */ 
  	public abstract void init(String keyspec) throws Exception;  
  
  	/**
  	 * This abstract method should be implemented in the algorithm-specific subclass.
  	 */ 
  	public abstract String getAlgorithm();  // Implemented in subclass
  
  	/**
  	 * Returns the keyword for this key.
  	 */ 
  	public String getKeyword() { 
  		return keyword; 
  	}
  
  	/**
  	 * Returns a reference to this key's alphabet.
  	 */
  	public Alphabet getAlphabet() {
  		return alphabet;
  	}
  
  	/**
  	 * Returns a reference to this key's cipherAlphabet.
  	 */
  	public Alphabet getCTAlphabet() {
  		return cipherAlphabet;
  	}
  
  	/**
  	 * Returns this cipher's blocksize.
  	 */ 
  	public int getBlocksize() { 
  		return blocksize; 
  	}
  
  	/**
  	 * Returns an interface prompt describing the key
  	 */ 
  	public String getKeyDescriptorPrompt() { 
  		return keyDescriptorPrompt; 
  	}
  
  	/**
  	 *  A utility method to remove duplicate characters from a
  	 *  string. For example, it would convert the passphrase "hello" to the
  	 *  keyword "helo".
  	 */ 
  	//    protected String removeDuplicateChars(String key) {  // REMOVES DUPLICATE CHARS FROM THE KEYWORD
  	public static String removeDuplicateChars(String key) {  // REMOVES DUPLICATE CHARS FROM THE KEYWORD
  		String newKey = "";
  		for (int k = 0; k < key.length(); k++)       // For each letter in the key
  			if (newKey.indexOf(key.charAt(k)) == -1) // If it's not already in newKey
  			   newKey = newKey + key.charAt(k);     // Append it to newKey
  	    //System.out.println("New final key: " + newKey);
  		return newKey;
  	} //end removeDuplicateChars()     
  
  	/**
  	 *  This method constructs char arrays consisting of
  	 *  the characters in the plaintext and ciphertext alphabets.
  	 *  Note: This method won't work if the keyword has duplicate
  	 *   characters. It will throw an exception.
  	 */ 
  	protected void initKeyArrays() throws Exception {
  		if (alphabet.getSize() != cipherAlphabet.getSize()) 
  			throw new Exception ("ERROR: Plain and cipher alphabets must be the same size");
  
  		char ch;  //Used in loops for storing a character
  
  		plainKey = new char[alphabet.getSize()];
  		if (cipherAlphabet != alphabet) 
  			cipherKey = new char[cipherAlphabet.getSize()];
  		else 
  			cipherKey = new char[alphabet.getSize()];
  
  		StringBuffer keychars = new StringBuffer();
  
  		//Eliminate characters not in the cipher alphabet
  		for (int k = 0; k < keyword.length(); k++) {
  			ch = keyword.charAt(k);
  			if (cipherAlphabet.isInAlphabet(ch))
  				keychars.append(ch);
  		}//for
  
  		String keycharStr = keychars.toString(); 
  
  		//Add any cipher alphabet characters not in keychars
  		for (int k = 0; k < cipherAlphabet.getSize(); k++) {
  			ch = cipherAlphabet.intToChar(k);
  			if (keycharStr.indexOf(ch) == -1) 
  				keychars.append(ch);
  		}//for
  
  		// keychars now contains each cipherAlphabet character exactly once
  		//        System.out.println("Keychars = " + keychars);
  
  		if (keychars.length() != cipherKey.length) 
  			throw new Exception ("ERROR: Unable to construct alphabets from keyword " + keyword);
  
  		for (int k = 0; k < keychars.length(); k++) {
  			ch = keychars.charAt(k);
  			//          System.out.println("keychars.len = " + keychars.length() + " ch= " + ch);
  			cipherKey[k] = ch;
  			plainKey[cipherAlphabet.charToInt(ch)] = alphabet.intToChar(k);
  		}//for
  	} //initKeyArrays()
  
  	
  	/**
  	 * Returns the cipher alphabet.
  	 */
  	public char[] getCipherKey() {
  		return cipherKey;
  	}
  
  	/**
  	 * Returns the plaintext alphabet.
  	 */
  	public char[] getPlainKey() { 
  		return plainKey; 
  	}
  
  
  	/**
  	 *  Prints both the cipher and plain alphabets to the System console.
  	 */
  	public void printAlphabets() {
  		for (int k = 0; k < cipherAlphabet.getSize(); k++)
  			System.out.print(cipherKey[k]);
  		System.out.println();
  