import java.util.Arrays;
import java.util.*;
import java.io.*;
import static   BH.Bytes_Hex.*;

class theKey implements java.io.Serializable {
    protected int[]  p; //The permutation
    protected byte[] m; //The mask
}

public class build_store {
    protected int[]  p;
    protected byte[] m;

    public static void main(String[] args){
        build_store akstore=new build_store();
        akstore.test();

    }
    public build_store(){
        p=Shuffle();
        m=AMask();
        try {
            theKey tK=new theKey();
            tK.p=p;
            tK.m=m;
            ObjectOutputStream out=new ObjectOutputStream( new FileOutputStream("mykey.dat"));
            out.writeObject(tK);
            out.close();
        } catch (Exception e) {
        }
    }

    private int[] Shuffle(){
        int N = 16;
        int r;
        int[][] a = new int[N][2];
        // insert integers 0..N-1
        for (int i = 0; i < N; i++) {
            a[i][0] = i;a[i][1]=0;
        }
        // shuffle
        for (int i = 0; i < N; i++) {
            if (a[i][1]==0) {
                a[i][1]=1;
                while (true) {
                    r = (int) (Math.random() * (N));
                    if (a[r][1]==0)break;
                }
                int swap = a[r][0];
                a[r][0] = a[i][0];
                a[r][1] =1;
                a[i][0] = swap;
            }
        }
        int [] p=new int[N];
        for (int i=0;i<16;i++)p[i]=a[i][0];
        return p;
    }

    private byte[] AMask(){
        byte[] theMask=new byte[8];
        for (int i=0;i<8;i=i+1) {
            theMask[i] = (byte) (Math.random() * (256));
        }
        return theMask;
    }
    ////////////Testing//////////////////////


    public void test(){
        String s="Code it.";  //8 bytes
        System.out.println("\n"+s);
        System.out.println(Decode(Encode(s)));
    }

    private  char[] permute(char[] s, int[] p ){
        char[] encoded=new char[16];
        for (int i=0;i<16;i=i+1) {
            encoded[i]=s[p[i]];
        }
        return encoded;
    }


    private byte[] mask(byte[] theBytes,byte[] theMask){
        byte[] theEncodedBytes=new byte[8];
        for (int i=0;i<8;i=i+1) {
            theEncodedBytes[i]=(byte)(theBytes[i]^theMask[i]);
        }
        return theEncodedBytes;
    }

    public String Encode(String s){
        byte[] theBytes = s.getBytes();
        System.out.println("Unmasked\n"+Arrays.toString(theBytes));
        byte[] theEncodedBytes=mask(theBytes,m);
        System.out.println("Masked\n"+Arrays.toString(theEncodedBytes));
        String hexstring= ByteArray2HexString(theEncodedBytes);
        System.out.println("Hex String\n"+hexstring);
        //Get ready to apply the permutation.
        char[] theHexBytes=hexstring.toCharArray();
        System.out.println("\n"+Arrays.toString(theHexBytes));
        //Apply the permutation.
        char[] Encoded=permute(theHexBytes,p);
        System.out.println("Permuted\n"+Arrays.toString(Encoded));
        byte[] theNewBytes=HexArray2ByteArray(Encoded);
        theNewBytes=mask(theNewBytes,m);
        System.out.println("Masked Again\n"+Arrays.toString(theNewBytes));
        return new String(theNewBytes);    
    }
    public String Decode(String s){
        System.out.println("______________\nNow Decode it\n______________");
        return Encode(s);
    }

}