求教一个C问题,RC4加密解密中遇到的问题。

时间:2021-12-09 11:43:52
我现在写了一个RC4加密算法。

想法是从一个文本文件中读取内容,用算法加密后,在重新保存到一个新的文本文件中。

但是现在我遇到一个问题:就是当我每次取出的一个字节随机与一个伪随机码(同为一个字节)异或时,得到的结果可能为0或者为32,存放到文本文件中时,都以空格形式保存,所以当解密时,读取出来的字符的ASC值就全为32了,就导致了我的解密失败。

想问问高人,我该如何避免这个问题。

16 个解决方案

#1


引用 楼主 crazyben 的回复:
我现在写了一个RC4加密算法。

想法是从一个文本文件中读取内容,用算法加密后,在重新保存到一个新的文本文件中。

但是现在我遇到一个问题:就是当我每次取出的一个字节随机与一个伪随机码(同为一个字节)异或时,得到的结果可能为0或者为32,存放到文本文件中时,都以空格形式保存,所以当解密时,读取出来的字符的ASC值就全为32了,就导致了我的解密失败。

想问问高……


这种作业型的,解决办法很多的。
比如异或为0时直接写入原始字符,或者变成和前一个字节异或,或者和前面第二个字节异或,或者......
或者和一个固定的字节异或,方法只要你想得到,多得是.....
异或32的话问题应该不大。

#2


这种问题在加解密的过程中是很容易出现的,通常加解密失败,首先就会想到这个问题
解决的办法很多,楼上已给提示
其实,楼主也可以把算法的逻辑再重新设计下
比如:后x个字节与前x个字节做异或等各种操作,最后不足的补齐
方法老多,多试试就行了。
呵呵,祝你好运!

#3


还有一点,加解密时在对字符串操作的时候,尤其是中间有结束符标识的字符串,
尽量不要用对结束符敏感的函数。
如:strlen(), strcpy()等,直接对字符串的内存进行操作就会少很多麻烦。

#4


也想过通过附加操作,在进行运算一次,但是那样那次运算如果还出现0或32的问题啊

#5


这是我加密部分的代码,能帮我看看怎么修改吗?

void WD(FILE *readfile,FILE *writefile,char *key)

 unsigned char S[255]={0};
 char a;
 unsigned char x;
 int i,j,t; 

re_WD(S,key);//读取密钥,生成密钥串
 i=j=0;
 while((a=fgetc(readfile))!=EOF)//核心加密程序
 {
    i = (i + 1)%256;
    j = (j + S[i])%256;
    
    swap(&S[i],&S[j]);//***伪随机序列生成
    x=putchar(a);
    t = (S[i] + (S[j] % 256))%256;
    x=x^S[t];
    fprintf(writefile,"%c",x);
    printf("\n");
    }
 printf("加密|解密成功!!!\n");
 
}

#6


引用 5 楼 crazyben 的回复:
这是我加密部分的代码,能帮我看看怎么修改吗?

void WD(FILE *readfile,FILE *writefile,char *key)

 unsigned char S[255]={0};
 char a;
 unsigned char x;
 int i,j,t; 

re_WD(S,key);//读取密钥,生成密钥串
 i=j=0……

代码不全哦  贴出完整的代码

#7


我也在做rc4加密,楼主加下QQ,1459653736,讨论讨论  求教一个C问题,RC4加密解密中遇到的问题。

#8


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <windows.h>

void swap(unsigned char *s1,unsigned char *s2)//位置交换
{
 char temp;
 temp=*s1;
 *s1=*s2;
 *s2=temp;
}

void re_S(unsigned char *S)//初始化数据源
{
 unsigned int i;
 for(i=0;i<256;i++)
    S[i]=i;
}

void re_T(unsigned char *T,char *key)//密钥重复复制给数据源
{
 int i;
 int keylen;
 keylen=strlen(key);
 for(i=0;i<256;i++)
  T[i]=key[i%keylen];
 }

void re_Sbox(unsigned char *S,unsigned char *T)//密钥调度算法。根据输入密钥增加随机性。非线性变换
{
 int i;
 int j=0;
 for(i=0;i<256;i++)
 {
    j=(j+S[i]+T[i])%256;
    swap(&S[i],&S[j]);
 }
}

void re_WD(unsigned char *S,char *key)
{
 unsigned char T[255]={0};
 re_S(S);//初始化数据源
 re_T(T,key);
 re_Sbox(S,T);
}

void WD(FILE *readfile,FILE *writefile,char *key)

 unsigned char S[255]={0};
 char a;
 unsigned char x;

 int i,j,t,tmp; 
 

re_WD(S,key);//读取密钥,生成密钥串
 i=j=0;
 while((a=fgetc(readfile))!=EOF)//核心加密程序
 {
    i = (i + 1)%256;
    j = (j + S[i])%256;
    
    swap(&S[i],&S[j]);//***伪随机序列生成
    x=putchar(a);

    t = (S[i] + (S[j] % 256))%256;
    
x=x^S[t];
tmp=x;
    if(tmp==0){
x=putchar(a);
    }

    fprintf(writefile,"%c",x);

printf("\n");

 }
 printf("加密|解密成功!!!\n");
 
}

int main()
{
 
 char key;
 FILE *file1,*file2;

file1= fopen( "plaint.txt","rb");
 file2 = fopen("cipher.txt","wt+");
 if (!file1||!file2)
 {  
    printf("读取文件出错\n");
    return 0;
 }
 printf("####欢迎使用R4序列密码####\n请输入密码:\n");
 scanf("%s",&key);

 WD(file1,file2,&key);//主要加密函数

 fclose(file1);
 fclose(file2);
 system("pause");
 return 1;
}

#9


感觉那个空字符和空格问题改过来了,但是发现解密还是会出现乱码,哪位朋友能帮我看下吗?多谢!

#10


char key;
scanf("%s",&key);
是这个原因吗?

#11


key这个类型定义错了吗?

#12


引用 11 楼 crazyben 的回复:
key这个类型定义错了吗?


应该没问题.反正你只输入一个字节,当然建议是改成getchar..

DEBUG,先定位是加密还是解密有错误,具体方法参考zhao4zhong1的经典回复。

另外建议代码放入代码框。一般放入代码框的会比较容易供大家阅读。

#13


在楼主代码的基础上改了该,运行结果如下图, 敬请验证:
求教一个C问题,RC4加密解密中遇到的问题。

#14


引用 13 楼 tonforce 的回复:
在楼主代码的基础上改了该,运行结果如下图, 敬请验证:

解密能解回来吗?

#15


楼主你的加密算法是算法没有公开,是一种很原始的加密算法,你的解密的过程可以通过加密的逆过程很容易求得,只要别人知道了你的加密算法,你的密码很快就会破解,所以现在这种加密已经很少用。现在的加密都是把怎么加密的过程公开,密钥保留,分为对称加密*和公钥密码*,一般都是两种一起配合来使用,推荐楼主可以看看《现代密码学》

#16


引用 15 楼 wyhllk 的回复:
楼主你的加密算法是算法没有公开,是一种很原始的加密算法,你的解密的过程可以通过加密的逆过程很容易求得,只要别人知道了你的加密算法,你的密码很快就会破解,所以现在这种加密已经很少用。现在的加密都是把怎么加密的过程公开,密钥保留,分为对称加密*和公钥密码*,一般都是两种一起配合来使用,推荐楼主可以看看《现代密码学》

我就是修的这门课做的课程设计

#1


引用 楼主 crazyben 的回复:
我现在写了一个RC4加密算法。

想法是从一个文本文件中读取内容,用算法加密后,在重新保存到一个新的文本文件中。

但是现在我遇到一个问题:就是当我每次取出的一个字节随机与一个伪随机码(同为一个字节)异或时,得到的结果可能为0或者为32,存放到文本文件中时,都以空格形式保存,所以当解密时,读取出来的字符的ASC值就全为32了,就导致了我的解密失败。

想问问高……


这种作业型的,解决办法很多的。
比如异或为0时直接写入原始字符,或者变成和前一个字节异或,或者和前面第二个字节异或,或者......
或者和一个固定的字节异或,方法只要你想得到,多得是.....
异或32的话问题应该不大。

#2


这种问题在加解密的过程中是很容易出现的,通常加解密失败,首先就会想到这个问题
解决的办法很多,楼上已给提示
其实,楼主也可以把算法的逻辑再重新设计下
比如:后x个字节与前x个字节做异或等各种操作,最后不足的补齐
方法老多,多试试就行了。
呵呵,祝你好运!

#3


还有一点,加解密时在对字符串操作的时候,尤其是中间有结束符标识的字符串,
尽量不要用对结束符敏感的函数。
如:strlen(), strcpy()等,直接对字符串的内存进行操作就会少很多麻烦。

#4


也想过通过附加操作,在进行运算一次,但是那样那次运算如果还出现0或32的问题啊

#5


这是我加密部分的代码,能帮我看看怎么修改吗?

void WD(FILE *readfile,FILE *writefile,char *key)

 unsigned char S[255]={0};
 char a;
 unsigned char x;
 int i,j,t; 

re_WD(S,key);//读取密钥,生成密钥串
 i=j=0;
 while((a=fgetc(readfile))!=EOF)//核心加密程序
 {
    i = (i + 1)%256;
    j = (j + S[i])%256;
    
    swap(&S[i],&S[j]);//***伪随机序列生成
    x=putchar(a);
    t = (S[i] + (S[j] % 256))%256;
    x=x^S[t];
    fprintf(writefile,"%c",x);
    printf("\n");
    }
 printf("加密|解密成功!!!\n");
 
}

#6


引用 5 楼 crazyben 的回复:
这是我加密部分的代码,能帮我看看怎么修改吗?

void WD(FILE *readfile,FILE *writefile,char *key)

 unsigned char S[255]={0};
 char a;
 unsigned char x;
 int i,j,t; 

re_WD(S,key);//读取密钥,生成密钥串
 i=j=0……

代码不全哦  贴出完整的代码

#7


我也在做rc4加密,楼主加下QQ,1459653736,讨论讨论  求教一个C问题,RC4加密解密中遇到的问题。

#8


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <windows.h>

void swap(unsigned char *s1,unsigned char *s2)//位置交换
{
 char temp;
 temp=*s1;
 *s1=*s2;
 *s2=temp;
}

void re_S(unsigned char *S)//初始化数据源
{
 unsigned int i;
 for(i=0;i<256;i++)
    S[i]=i;
}

void re_T(unsigned char *T,char *key)//密钥重复复制给数据源
{
 int i;
 int keylen;
 keylen=strlen(key);
 for(i=0;i<256;i++)
  T[i]=key[i%keylen];
 }

void re_Sbox(unsigned char *S,unsigned char *T)//密钥调度算法。根据输入密钥增加随机性。非线性变换
{
 int i;
 int j=0;
 for(i=0;i<256;i++)
 {
    j=(j+S[i]+T[i])%256;
    swap(&S[i],&S[j]);
 }
}

void re_WD(unsigned char *S,char *key)
{
 unsigned char T[255]={0};
 re_S(S);//初始化数据源
 re_T(T,key);
 re_Sbox(S,T);
}

void WD(FILE *readfile,FILE *writefile,char *key)

 unsigned char S[255]={0};
 char a;
 unsigned char x;

 int i,j,t,tmp; 
 

re_WD(S,key);//读取密钥,生成密钥串
 i=j=0;
 while((a=fgetc(readfile))!=EOF)//核心加密程序
 {
    i = (i + 1)%256;
    j = (j + S[i])%256;
    
    swap(&S[i],&S[j]);//***伪随机序列生成
    x=putchar(a);

    t = (S[i] + (S[j] % 256))%256;
    
x=x^S[t];
tmp=x;
    if(tmp==0){
x=putchar(a);
    }

    fprintf(writefile,"%c",x);

printf("\n");

 }
 printf("加密|解密成功!!!\n");
 
}

int main()
{
 
 char key;
 FILE *file1,*file2;

file1= fopen( "plaint.txt","rb");
 file2 = fopen("cipher.txt","wt+");
 if (!file1||!file2)
 {  
    printf("读取文件出错\n");
    return 0;
 }
 printf("####欢迎使用R4序列密码####\n请输入密码:\n");
 scanf("%s",&key);

 WD(file1,file2,&key);//主要加密函数

 fclose(file1);
 fclose(file2);
 system("pause");
 return 1;
}

#9


感觉那个空字符和空格问题改过来了,但是发现解密还是会出现乱码,哪位朋友能帮我看下吗?多谢!

#10


char key;
scanf("%s",&key);
是这个原因吗?

#11


key这个类型定义错了吗?

#12


引用 11 楼 crazyben 的回复:
key这个类型定义错了吗?


应该没问题.反正你只输入一个字节,当然建议是改成getchar..

DEBUG,先定位是加密还是解密有错误,具体方法参考zhao4zhong1的经典回复。

另外建议代码放入代码框。一般放入代码框的会比较容易供大家阅读。

#13


在楼主代码的基础上改了该,运行结果如下图, 敬请验证:
求教一个C问题,RC4加密解密中遇到的问题。

#14


引用 13 楼 tonforce 的回复:
在楼主代码的基础上改了该,运行结果如下图, 敬请验证:

解密能解回来吗?

#15


楼主你的加密算法是算法没有公开,是一种很原始的加密算法,你的解密的过程可以通过加密的逆过程很容易求得,只要别人知道了你的加密算法,你的密码很快就会破解,所以现在这种加密已经很少用。现在的加密都是把怎么加密的过程公开,密钥保留,分为对称加密*和公钥密码*,一般都是两种一起配合来使用,推荐楼主可以看看《现代密码学》

#16


引用 15 楼 wyhllk 的回复:
楼主你的加密算法是算法没有公开,是一种很原始的加密算法,你的解密的过程可以通过加密的逆过程很容易求得,只要别人知道了你的加密算法,你的密码很快就会破解,所以现在这种加密已经很少用。现在的加密都是把怎么加密的过程公开,密钥保留,分为对称加密*和公钥密码*,一般都是两种一起配合来使用,推荐楼主可以看看《现代密码学》

我就是修的这门课做的课程设计