#include
#include
#include
enum{MAX=2000}; //The
maximum of message char(s) in input txt
enum{LEN=10}; //The maximum of keyword
char original[MAX]; //array
which locates original char(s) of input txt
char
result[MAX]; //array which
locates succession of result char(s) after operation
int
kword[LEN]; //array which key-word register in
static int num=0; //The number
of char(s) in input txt
static int
key=0; //The key of encryption
//Deleting the repeat chars in key-word
int unRepeat(int kword[],int key)
{
int i,j,l;
for(i=1;i
for(j=0;j
if(kword[i]==kword[j])
{
for(l=i;l
kword[l]=kword[l+1];
key--; //Update
latest key value
}
return key;
}
//Obtaining the key from user's input
void getKey()
{
int i;
puts("Enter the key-word please:");
puts("(For example:“hill”)");
for(i=0;i
{
char c=NULL;
scanf("%c",&c);
if(c=='\n') //Once encounter
terminative symbol,
break; //terminate
read in form screen.
kword[i]=int(c); //Register
in key-word
if(kword[i]>=65&&kword[i]<=90)
kword[i]+=32; //Converting
capital letter to small letter
kword[i]-=97; //Converting
ASCII code to letter sequence-number
}
key=i; //Record
number of key-word
key=unRepeat(kword,key); //Deleting
the repeat chars in key-word
}
//Reading input message from txt
void readPlaintext()
{
FILE *fp;
fp=fopen("Input_hill.txt","r");
int i=0;
do
{
char ch=NULL;
fscanf(fp,"%c",&ch);
if(ch!='
') //Once char read-in is not a blank
original[i++]=ch;
//register it in original[]
}
while(i
whether the sum of char(s) overrun maxinum
//and
encounter terminative symbol “@”
num=i-1; //Record number of
message char(s) in input txt
//num+1
is location of “@”, there are num message char(s)
if(num%key!=0)
{
//Complement original[] by 'x'
so that num is a multiple of key
for(i=1;i
original[num+i-1]='x';
num=(num/key+1)*key;
}
if(num>=2000)
{
//Display a prompt if input
char(s) overrun maxinum
printf("May be
overflow...\n");
exit(-1);
}
for(i=0;i
{
if(original[i]>=65&&original[i]<=90)
original[i]+=32; //Converting
capital letter to small letter
original[i]-=97; //Converting ASCII code to letter sequence-number
}
fclose(fp);
}
//Converting given determinant to up-triangle
determinant
void convert(double m[][LEN],int n)
{
//array m is the pending matrix
//n is the dimension of this matrix
int i,j,e;
double d=1.0;
for(i=1;i
for(e=i;e
{
if(0==m[i-1][i-1]) //If
it equals 0, it is unnecessary to operate
break;
d=m[e][i-1]/m[i-1][i-1];
for(j=i-1;j
m[e][j]-=d*m[i-1][j];
}
}
//Calculating the value of given
determinant
double det(double m[][LEN],int n)
{
//array m is the pending matrix
//n is the dimension of this matrix
int i,j;
double t=1;
convert(m,n); //Converting
matrix m to a up-triangle determinant
for(i=0,j=0;i
t*=m[i][j]; //Multiply
items on prime diagonal continuously
//obtain
the determinant
return t;
}
//Calculating Cofactor for one item at
discretion of a matrix
// Cofactor n.余子式
double cofactor(int p,int q,double a[][LEN],int n)
{
//p is index of the item in row
//q is index of the item in column
//array a is the pending matrix
//n is the dimension of this matrix
int i,j;
double
b[LEN][LEN]; //array locates
the sub-matrix which will produce Cofactor
int e=0,f=0;
//Here i,j denote items in the matrix which will
birth sub-matrix for the counting Cofactor
//e,f denote items in sub-matrix
//But p,q are the indexes denote which item's
Cofactor is counting now
//So i,j mustn't be set as static value!
for(i=0,e=0;i
if(i!=p)
for(j=0,f=0;j
{
if(j!=q)
b[e][f]=a[i][j]; //Fill
legitimacy items of matrix a into matric b
else
f--;
}
else
e--;
}
return det(b,n-1); //The
determinant of sub-matrix is the Cofactor of the given
item(p,q)
}
//Counting power of a given number
double power(double x,int n)
{
int i;
double y=1;
for(i=0;i
y*=x;
return y;
}
//Calculating the adjoint of given
matrix
// adjoint n.伴随矩阵
void adjoint(double a[][LEN],double b[][LEN],int n)
{
//array a is the pending matrix
//array b will locate the adjoint of a
//n is the dimension of the 2 matrixes
int i,j;
for(i=0;i
for(j=0;j
b[i][j]=power(-1,i+j)*cofactor(j,i,a,n);
//the Algebraic Cofactor
//which is the item of adjoint
}
//Calculating the inverse-matrix of given
matrix
void inverse(double a[][LEN],double b[][LEN],int n)
{
//array a is the pending matrix
//array b will locate the inverse-matrix of
a
//n is the dimension of the 2 matrixes
int i,j;
double comp[LEN][LEN]; //array
which locates adjoint
adjoint(a,comp,n); //Calculating
the adjoint for matrix a
//and
return the adjoint as matrix comp[][]
for(i=0;i
for(j=0;j
b[i][j]=comp[i][j]/det(a,n);
}
//Creating the fake-ramdom num
int ra(int a,int b,int *r)
{
//a is the lower-bound of ramdom num which will
be created
//b is the high-bound of ramdom num which will be
created
int k,m,p,l=2,i=1;
k=b-a+1;
while(l
l=l*2;
m=4*l;
k=*r; //r is the seed of this
algorithm
while(i<=1)
{
k=5*k%m;
l=k/4+a;
if(l<=b)
{
p=l;
i++;
}
}
*r=k;
return p;
}
//Creating the encrypt-matrix
void createKM_e(int kword[],int key,double km[][LEN])
{
int i,j;
for(i=0;i
{
int
r=kword[i]; //Enery char in user's keyword will
be a seed
//for the creation of items in encrypt-matrix
for(j=i;j
km[i][j]=double(ra(2,15,&r)); //Fill the fake-ramdom num into encrypt-matrix
//(to form a up-triangle determinant)
}
for(i=0;i
km[i][i]=1.0; //Set items on
prime diagonal as 1
//(Make determinant of encrypt-matrix equal 1)
}
//Creating the decrypt-matrix
void createKM_d(int kword[],int key,double km[][LEN])
{
int i,j;
createKM_e(kword,key,km); //Creating
the encrypt-matrix
double
tem[LEN][LEN]={0.0}; //array
locates encrypt-matrix temporarily
for(i=0;i
for(j=0;j
tem[i][j]=km[i][j];
inverse(tem,km,key); //Calculating
decrypt-matrix (inverse-matrix of encrypt-matrix)
}
//Prompting user make choice.
//According to user's input carry the preparative for encryption or
decryption out
void menu(int kword[],int key,double km[][LEN])
{
system("cls");
puts("Encrypt or Decrypt?");
puts("(Choose “E” or “D”)");
char option;
scanf("%c",&option);
if(option=='E'||option=='e')
createKM_e(kword,key,km); //Creating
the encrypt-matrix
else if(option=='D'||option=='d')
createKM_d(kword,key,km); //Creating
the decrypt-matrix
else
{
puts("Error input!");
exit(-1);
} }
//Achieve the Hill Algorithm
void hill(int cell[],int key,double km[][LEN])
{
int i,j;
double c[LEN]={0.0}; //array
locates char operated temporarily
for(i=0;i
for(j=0;j
c[i]+=km[i][j]*cell[j]; //Crucial
operation
//during
either encryption or decryption
//The ciphertext which will be created has
extraordinary close relationship with each character in
plaintext!
for(i=0;i
{
while(c[i]<=0)
c[i]+=26; //Make
sure c[i] are all positive-number(s)
cell[i]=int(c[i])%26+97; //so
that after (mod26) it can be a letter sequence-number
//and
after (+97) it can be a ASCII code of a small letter
}
}
//Operating on the succession of input
char(s)
void encrypt(char original[],char result[],int key)
{
int i,j;
double km[LEN][LEN]={0.0};
menu(kword,key,km); //preparative
for encryption or decryption
for(i=0;i
module encrypt or decrypt input message char(s)
{ //Each
module has key char(s) and there are num/key module(s)
int
cell[LEN]={0}; //array locates each char
module
for(j=0;j
cell[j]=int(original[i*key+j]); hill(cell,key,km); //Algorithm
Implement
for(j=0;j
result[i*key+j]=char(cell[j]);
}
}
//Printing output message to txt
void output()
{
int i;
FILE* fo=fopen("Output_hill.txt","w");
for(i=0;i
fprintf(fo,"%c",result[i]);
fprintf(fo,"\n");
//Print out Olympic^o^
time_t t;
struct tm * a;
time(&t);
a=localtime(&t);
int year=1900+a->tm_year;
int month=1+a->tm_mon;
int day=a->tm_mday;
int duration;
int count_down(int,int,int);
duration=count_down(year,month,day);
fprintf(fo,"\n孙毅提醒您:
距2008北京奥运开幕还有%d天。\n",duration);
fclose(fo);
puts("\nWork has finished.");
puts("Look up result_hill.txt and have a
cheer!\n\n");
}
//Judging whether this year is a leap
year
int isLeap(int x)
{
if(0==x%4&&x%100!=0||0==x%400)
return 1;
else
return 0;
}
//Calculating how many days in given
month
int days_inMonth(int a,int b)
{
if(2==b)
{
if(1==isLeap(a))
return
29;
else
return
28;
}
else if(4==b||6==b||9==b||11==b)
return 30;
else
return 31;
}
//Calculating the index of given date in the
year
int index(int a,int b,int c)
{
int t=0;
int i;
for(i=1;i
t+=days_inMonth(a,i);
return t+c;
}
//Calculating duration
int count_down(int a,int b,int c)
{
int
span_inYear=index(2008,8,8)-index(a,b,c);
int span_betweenYears=2008-a;
int span=span_betweenYears*365+span_inYear;
span+=(2008-a)/4;
return span;
}
void main()
{
getKey(); //Obtaining
key
readPlaintext(); //Reading
input from txt
encrypt(original,result,key); //Encrypt or Decrypt
output(); //Printing
output message to txt
}