import java.util.Vector;
import java.io.FileInputStream;

public class Pad {
    // Note: if you have Java 1.4, you can use assert instead
    static private void check (boolean b, String s) {
	if (!b) {
	    System.err.println ("Assertion failed: " + s);
	    System.exit (1);
	}
    }

    static private char bitsToChar (boolean [] bits) {
	check (bits.length == 7, "bitsToChar: input array must be seven bits");

	int value = 0;
	for (int i = 0; i < bits.length; i++) {
	    value *= 2;
	    if (bits[i]) { value++; }
	}

	check (value >= 0 && value < 128, "Value out of range: " + value);
	return (char) value;
    }


    static public Vector /*boolean []*/ readFileBits (FileInputStream fin) {
	// Reads a file of "0" and "1" (characters) into a Vector
	// of 7-bit boolean arrays
	Vector res = new Vector ();
	int nbit = 0;

	try {
	    boolean bits [] = new boolean [7];
	    int rchar;

	    while ((rchar = fin.read ()) != -1) {
		if ((char) rchar == '0') {
		    bits[nbit++] = false;
		} else if ((char) rchar == '1') {
		    bits[nbit++] = true;
		} else if (Character.isWhitespace ((char) rchar)) {
		    ; // okay, skip whitespace
		} else {
		    check (false, "Bad character in file: " + (char) rchar);
		}

		if (nbit == 7) {
		    res.add (bits);
		    bits = new boolean[7];
		    nbit = 0;
		}
	    }

	    check (nbit == 0, "Incomplete data: " + nbit);
	} catch (Exception e) {
	    check (false, "Exception reading file: " + e);
	}

	return res;
    }
    
    static String toBitString (Vector bits) {
	String res = "";

	for (int i = 0; i < bits.size (); i++) {
	    boolean [] current = (boolean []) bits.get (i);
	    check (current.length == 7, "Bad bit array: " + current.length);
	    for (int b = 0; b < 7; b++) {
		if (current[b]) {
		    res += '1';
		} else {
		    res += '0';
		}
	    }

	    res += ' ';
	}

	return res;
    }

    static String toAlphaString (Vector bits) {
	String res = "";

	for (int i = 0; i < bits.size (); i++) {
	    boolean [] current = (boolean []) bits.get (i);
	    check (current.length == 7, "Bad bit array");
	    char c = bitsToChar (current);
	    res += c;
	}

	return res;
    }

    static public void main (String args[]) {
	if (args.length != 2) {
	    System.err.println ("Usage: java Pad <key file> <message file>");
	}

	FileInputStream kfile;
	FileInputStream mfile;

	try {
	    kfile = new FileInputStream (args[0]);
	} catch (Exception e) {
	    System.err.println ("Cannot open key file: " + e);
	    System.exit (1);
	    kfile = null; // Keep javac happy
	}

	try {
	    mfile = new FileInputStream (args[1]);
	} catch (Exception e) {
	    System.err.println ("Cannot open message file: " + e);
	    System.exit (1);
	    mfile = null; // Keep javac happy
	}

	Vector /*[boolean []]*/ keybits = readFileBits (kfile);
	Vector /*[boolean []]*/ msgbits = readFileBits (mfile);

	// The key must be at least as long as the message
	check (keybits.size () >= msgbits.size (),
		"Message length is longer than key: " + keybits.size () 
		+ " key characters, " + msgbits.size () + " message characters.");

	Vector cipherbits = new Vector ();
	for (int i = 0; i < msgbits.size (); i++) {
	    boolean [] key = (boolean []) keybits.get (i);
	    boolean [] msg = (boolean []) msgbits.get (i);
	    boolean [] cipher = new boolean [7];
	    check (key.length == 7, "Incorrect key length");
	    check (msg.length == 7, "Incorrect message length");

	    for (int b = 0; b < 7; b++) { 
		cipher[b] = key[b] ^ msg[b]; // ^ is XOR
	    }

	    cipherbits.add (cipher);
	}
	
	System.out.println (toBitString (cipherbits));
	System.out.println (toAlphaString (cipherbits));
    }
}
