How to encrypt a text file using bit-wise XOR?

半腔热情 提交于 2020-01-05 15:14:08

问题


I am trying to encrypt a message from a text file by using the bit-wise XOR operation on the left and right characters with two specific keys from another file(keys.txt), but I am receiving unreadable code in front of the original text file(nothing changed), which is not right. I am using two text files:

1) Input.txt - containing the message that is to be encrypted

2) Keys.txt - This contains two characters that do the XOR operation to each character in the input.txt (character 1 is key 1 and character 2 is key 2)

The following code in my program:

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

is the line of code that is suppose to be performing the XOR operation

Note My desired output should look similar to this:

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

Can someone clarify the issue that I am running into?

The user should enter:

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

(The e just stands for encryption)

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


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!");
}

回答1:


C arrays indexes are zero based, then you should use

str2[0],str2[1]

instead of

str2[1],str2[2]

In this fragment

for(i=0;i<len;i++)
{
  str[i]=str[i]^str2[2];
  str[++i]=str[i]^str2[1];
  break;
}

break statement stop loop after first iteration. You should remove it. Then you get

for(i=0;i<len;i++)
{
  str[i]^=str2[1];
  str[++i]^=str2[0];
}

In line

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

you need logical AND instead of bitwise

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

And if your input.txt file contain more the 1024 byte to show all results you need to move printf("%s\n", str); into the while loop

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



回答2:


There are multiple issues with your code:

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

You should use the logical and operator (&&) instead of bitwise and (&)

char str2[2];

str2 can hold only 2 characters, so str[2] is illegal. Also, it does not have any space to hold the ending NULL character.

The for loop is incorrect. Here is an alternative:

for(i=0; i<len; i++) {
 str[i] ^= str2[i%2];
}

Finally, simply XORing two characters can produce values that are not valid ascii characters and thus won't be printed correctly. 'b'^'c' is 1, which will likely be printed as junk in your terminal. Consider using a modulo operation to produce the result string.




回答3:


To expand on Sourav's answer: If you are using an 8 bit code, such as ISO-8859-1, in which the printable characters are 32 to 126 and 160 to 255, giving 191 distinct values. Rather than using XOR, you could convert each character to an index between 0 and 190, add the message character index and the corresponding key character index modulus 191, and convert the result back to a character.




回答4:


From an encryption point of view, this is encryption, albeit a very weak one. It is the Shift Cipher (Caesar Cipher). Please note that str[0]^str2[1] is a constant, and the order of the XOR operations does not matter, so that

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

Is equivalent to:

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

To replace the XOR with a method that preserves readability following is my solution:

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

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


来源:https://stackoverflow.com/questions/29499480/how-to-encrypt-a-text-file-using-bit-wise-xor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!