import java.io.*;
public class Encode {
   InputStream in; // input file
   OutputStream out; // output file

   long seed1;
   long seed2;
   long seed;
   long seed3;
   long seed4;
   long seed5;
   long ah1 = 161803398;
   long ah2 = 316227766;
   long ah3 = 230258509;
   long ah4 = 577215664;

   public Encode() {
   }

   public Encode(InputStream infile, OutputStream outfile, String passwd) {
      in =  infile;
      out = outfile;
      seed1 = hashit(passwd, ah1);
      seed2 = hashit(passwd, ah2);
      seed3 = hashit(passwd, ah3);
      seed4 = hashit(passwd, ah4);
   }

   // writeByte: write byte
   private void writeByte(int b) {
      try {
         out.write(b);
      } catch (IOException e) {
         System.err.print("Error writing file");
         System.exit(-1);
      }
   }

   public void processFile() {
      try {
         int b; // input byte
         while ((b = in.read()) != -1) {
            int r = randByte();
            int s = randByte3();
            b = b ^ r ^ s;
            writeByte(b);
         } // end of while
      } catch (IOException e) {
         System.err.println("Error reading input file");
         System.exit(-1);
      } // end try
   }
   
   // rand: version using doubles.  Works on all hardware.
   // seed1 = 48271*seed1 mod 2^31 - 1
   // seed2 = 40691*seed1 mod 2^31 - 249
   // seed  = (seed1 - seed2) mod 2^31 -1
   private double rand() {
      long a1 = 48271,        a2 = 40692,
           m = 2147483647,    m2 = 2147483399;
      long q1,                q2;
      long q, diff;
      seed1 = a1*seed1;       seed2 = a2*seed2;
      q1 = seed1/m;    q2 = seed2/m2;
      seed1 = seed1 - q1*m;     seed2 = seed2 - q2*m2;
      // now combine results
      if ((diff = seed1 - seed2) < 0.0) diff = diff + m;
      q = diff/m;
      seed = diff - q*m;
      return((double)seed/(double)m);
   }

   private int randByte() {
      int b = (int)(256.0*rand());
      return b;
   }

   private double rand3() {
      long a3 = 271828183,
           a4 = 314159269,
           m2 = 2147483399;
      long q3;
      seed5 = (a3*seed3 - a4*seed4) % m2;
      if (seed5 < 0) seed5 = seed5 + m2;
      seed3 = seed4;
      seed4 = seed5;
      return((double)seed5/(double)m2);
   }

   private int randByte3() {
      int b = (int)(256.0*rand3());
      return b;
   }

   public long hashit(String key, long ah) {
      long s = ah; // 2^30 - 35
      long m = 2147483647;
      long a = s;
      for (int i = 0; i < key.length(); i++) {
        s = (s + ah*key.charAt(i)) % m;
      }
      return s;
   }
}