#include <stdio.h>
#include <conio.h>
#include <process.h>

#define NBIT  8

void init_table(int *permu_table);
unsigned char permutation(unsigned char data, int *permu_table);
unsigned char unpermutation(unsigned char data, int *permu_table);
unsigned char key(unsigned char data, char key);

void main () {
 int permu_table[NBIT];
 char ch;
 FILE *fpi, *fcipher, *freverse, *fkey ,*funkey;

 init_table(permu_table);

 if((fpi = fopen("plain.txt","r"))==NULL)  {
   printf("Can not Open File\n");
   exit(-1);
 }

 if((fcipher = fopen("cipher.txt","w"))==NULL)  {
   printf("Can not Open File\n");
   exit(-1);
 }

 if((freverse = fopen("reverse.txt","w"))==NULL)  {
   printf("Can not Open File\n");
   exit(-1);
 }

 if((fkey = fopen("key.txt","w"))==NULL)  {
   printf("Can not Open File\n");
   exit(-1);
 }

 if((funkey = fopen("unkey.txt","w"))==NULL)  {
   printf("Can not Open File\n");
   exit(-1);
 }

 clrscr();
 ch=getc(fpi);
 while(ch!=EOF)  {
   putc(permutation(ch, permu_table), fcipher); /* Encrypt plain.txt to cipher.txt */
   putc(unpermutation( permutation(ch,
        permu_table), permu_table), freverse);  /* Decrypt of permutation to reverse.txt */
   putc(key(ch, 'a'), fkey);                    /* Encrypt plain.txt to key.txt */
   putc(key(key(ch, 'a'),'a'), funkey);         /* Decrypt of key to unkey.txt */
   ch=getc(fpi);
 }
 fclose(fpi);
 fclose(fcipher);
 fclose(freverse);
 fclose(funkey);
 fclose(funkey);
}

void init_table(int *permu_table) {
  permu_table[0] = 7;  /* initialize table of bit permutation */
  permu_table[1] = 6;
  permu_table[2] = 5;
  permu_table[3] = 4;
  permu_table[4] = 3;
  permu_table[5] = 2;
  permu_table[6] = 1;
  permu_table[7] = 0;
}

unsigned char permutation(unsigned char data, int *permu_table)  {
  int i;
  unsigned char mask, result=0, output=0;

  for(i=0; i<NBIT; i++)  {
    if(permu_table[i] >= i)
      output=data<<(permu_table[i]-i);
    else
      output=data>>(i-permu_table[i]);
    mask=0x01<<permu_table[i];
    output&=mask;
    result|=output;
  }
  return(result);
}

unsigned char unpermutation(unsigned char data, int *permu_table)  {
  int i;
  unsigned char mask, result=0, output=0;

  for(i=0; i<NBIT; i++)  {
    if(permu_table[i] >= i)
      output=data>>(permu_table[i]-i);
    else
      output=data<<(i-permu_table[i]);
    mask=0x01<<i;
    output&=mask;
    result|=output;
  }
  return(result);
}

unsigned char key(unsigned char data, char key)  {
  return(data^key);
}

