⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idea.c

📁 强大的加解密算法
💻 C
字号:

#include "idea.h"

static uint16 inv(uint16 x)
{
   uint16 t0,t1;
   uint16 q,y;
   if (x<=1)
      return x;
   t1=(uint16)(0x10001l/x);
   y=(uint16)(0x10001l%x);
   if (y==1)
	return low16(1-t1);
   t0=1;
   do
   {
      q=x/y;
      x=x%y;
      t0+=q*t1;
      if (x==1)
	return t0;
      q=y/x;
      y=y%x;
      t1+=q*t0;
   } while (y!=1);
   return low16(1-t1);
}

static void en_key_idea(word16 *userkey, word16 *Z)
{
   int i,j;
   /* shifts */
   for (j=0;j<8;j++)
      Z[j]=*userkey++;
   for (i=0;j<KEYLEN;j++)
   {
      i++;
      Z[i+7]=((Z[i&7] << 9) | (Z[i+1 & 7] >> 7));
      Z+=i&8;
      i&=7;
   }
}

static void de_key_idea(IDEAkey Z,IDEAkey DK)
{
   int j;
   uint16 t1,t2,t3;
   IDEAkey T;
   word16 *p=T+KEYLEN;
   t1=inv(*Z++);
   t2=-*Z++;
   t3=-*Z++;
   *--p=inv(*Z++);
   *--p=t3;
   *--p=t2;
   *--p=t1;
   for (j=1;j<ROUNDS;j++)
   {
      t1=*Z++;
      *--p=*Z++;
      *--p=t1;
      t1=inv(*Z++);
      t2=-*Z++;
      t3=-*Z++;
      *--p=inv(*Z++);
      *--p=t2;
      *--p=t3;
      *--p=t1;
   }
   t1=*Z++;
   *--p=*Z++;
   *--p=t1;
   t1=inv(*Z++);
   t2=-*Z++;
   t3=-*Z++;
   *--p=inv(*Z++);
   *--p=t3;
   *--p=t2;
   *--p=t1;
   /*copy and destroy temp copy*/
   for(j=0,p=T;j<KEYLEN;j++)
   {
      *DK++=*p;
      *p++=0;
   }
}


uint16 mul(uint16 a, uint16 b)
{
   word32 p;

   if (a)
   {
      if (b)
      {
	 p=(word32)a*b;
	 b=(uint16)(low16(p));
	 a=(uint16)(p>>16);
	 return b-a+(b<a);
      }
      else
      {
	 return 1-a;
      }
   }
   else
      return 1-b;
}

#define MUL(x,y) (x=mul(low16(x),y))


#define CONST

static void cipher_idea(word16 in[4],word16 out[4],register CONST IDEAkey Z)
{
   register uint16 x1,x2,x3,x4,t1,t2;
   int r=ROUNDS;
   x1=*in++; x2=*in++;
   x3=*in++; x4=*in;
   do
   {
      MUL(x1,*Z++);
      x2+=*Z++;
      x3+=*Z++;
      MUL(x4,*Z++);
      t2=x1^x3;
      MUL(t2,*Z++);
      t1=t2+(x2^x4);
      MUL(t1,*Z++);
      t2=t1+t2;
      x1^=t1;
      x4^=t2;
      t2^=x2;
      x2=x3^t1;
      x3=t2;
   } while (--r);
   MUL(x1,*Z++);
   *out++=x1;
   *out++=(x3+*Z++);
   *out++=(x2+*Z++);
   MUL(x4,*Z);
   *out=x4;
}

char read_char_from_file(FILE *fp)
{
   char temp=0;

   if ((fread(&temp,sizeof(char),1,fp))!=1)
      end_of_file=1;

   return (temp);
}

word16 read_word16_from_file(FILE *fp)
{
   word16 temp=0;

   if ((fread(&temp,sizeof(word16),1,fp))!=1)
      end_of_file=1;

   return temp;
}

void write_char_to_file(char data,FILE *fp)
{
   if ((fwrite(&data,sizeof(char),1,fp))!=1)
   {
      printf("Fatal Error writing output file!!!\n");
      exit(-1);
   }
}

void write_word16_to_file(word16 data,FILE *fp)
{
   if ((fwrite(&data,sizeof(word16),1,fp))!=1)
   {
      printf("Fatal Error writing output file!!!\n");
      exit(-1);
   }
}


void cipher_file(FILE *in,FILE *out,word16 *key)
{
   word16 input[4],output[4];
   IDEAkey Z;
   int x,y;
   int count=0;
   long length;
   int temp;

   en_key_idea(key,Z);
   end_of_file=0;

   length=filelength(fileno(in));
   fwrite(&length,sizeof(long),1,out);

   while (!end_of_file)
   {
      x=0;

      while (x<4)
      {
	 input[x]=((word16)(read_char_from_file(in)<<8));
	 if (!end_of_file)
	 {
	    temp=read_char_from_file(in);
	    if (temp<0) temp+=256;
	    input[x]=input[x]|temp;
	    x++;
	 }
	 if (end_of_file)
	 {
	    while (x<4) input[x++]=0;
	    break;
	 }
      }

      cipher_idea(input,output,Z);

      for (y=0;y<x;y++)
      {
	 if (noisy) if (count++%256==0) printf(".");
	 write_word16_to_file(output[y],out);
      }
   }
}

void decipher_file(FILE *in,FILE *out,word16 *key)
{
   word16 input[4],output[4];
   int x,y;
   IDEAkey Z,DK;
   int count=0;
   long length=0;

   en_key_idea(key,Z);
   de_key_idea(Z,DK);

   end_of_file=0;

   fread(&length,sizeof(long),1,in);


   while (!end_of_file)
   {
      x=0;
      while (x<4)
      {
	 input[x]=read_word16_from_file(in);
	 if (end_of_file)
	    break;
	 x++;
      }
      cipher_idea(input,output,DK);
      for (y=0;y<x;y++)
      {
	 if (noisy) if (count++%256==0) printf(".");
	 if (length-->0)
	    write_char_to_file(((char)(output[y]>>8)),out);
	 if (length-->0)
	    write_char_to_file(((char)(output[y]&255)),out);
      }
   }
}

void swap_files_and_clean_up(char *file)
{
   long fsize,count;
   FILE *fp;
   char temp[100];

   if (overwrite)
   {
      if ((fp=fopen(file,"r+b"))==NULL)
      {
	 printf("\nError overwriting old file, security compromised.\n");
      }
      else
      {
	 fseek(fp,0l,SEEK_END);
	 fsize=ftell(fp);
	 fseek(fp,0l,SEEK_SET);
	 for (count=0;count<fsize;count++)
	    fputc('0',fp);
	 fclose(fp);
      }

      if ((remove(file))!=0)
      {
	 printf("\nERROR removing old file <%s>\n",file);
	 printf("encoded data remains in temporary file <%s>\n",tempfilename);
	 exit(-1);
      }
   }
   else
   {
      strcpy(temp,file);
      file=strtok(temp,".");
      strcat(file,".enc");
   }

   if ((rename(tempfilename,file))!=0)
   {
      printf("\nERROR renaming temporary file <%s>!!\n",tempfilename);
      printf("Data is safely processed and stored in that file.\n");
      exit(-1);
   }
}





/*-----------------------------------------------*/


#define KBYTES 1024

void getuserkeyfromargv(word16 *key,char *arg)
{
   int x;

   for (x=0;x<strlen(arg) && x<8;x++)
   {
       if (x==0) key[x]=arg[x]<<8;
       else key[x]=((arg[x]<<8)|(key[x-1]>>8));
   }

   if (strlen(arg)>8) printf ("\nONLY first *8* characters of key used!!!\n");

   if (x<8) while (x<8) key[x++]=0;
}

main(int argc, char **argv)
{
   word16 userkey[8];
   char filename[100];
   FILE *fp,*temp;
   int to_or_from;


   noisy=1;
   overwrite=0;

   if (argc!=4)
   {
      printf("\nUsage: idea filename.ext [e|d[w]] key\n");
      printf("          e=encode   d=decode   w=overwrite file\n");
      printf("       NOTE: Key must be no longer than 8 characters long!!!\n");
      exit(-1);
   }
   else
   {
      strncpy(filename,argv[1],99);
      filename[99]='\0';
      if (argv[2][0]=='e') to_or_from=1;
      else if (argv[2][0]=='d') to_or_from=0;
      else
      {
	 printf("\nUsage: idea filename.ext [e|d[w]] key\n");
	 printf("		e=encrypt d=decrypt w=overwrite file\n");
	 printf("       NOTE: Key must be no longer than 8 characters long!!!\n");
	 exit(-1);
      }
      if (argv[2][1]=='w') overwrite=1;
      getuserkeyfromargv(userkey,argv[3]);
   }


   if ((fp=fopen(filename,"r+b"))==NULL)
   {
      printf("\nError opening File %s\n",filename);
      exit (-1);
   }

   if ((temp=fopen(tempfilename,"w+b"))==NULL)
   {
      printf("\nError opening temporary file\n");
      exit(-1);
   }

   if (to_or_from==1)
   {
      printf("\nEncoding file %s   ",filename);
      cipher_file(fp,temp,userkey);
   }
   else
   {
      printf("\nDecoding file %s   ",filename);
      decipher_file(fp,temp,userkey);
   }

   fclose (fp);
   fclose(temp);

   swap_files_and_clean_up(filename);
   getch();
   return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -