本来就想做个课程内容的Feistel加解密,可是c语言基础太差,整天遇到数组越界连续两个****scanf输入字符串key和paintext时,就发生过,如果没memset这两个属性,后面在makeGroup和generateKey会发生数组越界。我觉得应该是我没有给这两个属性初始化,所以这两个属性的地址可能就是相连的?等同于一个字符串,中间只是相隔一个’\0’,所以虽然printf时没输出,但是如果把’\0’重置后,使用strlen(paintext)访问时,就会发生数组越界,因为根据strlen,paintext[strlen]用访问到了属于key中的元素。
还有另外一个越界就是,后面makeGroup中的这段,如果没给’\0’分配空间,则直接给字符串content[8]加上‘’\0’,就会导致numP会被重置为0,而如果不加’\0’,content输出时会把numP一连输出,而content长度strlen居然是9,又是连续分配空间?应该也是没初始化的问题?
int numP;
//char content[8] 不分配’/0’空间,printf --》 content时, 会把content连着numP作为一个字符串输出,strlen长度是9!!
char content[9]; //回车符号也分配空间,sizeof,避免越界
numP = strlen§ / sizeof(char) / 8; //输出正常
for(i=0;i<numP;i++)
{
strncpy(content,p+8*i,8);
content[8]='\0'; //终结符
}
这两段解决完了,又遇到新问题了,就是下面main函数我printf密钥组这段
类似的,第一次密钥组generateKey生成的keysPoint 输出正常,而明文分组makeGroup生成的p也正常,然而第二次输出keysPoint时,也就是makeGroup运行后,printf–》keyPoint发生了改变,keyPoint变成了乱码。而当我尝试初始化makeGroup中的pContent时,第二次输出的keysPoint也发生了改变,居然都是0*!!为什么,在makeGroup初始化pContent数组,会导致keysPoint发生变化。而且,我也试了一下,大概makeGroup的pContent重置中,i等于17时,keysPoint的数值就发生变化,由空变成0,这。。。。。初始化的时候出问题,而generateKey中的初始化我也重新设置了,没效果。。。这是什么操作。。。。。。晕。。。。。。。这越界是因为指针的问题?有大牛大大帮忙解答一下么,说一下数组越界的原理运行,本人基础太弱,也不知道怎么搜得到这类知识,希望各位尽情发言,多多关照,谢谢。
以下是关联到这些问题的部分代码,应该可以运行
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
int main()
{
int i=0,j=0;
char key[50]; //key最大位数50位,但是还是只取16位
char plaintext[100]; //明文
char keyGroup[16][17]; //密码组
char * generateKey(char * key); //生成密钥组
char * makeGroup(char plaintext[100]); //明文分组
memset(plaintext,0,sizeof(plaintext)/sizeof(char));
//重置,会让数组分配最大的空间,如不重值,当把plaintext的'\0'置换时,printf-》plaintext时会把key的值一同printf出来。
memset(key,0,sizeof(key)/sizeof(char));
printf("请输入明文\n");
scanf("%s",plaintext);
printf("请输入密码\n");
scanf(" %s",key);
char * keysPoint = generateKey(key); //生成密钥组
printf("密钥 1 %s\n",keysPoint); //第一次输出keysPoint
char * p;
p = makeGroup(plaintext); //明文分组
printf("密钥 2 %s\n",keysPoint); //第二次输出keysPoint
return 0;
}
char * makeGroup(char plaintext[100])
{
int i=0,j=0;
int g_num=0; //分组数
int b_num=0;
int n_num=0;
int pLength=0;
char pContent[50][9]; //最大50组,"\0"的空间必须分配
for(i=0;i<50;i++) //初始化pContent
{
for(j=0;j<9;j++)
{
pContent[i][j]=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;i<n_num;i++)
{
plaintext[strlen(plaintext)] = n_num + '0';
}
}
plaintext[strlen(plaintext)]='\0';
for(i=0;i<g_num;i++)
{
for(j=0;j<8;j++)
{
pContent[i][j] = plaintext[i*8+j];
}
pContent[i][8]='\0';
}
char (*p)[9];
p = pContent;
return *p;
}
//生产密钥组
char * generateKey(char * key)
{
int i=0,j=0;
char keyadd[50]; //单个密码
memset(keyadd,0,50);
char keyGroup[16][17]; //密码组,16位密码,1位'\0'
for(i=0;i<16;i++)
{
for(j=0;j<17;j++)
{
keyGroup[i][j]=0;
}
}
char last;
while(strlen(key)<16) //16*8=128bit
{
strcpy(keyadd,key);
strcat (key,keyadd);
}
memset(keyadd,0,sizeof(keyadd));
strncpy(keyadd,key,16);
for(i=0;i<16;i++) //获取不同的key,循环移位一bit
{
last = keyadd[15]; //最后一个
for(j=15;j>0;j--) //不用strlen获取长度了,因为是固定的
{
keyadd[j]=keyadd[j-1];
}
keyadd[0] = last;
memcpy(keyGroup[i],keyadd,16*sizeof(char)); //一维数组叠加成为二维数组
keyGroup[i][16]='\0'; //密文矩阵
}
char (*k)[17];
k = keyGroup;
return *k;
}