如何使用逐位XOR加密文本文件?

我试图通过使用来自另一个文件(keys.txt)的两个特定键的左右字符的逐位XOR操作来加密来自文本文件的消息,但是我在原始文本前面接收到不可读的代码文件(没有改变),这是不对的。 我使用两个文本文件:

1)Input.txt – 包含要加密的消息

2)Keys.txt – 包含两个字符,对input.txt中的每个字符执行XOR操作(字符1是键1,字符2是键2)

我的程序中的以下代码:

str[i]=str[i]^str2[2]; str[++i]=str[i]^str2[1]; break; 

是要执行XOR操作的代码行

注意我想要的输出应该类似于:

m @#EmI(> 9S(@)H#FmN#XGmmmmU,H!Gmr(DmI“VmD,F(S!XmU%DmM”C> U(S>,O)9I(9T?U!D>, M!,E; @#B(Gmu%D4,S(:@ $ U $ O *“OmU%DmR%H#F!D`V $ M!4N8.N Dm @#EmK”H#9I(+ MMMM)@#B(F

有人可以澄清我遇到的问题吗?

用户应输入:

 gcc myProgram.c ./a.out e input.txt keys.txt 

(e只代表加密)

 #include #include #include int main(int args, char *argc[]){ int i; int len=0; char str[1024]; char str2[2]; FILE *finp; FILE *keyFile; if ( strcmp(argc[1], "e") == 0 ) { if ( (finp = fopen(argc[2],"r")) == NULL ) { printf("Could Not Open file %s\n", argc[2]); exit(1); } if ( (keyFile = fopen(argc[3],"r")) == NULL ) { printf("Could Not Open file %s\n", argc[3]); exit(1); } while((fgets(str,1024,finp)!=NULL)&(fgets(str2,2,keyFile)!=NULL)) { printf("%c\n %c",str2[1],str2[2]); /* *** START CODE THAT USES INPUT.TXT FILE & KEYS.TXT *** */ len = strlen(str); for(i=0;i<len;i++) { str[i]=str[i]^str2[2]; str[++i]=str[i]^str2[1]; break; } } printf("%s\n", str); fclose(finp); return 0; } else { printf("SORRY!"); } 

C数组索引是基于零的,那么你应该使用

 str2[0],str2[1] 

代替

 str2[1],str2[2] 

在这个片段中

 for(i=0;i 

第一次迭代后,break语句停止循环。 你应该删除它。 然后你得到

 for(i=0;i 

排队

 while((fgets(str,1024,finp)!=NULL)&(fgets(str2,2,keyFile)!=NULL)) 

你需要逻辑AND而不是按位

 while((fgets(str,1024,finp)!=NULL)&&(fgets(str2,2,keyFile)!=NULL)) 

如果你的input.txt文件包含更多1024字节来显示所有结果你需要移动printf(“%s \ n”,str); 进入while循环

 while((fgets(str,1024,finp)!=NULL)&&(fgets(str2,2,keyFile)!=NULL)) { ... printf("%s\n", str); } 

您的代码存在多个问题:

 while((fgets(str,1024,finp)!=NULL)&(fgets(str2,2,keyFile)!=NULL)) 

您应该使用逻辑和运算符(&&)而不是按位和(&)

 char str2[2]; 

str2只能容纳2个字符,因此str [2]是非法的。 此外,它没有任何空间来保存结束NULL字符。

for循环不正确。 这是一个替代方案:

 for(i=0; i 

最后,简单地对两个字符进行异或操作可以生成无效ascii字符的值,因此无法正确打印。 'b'^'c'为1,可能会在您的终端中打印为垃圾。 考虑使用模运算来生成结果字符串。

扩展Sourav的答案:如果您使用的是8位代码,例如ISO-8859-1,其中可打印字符为32到126和160到255,给出191个不同的值。 您可以将每个字符转换为0到190之间的索引,添加消息字符索引和相应的键字符索引模数191,然后将结果转换回字符,而不是使用XOR。

从加密的角度来看,这是加密,虽然是非常弱的。 它是Shift Cipher(Caesar Cipher)。 请注意,str [0] ^ str2 [1]是一个常量,并且XOR运算的顺序无关紧要,因此

  str[i]^=str2[1]; str[++i]^=str2[0]; 

相当于:

  char str12=str2[0]^str2[1]; // Outside of the loop ... str[++i]^=str12; 

要使用保留可读性的方法替换XOR,我的解决方案是:

 #include #include #include int index(int c) { int i; if ((c >= 32) && (c <= 126)) { i = c - 32; } else if ((c >= 160) && (c <= 255)) { i = c - 65; } else { i = 63; // Question mark } return i; } char unindex(int i) { if (i <= 94) { return (char)(i + 32); } else { return (char)(i + 65); } } char encrypt(char a, char b) { int aa = index(a & 255); int bb = index(b & 255); int cc = (aa + bb) % 191; return unindex(cc); } char decrypt (char a, char b){ int aa = index(a & 255); int bb = index(b & 255); int cc = (191 + aa - bb) % 191; return unindex(cc); } int main(int args, char *argc[]){ char e; printf("test\n"); e = encrypt('a',' '); printf ("encrypt('a',' ') = %c\n" , e); printf ("decrypt('a',' ') = %c\n" , decrypt (e, ' ')); e = encrypt('a','!'); printf ("encrypt('a','!') = %c\n" , e); printf ("decrypt('a','!') = %c\n" , decrypt (e, '!')); e = encrypt('ב',' '); printf ("encrypt('ב',' ') = %c\n" , e); printf ("decrypt('ב',' ') = %c\n" , decrypt(e,' ')); printf("(char) 255 = %c\n", (char) 255); e = encrypt((char) 255,' '); printf ("encrypt(255,' ') = %c\n" , e); printf ("decrypt(255,' ') = %c\n" , decrypt(e,' ')); e = encrypt('A',(char) 255); printf ("encrypt('A',255) = %c\n" , e); printf ("decrypt('A',255) = %c\n" , decrypt(e,(char) 255)); e = encrypt((char) 255,(char) 255); printf ("encrypt(255,255) = %c\n" , e); printf ("decrypt(255,255) = %c\n" , decrypt(e,(char) 255)); printf("end test\n"); return; }es