关于vigenger加密问题 (C语言)
本帖最后由 北有樵先生 于 2020-4-8 15:10 编辑问题是输出期望的结果后,有有一些不符合期望的字符跟在其后面。具体描述在代码最后。代码如下:
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <string.h>
# define OK 1
# define ERROR0
# define SIZE 16
typedef char Elemtype ;
typedef struct node
{
Elemtype elem ;
struct node *next ;
struct node *previous ;
}node , *Linklist ;
static char* input_plaintext (void) ;
static void create_BidCirlinklist ( Linklist *L) ;
static int * create_CipherKey ( int len ) ;
static node* find_ch (Linklist L , Elemtype ch);
static void create_one_cipher (node*S , int n , Elemtype *ch) ;
static Elemtype* create_Cipher (Linklist L, int len , int *key , char * passward);
int main (void)
{
FILE *fp ;
int len , *key , i;
Elemtype *password , *new_password ;
Linklist l = NULL;
if ( (fp = fopen("Encrypted.txt", "wb")) == NULL)
{
printf("打开文件失败\n") ;
exit(EXIT_FAILURE) ;
}
password = input_plaintext() ;
len = strlen(password) ;
key = create_CipherKey(len) ;
fwrite(password,sizeof(char),len,fp) ;
fwrite(key,sizeof(int),len,fp) ;
fclose(fp) ; // 至此写入明文和密匙,以二进制的形式
create_BidCirlinklist(&l) ;
new_password = create_Cipher(l,len,key,password) ;
printf ("%s\n",password) ; // 从这里开始便是验证输入和输出结果
i = 0 ;
while ( i < len )
{
printf("%2d ",key) ;
i++;
}
printf("\n") ;
for( i = 0; i < len ; i++)
{
printf("%c ",new_password) ;// 单个字母输出并无问题
}
printf("\n") ;
printf("%s\n",new_password) ;// 问题出现在这个输出上
free(new_password);
free(key);
return 0;
}
// 输入明文
static char* input_plaintext (void)
{
int Len ;
char *Str ,*str;
str = (char*)malloc( SIZE * sizeof(char)) ;
printf ("请输入明文(至多输入16位):") ;
scanf ("%s",str) ;
Len = strlen(str) ;
Str = (char*)malloc( Len * sizeof(char)) ;
strcpy(Str,str) ;
return Str ;
}
// 建立解密环
static void create_BidCirlinklist ( Linklist *L) // L是指针的指针
{
node *flag , *new_node ;
int i = 0 ;
while ( i< 26 )
{
new_node = (node *)malloc(sizeof(node )) ;
new_node->elem = 'A'+i ;
if ((*L) == NULL )
{
flag = (*L) = new_node ;
flag->next = flag->previous = NULL ;
}
else
{
new_node->next = flag->next ;
flag->next = new_node ;
new_node->previous = flag ;
flag = new_node ;
}
i++ ;
}
flag->next = (*L) ;
(*L)->previous = flag ;
}
// 生成随机密匙
static int * create_CipherKey ( int len )
{
int i ;
int *Key = (int *)malloc(sizeof(int) * len) ;
time_t t;
srand(time(&t)) ;
for( i = 0 ; i < len ; i++)
{
Key = rand()%100 ;
}
return Key ;
}
// 生成密文
static Elemtype* create_Cipher (Linklist L, int len , int *key , char * passward)
{
int i ;
Elemtype *new_cipher = (Elemtype*)malloc( sizeof(Elemtype)*len ) ;
node *flag ;
for ( i = 0 ; i < len ; i++)
{
flag = find_ch(L , passward) ;
create_one_cipher(flag,key,&new_cipher) ;
}
return new_cipher ;
}
// 找到对应的字母,便于生成新字母
static node* find_ch (Linklist l , Elemtype ch)
{
node *flag1 = l ;
if ( ch > 'Z')
{
ch -= 32 ;
}
if ( ch <= 'M')
{
while (flag1->elem != ch)
flag1 = flag1->next ;
}
else
{
while (flag1->elem != ch)
flag1 = flag1->previous ;
}
return flag1 ;
}
// 生成新一位密文并用ch返回
static void create_one_cipher (node*S , int n , Elemtype *ch)// 当n的绝对值大于13时 向反方向移动 提高效率
{
node *flag2 = S ;
if ( n > 0)
{
n %= 26 ;
if ( n >13)
{
while (n--)
flag2 = flag2->previous;
}
else
{
while (n--)
flag2 = flag2->next ;
}
}
else
{
n %= -26 ;
if ( n >13)
{
while (n++)
flag2 = flag2->previous;
}
else
{
while (n++)
flag2 = flag2->next ;
}
}
*ch = flag2->elem ;
}
我已经调试了,结果都正确,问题在于结果后会跟不相符的字符;
这个临界点出现在输入7个字母和8个字母,8个字符往后都会出现这些,而且越多,我已经调试完了,可以正常运行,单个字母进行输出,也可以得到结果
因为是新人所以不能上传图片,但程序可运行,可以尝试输入,谢谢
给出输入样例和输出结果,如果有必要,再指出哪里和你期望的结果不符
这样会对我调试程序很有帮助
还有代码写的也挺长了,该学一学调试程序的方法了
本帖最后由 北有樵先生 于 2020-3-31 15:56 编辑
人造人 发表于 2020-3-31 12:09
给出输入样例和输出结果,如果有必要,再指出哪里和你期望的结果不符
这样会对我调试程序很有帮助
还有代 ...
你的前半句很有道理,是我对问题的描述不够,我已经改了,谢谢。不过我想说,一上来就质疑人啥都没干,这种行为很愚蠢 北有樵先生 发表于 2020-3-31 14:16
你的前半句很有道理,是我对问题的描述不够,我已经改了,谢谢。不过我想说,一上来就质疑人啥都没干, ...
你修改后的结果也一样,对调试程序没有任何帮助
我期望的是像下面这样的
输入:abcd1234
输出:234abcd1+
我期望的输出是:1234abcd 发现了好多问题
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <string.h>
# define OK 1
# define ERROR0
# define SIZE 16
typedef char Elemtype ;
typedef struct node
{
Elemtype elem ;
struct node *next ;
struct node *previous ;
}node , *Linklist ;
static char* input_plaintext (void) ;
static void create_BidCirlinklist ( Linklist *L) ;
static int * create_CipherKey ( int len ) ;
static node* find_ch (Linklist L , Elemtype ch);
static void create_one_cipher (node*S , int n , Elemtype *ch) ;
static Elemtype* create_Cipher (Linklist L, int len , int *key , char * passward);
int main (void)
{
FILE *fp ;
int len , *key , i;
Elemtype *password , *new_password ;
Linklist l = NULL;
srand(time(NULL)) ; // 放在这里更好
if ( (fp = fopen("Encrypted.txt", "wb")) == NULL)
{
printf("打开文件失败\n") ;
exit(EXIT_FAILURE) ;
}
password = input_plaintext() ;
len = strlen(password) ;
key = create_CipherKey(len) ;
fwrite(password, 1, len, fp) ;
fwrite(key,sizeof(int),len,fp) ;
fclose(fp) ; // 至此写入明文和密匙,以二进制的形式
create_BidCirlinklist(&l) ;
new_password = create_Cipher(l,len,key,password) ;
printf ("%s\n",password) ; // 从这里开始便是验证输入和输出结果
i = 0 ;
while ( i < len )
{
printf("%2d ",key) ;
i++;
}
printf("\n") ;
for( i = 0; i < len ; i++)
{
printf("%c ",new_password) ;// 单个字母输出并无问题
}
printf("\n") ;
printf("%s\n",new_password) ;// 问题出现在这个输出上 // 你期望这个printf输出什么内容?
free(password); // 少了这个吧?
free(new_password);
free(key);
return 0;
}
// 输入明文
static char* input_plaintext (void)
{
#if 0
int Len ;
char *Str ,*str;
str = (char*)malloc(SIZE) ; // 永远都不需要乘一个sizeof(char)
printf ("请输入明文(至多输入16位):") ;
scanf ("%s",str) ;
Len = strlen(str) ;
Str = (char*)malloc(Len + 1) ;// 这里不需要加1吗?
strcpy(Str,str) ;
free(str); // 这里不需要free吗?
return Str ;
#endif
char *str = malloc(5);
strcpy(str, "abcd");
return str;
}
// 建立解密环
static void create_BidCirlinklist ( Linklist *L) // L是指针的指针
{
node *flag , *new_node ;
int i = 0 ;
while ( i< 26 )
{
new_node = (node *)malloc(sizeof(node )) ;
new_node->elem = 'A'+i ;
if ((*L) == NULL )
{
flag = (*L) = new_node ;
flag->next = flag->previous = NULL ;
}
else
{
new_node->next = flag->next ;
flag->next = new_node ;
new_node->previous = flag ;
flag = new_node ;
}
i++ ;
}
flag->next = (*L) ;
(*L)->previous = flag ;
}
// 生成随机密匙
static int * create_CipherKey ( int len )
{
int i ;
int *Key = (int *)malloc(sizeof(int) * len) ;
for( i = 0 ; i < len ; i++)
{
Key = rand()%100 ;
}
return Key ;
}
// 生成密文
static Elemtype* create_Cipher (Linklist L, int len , int *key , char * passward)
{
int i ;
Elemtype *new_cipher = (Elemtype*)malloc( sizeof(Elemtype)*len ) ;
node *flag ;
for ( i = 0 ; i < len ; i++)
{
flag = find_ch(L , passward) ;
create_one_cipher(flag,key,&new_cipher) ;
}
return new_cipher ;
}
// 找到对应的字母,便于生成新字母
static node* find_ch (Linklist l , Elemtype ch)
{
node *flag1 = l ;
if ( ch > 'Z')
{
ch -= 32 ;
}
if ( ch <= 'M')
{
while (flag1->elem != ch)
flag1 = flag1->next ;
}
else
{
while (flag1->elem != ch)
flag1 = flag1->previous ;
}
return flag1 ;
}
// 生成新一位密文并用ch返回
static void create_one_cipher (node*S , int n , Elemtype *ch)// 当n的绝对值大于13时 向反方向移动 提高效率
{
node *flag2 = S ;
n = n > 0 ? n : -n;
n %= 26 ;
while (n--)
flag2 = flag2->next ;
*ch = flag2->elem ;
#if 0
node *flag2 = S ;
n = n > 0 ? n : -n;
n %= 26 ;
if ( n >13) // 这个if-else可以提高效率?
{
while (n--)
flag2 = flag2->previous;
}
else
{
while (n--)
flag2 = flag2->next ;
}
*ch = flag2->elem ;
#endif
#if 0
node *flag2 = S ;
if ( n > 0)
{
n %= 26 ;
if ( n >13)
{
while (n--)
flag2 = flag2->previous;
}
else
{
while (n--)
flag2 = flag2->next ;
}
}
else
{
n %= -26 ;
if ( n >13)
{
//while (n++) // 确定这里是++ ?
while(n--)
flag2 = flag2->previous;
}
else
{
//while (n++) // 还有这里
while(n--)
flag2 = flag2->next ;
}
}
*ch = flag2->elem ;
#endif
}
本帖最后由 北有樵先生 于 2020-4-1 17:00 编辑
人造人 发表于 2020-3-31 18:40
发现了好多问题
首先十分感谢你能看我的代码并指出问题,也让我注意到了很多问题,但输出还是有问题
比如:
输入: wangbuliuxing
密匙: 0000000000001(假设是这个,方便讨论)
期望输出:wangbuliuxinh
实际输出:wangbuliuxinh794问日20394
后面粗体意思是所出现的乱码,通过malloc函数分配的空间所存储的字符,再用printf(“%s”)输出时会出现乱码,也就是我第二个输出那里,你问我想做什么,那里是我想与上面通过输出单个字符的结果作比较。根据我自己试下来,当输入字符串长度大于等于8时,通过%s输出会出现乱码,这个也是我一开始的问题 北有樵先生 发表于 2020-4-1 16:59
首先十分感谢你能看我的代码并指出问题,也让我注意到了很多问题,但输出还是有问题
比如:
输入: ...
一组输入输出不具有代表性,我看不出规律
输入g,在密匙为1时输出h,密匙是2时输出什么?是3呢?-1呢?-2?等等
你说长度大于8会出问题,那小于等于8没问题?再举3个例子
小于8不会出问题的
等于8不会出问题的
还有大于8会出问题的
“假设是这个,方便讨论”
最好还是不要这样,这样不方便观察输入与输出的关系
为了更好的观察输入输出,你就随便编一个密匙吧,类似于随机
考虑上正数、负数和 0
就用这个密匙,在你看来输出什么才对?
./main
wangbuliuxing
39 93 42 16 54 77 50 38 610 42 15 13
J P D W D T J U D X Y C T
JPDWDTJUDXYCT
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define OK 1
#define ERROR0
#define SIZE 16
typedef char Elemtype ;
typedef struct node
{
Elemtype elem ;
struct node *next ;
struct node *previous ;
}node , *Linklist ;
static char* input_plaintext (void) ;
static void create_BidCirlinklist ( Linklist *L) ;
static int * create_CipherKey ( int len ) ;
static node* find_ch (Linklist L , Elemtype ch);
static void create_one_cipher (node*S , int n , Elemtype *ch) ;
static Elemtype* create_Cipher (Linklist L, int len , int *key , char * passward);
int main (void)
{
FILE *fp ;
int len , *key , i;
Elemtype *password , *new_password ;
Linklist l = NULL;
srand(time(NULL)) ; // 放在这里更好
if ( (fp = fopen("Encrypted.txt", "wb")) == NULL)
{
printf("打开文件失败\n") ;
exit(EXIT_FAILURE) ;
}
password = input_plaintext() ;
len = strlen(password) ;
key = create_CipherKey(len) ;
fwrite(password, 1, len, fp) ;
fwrite(key,sizeof(int),len,fp) ;
fclose(fp) ; // 至此写入明文和密匙,以二进制的形式
create_BidCirlinklist(&l) ;
new_password = create_Cipher(l,len,key,password) ;
printf ("%s\n",password) ; // 从这里开始便是验证输入和输出结果
i = 0 ;
while ( i < len )
{
printf("%2d ",key) ;
i++;
}
printf("\n") ;
for( i = 0; i < len ; i++)
{
printf("%c ",new_password) ;// 单个字母输出并无问题
}
printf("\n") ;
printf("%s\n",new_password) ;// 问题出现在这个输出上 // 你期望这个printf输出什么内容?
free(password); // 少了这个吧?
free(new_password);
free(key);
return 0;
}
// 输入明文
static char* input_plaintext (void)
{
#if 0
int Len ;
char *Str ,*str;
str = (char*)malloc(SIZE) ; // 永远都不需要乘一个sizeof(char)
printf ("请输入明文(至多输入16位):") ;
scanf ("%s",str) ;
Len = strlen(str) ;
Str = (char*)malloc(Len + 1) ;// 这里不需要加1吗?
strcpy(Str,str) ;
free(str); // 这里不需要free吗?
return Str ;
#endif
char *str = malloc(14);
strcpy(str, "wangbuliuxing");
return str;
}
// 建立解密环
static void create_BidCirlinklist ( Linklist *L) // L是指针的指针
{
node *flag , *new_node ;
int i = 0 ;
while ( i< 26 )
{
new_node = (node *)malloc(sizeof(node )) ;
new_node->elem = 'A'+i ;
if ((*L) == NULL )
{
flag = (*L) = new_node ;
flag->next = flag->previous = NULL ;
}
else
{
new_node->next = flag->next ;
flag->next = new_node ;
new_node->previous = flag ;
flag = new_node ;
}
i++ ;
}
flag->next = (*L) ;
(*L)->previous = flag ;
}
// 生成随机密匙
static int * create_CipherKey ( int len )
{
int i ;
int *Key = (int *)malloc(sizeof(int) * len) ;
for( i = 0 ; i < len ; i++)
{
Key = rand()%100 ;
}
return Key ;
}
// 生成密文
static Elemtype* create_Cipher (Linklist L, int len , int *key , char * passward)
{
int i ;
Elemtype *new_cipher = (Elemtype*)malloc( sizeof(Elemtype)*len ) ;
node *flag ;
for ( i = 0 ; i < len ; i++)
{
flag = find_ch(L , passward) ;
create_one_cipher(flag,key,&new_cipher) ;
}
return new_cipher ;
}
// 找到对应的字母,便于生成新字母
static node* find_ch (Linklist l , Elemtype ch)
{
node *flag1 = l ;
if ( ch > 'Z')
{
ch -= 32 ;
}
if ( ch <= 'M')
{
while (flag1->elem != ch)
flag1 = flag1->next ;
}
else
{
while (flag1->elem != ch)
flag1 = flag1->previous ;
}
return flag1 ;
}
// 生成新一位密文并用ch返回
static void create_one_cipher (node*S , int n , Elemtype *ch)// 当n的绝对值大于13时 向反方向移动 提高效率
{
node *flag2 = S ;
n = n > 0 ? n : -n;
n %= 26 ;
while (n--)
flag2 = flag2->next ;
*ch = flag2->elem ;
#if 0
node *flag2 = S ;
n = n > 0 ? n : -n;
n %= 26 ;
if ( n >13) // 这个if-else可以提高效率?
{
while (n--)
flag2 = flag2->previous;
}
else
{
while (n--)
flag2 = flag2->next ;
}
*ch = flag2->elem ;
#endif
#if 0
node *flag2 = S ;
if ( n > 0)
{
n %= 26 ;
if ( n >13)
{
while (n--)
flag2 = flag2->previous;
}
else
{
while (n--)
flag2 = flag2->next ;
}
}
else
{
n %= -26 ;
if ( n >13)
{
//while (n++) // 确定这里是++ ?
while(n--)
flag2 = flag2->previous;
}
else
{
//while (n++) // 还有这里
while(n--)
flag2 = flag2->next ;
}
}
*ch = flag2->elem ;
#endif
}
本帖最后由 北有樵先生 于 2020-4-1 18:57 编辑
人造人 发表于 2020-4-1 18:00
就用这个密匙,在你看来输出什么才对?
我用的dev c++ 5.11,我复制你的代码然后运行,在正确结果后会出现乱码,会是编译器的问题嘛
因为我权限不够,没法给你发图片,要不先放着,然后我权限够了再说?{:10_266:}
https://user.qzone.qq.com/1924366928/infocenter
北有樵先生 发表于 2020-4-1 18:50
我用的dev c++ 5.11,我复制你的代码然后运行,在正确结果后会出现乱码,会是编译器的问题嘛
因为我权 ...
图片显示不出来
人造人 发表于 2020-4-1 19:29
图片显示不出来
那我先等到我有权限了吧{:10_284:} 北有樵先生 发表于 2020-4-2 10:36
那我先等到我有权限了吧
https://fishc.com.cn/forum.php?mod=viewthread&tid=155962&highlight=%B7%A2%CD%BC%C6%AC
人造人 发表于 2020-4-2 13:12
https://fishc.com.cn/forum.php?mod=viewthread&tid=155962&highlight=%B7%A2%CD%BC%C6%AC
https://imgchr.com/i/GJvEaq
https://imgchr.com/i/GJvVI0
审核把回复删了,现在重发,第二个图就出现了乱码
页:
[1]