import java.util.Arrays;
import java.util.*;
import java.io.*;
import java.nio.file.*;
class theKey implements java.io.Serializable {
protected int[] p; //The permutation
protected byte[] m; //The mask
}
public class build_store16 {
protected int[] p;
protected byte[] m;
public static void main(String[] args){
build_store16 akstore=new build_store16();
akstore.test();
}
public build_store16(){
p=Shuffle();
m=AMask();
try {
theKey tK=new theKey();
tK.p=p;
tK.m=m;
Files.deleteIfExists(Paths.get("./mykey.dat"));
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;
}
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<N;i++)p[i]=a[i][0];
System.out.println("The Shuffel\n"+Arrays.toString(p));
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(s);
System.out.println(Decode(Encode(s)));
}
private byte[] permute(byte[] s, int[] p ){
byte top=(byte)240;
byte bottom=(byte)15;
byte[] start=new byte[16];
for (int i=0;i<8;i++) {
start[2*i]=getTop(s[i]);
start[2*i+1]=(byte)(s[i]&bottom);
}
System.out.println("The start\n"+Arrays.toString(start));
byte[] encode16=new byte[16];
for (int i=0;i<16;i=i+1) {
encode16[i]=start[p[i]];
}
byte[] encoded=new byte[8];
for (int i=0;i<8;i++) {
encoded[i]=(byte)((encode16[2*i]<<4)+encode16[2*i+1]);
}
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=new byte[s.length()];;
try{theBytes = s.getBytes( "ISO-8859-1");}
catch(Exception e){System.out.println("can't do that");}
System.out.println("Unmasked\n"+Arrays.toString(theBytes));
byte[] theMaskedBytes=mask(theBytes,m);
System.out.println("Masked\n"+Arrays.toString(theMaskedBytes));
byte[] ThePermutedBytes=permute(theMaskedBytes,p);
System.out.println("Permuted\n"+Arrays.toString(ThePermutedBytes));
byte[] theNewBytes=mask(ThePermutedBytes,m);
System.out.println("Masked Again\n"+Arrays.toString(theNewBytes));
try{ return new String(theNewBytes, "ISO-8859-1"); }
catch(Exception e){System.out.println("can't do that either");}
return "bah";
}
public String Decode(String s){
System.out.println("______________\nNow Decode it\n______________");
return Encode(s);
}
public byte getTop(byte tester){
// byte tester=(byte)240;
byte shifted=0;
int the_part=0;
int all=0;
for (int i=4;i<8;i++) {
the_part=(GetBit(tester,i))?(int)Math.pow(2,(i-4)) :0;
// Is the bit in position i 1 or 0
// If a 1 add 2 to the i-4.
all=all+the_part;
}
return(byte)all ;
}
static boolean GetBit(byte thebyte, int position){
return(1 == ((thebyte >> position) & 1));
}
}