/*
 *  CsvJdbc - a JDBC driver for CSV files
 *  Copyright (C) 2001  Jonathan Ackerman
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *  This library 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
 *  Lesser General Public License for more details.
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.relique.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Example encryption filter that XOR's the all data with a secret seed value.
 */
public class XORCipher implements CryptoFilter
{
	private int keyCounter;
	private int[] scrambleKey;

	public XORCipher(String seed)
	{
		scrambleKey = new int[seed.length()];
		for (int i = 0; i < seed.length(); i++)
			scrambleKey[i] = seed.charAt(i);
		keyCounter = 0;
	}

	@Override
	public int read(InputStream in) throws IOException
	{
		if (in.available() > 0)
		{
			return (byte) scrambleInt(in.read());
		}
		else
			return -1;
	}

	@Override
	public int read(InputStream in, byte[] b) throws IOException
	{
		int len;
		len = in.read(b, 0, b.length);
		scrambleArray(b);
		return len;
	}

	@Override
	public int read(InputStream in, byte[] b, int off, int len)
			throws IOException
	{
		len = in.read(b, off, len);
		scrambleArray(b);
		return len;
	}

	@Override
	public String toString()
	{
		return "XORCipher(" + scrambleKey.length + "):'" + scrambleKey + "'";
	}

	/**
	 * Perform the scrambling algorithm (named bitwise XOR encryption) using
	 * bitwise exclusive OR (byte) encrypted character = (byte) original
	 * character ^ (byte) key character.
	 * <p/>
	 * Note that ^ is the symbol for XOR (and not the mathematical power)
	 * 
	 * @param org
	 *            is the original value
	 * @return
	 */
	private int scrambleInt(int org)
	{
		int encrDataChar = org ^ scrambleKey[keyCounter];
		keyCounter++;
		keyCounter %= scrambleKey.length;
		return encrDataChar;
	}

	/**
	 * Perform the scrambling algorithm (named bitwise XOR encryption) using
	 * bitwise exclusive OR (byte) encrypted character = (byte) original
	 * character ^ (byte) key character.
	 * <p/>
	 * Note that ^ is the symbol for XOR (and not the mathematical power)
	 * 
	 * @param org
	 *            is the original byte array
	 * @return
	 */
	private void scrambleArray(byte[] org)
	{
		for (int i = 0; i < org.length; i++)
		{
			org[i] ^= scrambleKey[keyCounter];
			keyCounter++;
			keyCounter %= scrambleKey.length;
		}
	}

	@Override
	public void write(OutputStream out, int ch) throws IOException
	{
		out.write(scrambleInt(ch));
	}

	@Override
	public void reset()
	{
		keyCounter = 0;
	}
}

@@ -1835,76 +1835,259 @@
 %7B%0A%09%09
-return %22XORCipher(%22 + scrambleKey.length + %22):'%22 + scrambleKey + %22'%22
+StringBuilder sb = new StringBuilder(%22XORCipher(%22);%0A%09%09sb.append(scrambleKey.length);%0A%09%09sb.append(%22):'%22);%0A%09%09for (int i = 0; i %3C scrambleKey.length; i++)%0A%09%09%7B%0A%09%09%09if (i %3E 0)%0A%09%09%09%09sb.append(' ');%0A%09%09%09sb.append(i);%0A%09%09%7D%0A%09%09sb.append(%22'%22);%0A%09%09return sb.toString()
 ;%0A%09%7D
@@ -2486,16 +2486,73 @@
 taChar =
+ org;%0A%09%09if (scrambleKey.length %3E 0)%0A%09%09%7B%0A%09%09%09encrDataChar =
  org %5E s
@@ -2575,16 +2575,17 @@
 unter%5D;%0A
+%09
 %09%09keyCou
@@ -2590,24 +2590,25 @@
 ounter++;%0A%09%09
+%09
 keyCounter %25
@@ -2629,16 +2629,20 @@
 length;%0A
+%09%09%7D%0A
 %09%09return
@@ -3049,16 +3049,51 @@
 org)%0A%09%7B%0A
+%09%09if (scrambleKey.length %3E 0)%0A%09%09%7B%0A%09
 %09%09for (i
@@ -3123,23 +3123,25 @@
 h; i++)%0A
+%09
 %09%09%7B%0A%09%09%09
+%09
 org%5Bi%5D %5E
@@ -3162,32 +3162,33 @@
 keyCounter%5D;%0A%09%09%09
+%09
 keyCounter++;%0A%09%09
@@ -3177,32 +3177,33 @@
 %09%09keyCounter++;%0A
+%09
 %09%09%09keyCounter %25=
@@ -3219,24 +3219,29 @@
 Key.length;%0A
+%09%09%09%7D%0A
 %09%09%7D%0A%09%7D%0A%0A%09@Ov

Allow empty scrambleKey in XORCipher for no ciphering