c简单实现Feistel加解密

关于上次数组越界的问题已经解决,内部定义的数组,函数结束时内存可能被回收。同一个函数定义的变量和数组之类,地址在方法栈中应该是连续的,如果字符串数组不定义结束符,%s输出会越界读取。
采取的方法是
1.尽量使用外部的数组或者指针,或者在函数内部手动分配空间(手动分配空间,系统并不会自动回收空间)!
因为外部指针(数组)在函数内进过修改,不用return,函数结束时影响也在,是直接修改对应地址的值。
2.数组尽量多分配几个空间,以便定义结束符号
3.可以采用数据断点来判断是否越界
以下是正确的feistel算法简单实现,还需留意的是明文加密最后,密文的组成是RiLi,而非LiRi,所以与前面加密分开理解。而解密时最后一步也是如此。


#include
#include
#include
#include


int main()
{
  int i=0,j=0;

  char key[50];        //key最大位数50位,但是还是只取16位

  char plaintext[100];   //明文

  char pGroup[10][10]; //明文组
 
  char keyGroup[16][17]; //密码组

  void encryption(char pGroup[10][10],char keyGroup[16][17]); 

  void decryption(char pGroup[10][10],char keyGroup[16][17]);
 
  void generateKey(char  key[50],char keyGroup[16][17]);

  void makeGroup(char plaintext[100],char pGroup[10][10]);
 
  memset(plaintext,0,sizeof(plaintext)/sizeof(char));

  memset(key,0,sizeof(key)/sizeof(char));

  memset(pGroup,0,sizeof(pGroup) / sizeof(char) );

  memset(keyGroup,0,sizeof(keyGroup) / sizeof(char) );

  printf("请输入明文\n");

  scanf("%s",plaintext);

  printf("请输入密码\n");

  scanf(" %s",key);

  generateKey(key,keyGroup);

  makeGroup(plaintext, pGroup);

   encryption(pGroup,keyGroup);

   printf("密文--》\n");

   for(i=0;i<10;i++)
   {
	   printf("%s",pGroup[i]);
   }

   printf("\n");

   decryption(pGroup,keyGroup);

	printf("明文--》\n");

   for(i=0;i<10;i++)
   {
	   printf("%s",pGroup[i]);
   }

   printf("\n");

  return 0;
}

void makeGroup(char plaintext[100],char pGroup[10][10])
{

    int i=0,j=0;

	int g_num=0;   //分组数
    
	int b_num=0;

	int n_num=0;

	int pLength=0;

	pLength = strlen(plaintext); 
    
	b_num = pLength % 8;

	n_num = 8 - b_num;

	g_num = pLength / 8 ;

	if(b_num != 0)
	{
		g_num += 1;

		for(i=0;i0;j--)     //不用strlen获取长度了,因为是固定的
	 {
		   key[j]=key[j-1];
	 }
    
	 key[0] = last;     

	 memcpy(keyGroup[i],key,16*sizeof(char)); //一维数组叠加成为二维数组 
      
     keyGroup[i][16]='\0';     //密文矩阵
	  
   }
 
}

void f(char p[10],char key[17],int flag,int time)    //密钥固定16位
{

    int i=0,j=0;

	char LE[4];  //不用给多余空间,密码的大小是固定的

	char RE[4];

	char LE1[4];

	char RE1[4];
	
	strncpy(LE,p,4);

	strncpy(RE,p+4,4);

	strncpy(LE1,RE,4); 
    
	for(i=0;i<4;i++)
	{
		RE1[i] = RE[i]^key[4*i]^LE[i];  //按位异或
	}
   
	if(flag==0 && time == 15 || flag == 1 && time == 0)     //特殊处理(倒序)加密第16次和解密第16次
	{
		for(i=0;i<8;i++)
		{
		   if(i<4)
		   {
			 p[i]=RE1[i];
		   }
		   else
		   {
			 p[i]=LE1[i-4];
		   }
			
		}

	}
    else //正常处理
	{
		for(i=0;i<8;i++)
		{
		   if(i<4)
		   {
			 p[i]=LE1[i];
		   }
		   else
		   {

			 p[i]=RE1[i-4];

		   }
			
		}
	}
}


void loop(char pGroup[10],int flag,char keyGroup[16][17])         //flag=0为加密,flag=1为解密
{
	printf("loop开始\n");

	int i = 0;
	
   if(flag==0)
   {
 		 for(i=0;i<16;i++)
		 {
			f(pGroup,keyGroup[i],flag,i);  //循环16次,加密,密钥正向、
		 }

		 pGroup[8]='\0';
   }

  else	
  {

		for(i=15;i>-1;i--)
		{
			f(pGroup,keyGroup[i],flag,i);  //循环16次,解密,密钥倒过来
		}

		pGroup[8]='\0';

  }

}


void encryption(char pGroup[10][10],char keyGroup[16][17])    //加密
{   

     int i=0;

     int numP;

	numP = sizeof(pGroup) / sizeof(char);  //求组数,行数

	for(i=0;i

你可能感兴趣的:(c简单实现Feistel加解密)