//
// XorCryptographer.java - A fast (and unsafe) cryptographer that uses a simple xor algorithm.
//
// Copyright (C) 1996-1997 by Connect Software, Inc. All rights reserved.
//
// All the usual legal disclaimers and restrictions applicable to cryptography apply.
//
// Disclaimer: This is nothing more than toy cryptography (similar to the one used in digital cellular phones).
//
// Designed and written by Gionata Mettifogo.
//

package connect.cryptography;                                           // belong to the cryptography package

public class XorCryptographer extends Cryptographer
{
    /** Initialize xor cryptographer using given string as the encryption and decryption private key. */

    public XorCryptographer(String privateKey)
    {
        int len = privateKey.length();                                  // length of the private key string

        key = new byte[len];                                            // create array of bytes for the key

        privateKey.getBytes(0,len,key,0);                               // convert string into array of bytes
    }

    /** Initialize xor cryptographer using standard private key. */

    public XorCryptographer()
    {
        this("R1@t5&*43,.:{=zDy)_y+}]|y&7k5/#3gt,{szq!`:+");            // use default key
    }

    /** Encrypts the given block of data. */

    public void encrypt(byte [] data, int offset, int length)
    {
        for(int i = offset, j = offset + length ; i < j ; i++)          // encrypt each byte in the data
        {
            byte b = data[i];

            data[i] ^= key[count++ % key.length] ^ previous;            // xor current byte with key and previous byte

            previous = b;                                               // remember current uncrypted byte (will be used to encrypt the next)
        }
    }

    /** Decrypts the given block of data. */

    public void decrypt(byte [] data, int offset, int length)
    {
        for(int i = offset, j = offset + length ; i < j ; i++)          // encrypt each byte in the data
        {
            data[i] ^= previous ^ key[count++ % key.length];            // xor current byte with key and previous byte

            previous = data[i];                                         // remember current byte (will be used to encrypt the next)
        }
    }

    /** The key used for encryption. */

    private byte [] key = null;

    /** Index in key of the byte that will be used to encrypt the next byte. */

    private int count = 0;

    /** The last byte encrypted (used to encrypt following byte). */

    private byte previous = (byte) 0xE3;                                // this is just some random number (so that the first byte also looks like it's encrypted)
}

