ASCII encryption in C

Asked

Viewed 728 times

1

I need help with that, I’ve done the functions that encryption and decryption, it encrypts normal, however, at the time of decryption it sure does not do the process properly.

The error and the following: to encrypt I think it encrypts correctly I even made a pritf there to see the result and how it is controlling the arrays, but when decrypting it eats a letter of the password, and says that there is a character more in the file, Besides the password entry go from 1 to 8 and I think it should go from 0 to 7 as in encryption.

follows a "Log" of what happens:

    ESSE E O LOG DELE ENCRIPTANDO
    O---------------------------------------O
    |     WELCOME TO ENCRYPTION SYSTEM      |
    |---------------------------------------|
    | 1 - Encrypt file                      |
    | 2 - Decrypt file                      |
    | 0 - Quit                              |
    O---------------------------------------O
    o--> 1
    Please, enter password: Senha123
    Enter the name of the source file: test.txt
    The source file will be encrypted in the target file.
    Enter the target file name: enc
    File chars: 15
    Password chars: 8
    char: �[15] - encrypted: � - password: S[0]
    char:  [14] - encrypted: � - password: e[1]
    char: z[13]  - encrypted:  - password: n[2]
    char: t[12] - encrypted: # - password: h[3]
    char: n[11] - encrypted: 0 - password: a[4]
    char: e[10] - encrypted: i - password: 1[5]
    char: W[9]  - encrypted: v - password: 2[6]
    char:  [8]  - encrypted: � - password: 3[7]
    char: s[7]  - encrypted: 9 - password: S[0]
    char: o[6]  - encrypted: + - password: e[1]
    char: i[5]  - encrypted: ( - password: n[2]
    char: c[4]  - encrypted: 4 - password: h[3]
    char: i[3]  - encrypted: 5 - password: a[4]
    char: n[2]  - encrypted: ` - password: 1[5]
    char: i[1]  - encrypted: d - password: 2[6]
    char: V[0]  - encrypted: v - password: 3[7]



    ESSE E O LOG DELE DESECRIPTANDO
    O---------------------------------------O
    |     WELCOME TO ENCRYPTION SYSTEM      |
    |---------------------------------------|
    | 1 - Encrypt file                      |
    | 2 - Decrypt file                      |
    | 0 - Quit                              |
    O---------------------------------------O
    o--> 2
    Please, enter password: Senha123
    Enter the name of the source file: enc
    The encrypted file will be dencrypted in the target file.
    Enter the target file name: dec
    File chars: 16
    Password chars: 8
    char: �[16] - decrypted:  - password: [8]
    char: �[15] - decrypted: � - password: 3[7]
    char: �[14] - decrypted: � - password: 2[6]
    char: �[13] - decrypted: � - password: 1[5]
    char: �[12] - decrypted: � - password: a[4]
    char: �[11] - decrypted: � - password: h[3]
    char: �[10] - decrypted: � - password: n[2]
    char: �[9] - decrypted: � - password: e[1]
    char: �[8] - decrypted:  - password: [8]
    char: �[7] - decrypted: � - password: 3[7]
    char: �[6] - decrypted: � - password: 2[6]
    char: �[5] - decrypted: � - password: 1[5]
    char: �[4] - decrypted: � - password: a[4]
    char: �[3] - decrypted: � - password: h[3]
    char: �[2] - decrypted: � - password: n[2]
    char: �[1] - decrypted: � - password: e[1]
    char: �[0] - decrypted:  - password: [8]

follows the explanation:

Algorithm 1 - Text encryption algorithm A program must be developed to encrypt and decrypt text files. The program must ask the user for the name of the file with the text to be encrypted, the name of the target file of the encrypted text, and a keyword for the encryption. With this information the program must create the second file containing the encrypted text. This same program must decrypt the text file. The program must ask the user the name of the source files (encrypted text) and destination (plain text) and the keyword that was used in the encryption, the program must generate the target file containing the plain text (decrypted).

Encryption protocol: Given any keyword (and any size), the program must read from the text block text file (vector) the size of that keyword, the vector must be reversed and calculated a displacement on top of each element of the text block, the amount to be shifted should be the ASCII number of the corresponding element in the keyword, only printable characters of the ASCII tables should be used, ranging from -127 +127 (or 0-255).

Example: Example text: This is an example text! Keyword: "Password 123"

keyword size: 8, then data blocks will be read from 8 on 8. ex: "This and u", the block should be inverted, ex: "u e etse", and calculated the keyword displacement in the case: 83, 101, 110, 104, 97, 49, 50, 51.

From this information one should apply the scroll on top of each element of the text block, for example, the text block (already inverted) "u e etse" has the following ASCII codes: 117, 32, 101, 32, 101 ,116, 115, 69. Now just add the displacement with the codes of the text block, example: 83+117, 101+32, 110+101, 104+32, 97+101, 49+116, 50+115, 51+69. This is the same as: -55, -122, -44, -119, -57, -90, -90, 120. Soon the encrypted text should look like this: "?ԉA6x]". Note that I said similar, and not identical, as the characters shown are not standard, their graphical display should vary from operating system to operating system.

This operation must be undone through the decryption function in the same program, which will basically do the reverse process.

Follows the codes of the functions that make the encryption and decryption:

ENCRYPTION

    #include "encryptEngine.h"
    void encrypt(FILE* sourceFile, FILE* encryptedFile, char* password) {
      char* sourceFileName = malloc(sizeof(char) * MAX_FILE_LENGTH);
      char* encryptedFileName;

      setPassword(password);
      setFileName(sourceFileName);
      if((sourceFile = fopen(sourceFileName, "r")) != NULL) {
        encryptedFileName = malloc(sizeof(char) * MAX_FILE_LENGTH);
        setEncryptedFileName(encryptedFileName);
      } else {
        fileErrorHandler("notExist");
      }

      int index, indexPass;
      char auxiliary, encryptedChar;

      rewind(sourceFile);
      fseek(sourceFile, 0L, SEEK_END);
      printf("File chars: %d\n", ftell(sourceFile));
      printf("Password chars: %d\n", sizeof(password));
      if((encryptedFile = fopen(encryptedFileName, "w")) != NULL) {
        indexPass = 0;
        index = ftell(sourceFile);
        while(index >= 0L){
          fseek(sourceFile, index, SEEK_SET);
          auxiliary = fgetc(sourceFile);
          encryptedChar = 255 - (password[indexPass] + auxiliary);
          printf("char: %c[%d] - encrypted: %c - password: %c[%d]\n", auxiliary, index, encryptedChar, password[indexPass], indexPass);
          fprintf(encryptedFile, "%c", encryptedChar);
          indexPass++;
          if(indexPass == sizeof(password)) {
            indexPass = 0;
          }
          index--;
        }
        printf("\n");
      } else {
        fileErrorHandler("fileName");
      }
      fclose(sourceFile);
      fclose(encryptedFile);
      free(sourceFileName);
      free(encryptedFileName);
    }

DECRYPTION

    #include "decryptEngine_new.h"
    void decrypt(FILE* encryptedFile, FILE* decryptedFile, char* password) {
      char* encryptedFileName = malloc(sizeof(char*) * MAX_FILE_LENGTH);
      char* decryptedFileName;

      setPassword(password);
      setFileName(encryptedFileName);
      if((encryptedFile = fopen(encryptedFileName, "r")) != NULL) {
        decryptedFileName = malloc(sizeof(char*) * MAX_FILE_LENGTH);
        setDecryptedFileName(decryptedFileName);
      } else {
        fileErrorHandler("notExist");
      }

      int index, indexPass;
      char auxiliary, decryptedChar;

      rewind(encryptedFile);
      fseek(encryptedFile, 0L, SEEK_END);
      printf("File chars: %d\n", ftell(encryptedFile));
      printf("Password chars: %d\n", sizeof(password));
      if((decryptedFile = fopen(decryptedFileName, "w")) != NULL) {
        indexPass = sizeof(password);
        index = ftell(encryptedFile);
        while(index >= 0L) {
          fseek(encryptedFile, index, SEEK_END);
          auxiliary = fgetc(encryptedFile);
          decryptedChar = (255 - auxiliary) - password[indexPass];
          printf("char: %c[%d] - decrypted: %c - password: %c[%d]\n", auxiliary, index, decryptedChar, password[indexPass], indexPass);
          fprintf(decryptedFile, "%c", decryptedChar);
          indexPass--;
          if(indexPass == 0) {
            indexPass = sizeof(password);
          }
          index--;
        }
        printf("\n");
      } else {
        fileErrorHandler("fileName");
      }
      fclose(encryptedFile);
      fclose(decryptedFile);
      free(encryptedFileName);
      free(decryptedFileName);
    }

I would be very happy with a help, or even a tip, I do not want the answer to the problem because I like to do it by myself, however, I am 3 days with the problem.

  • Next time try to create a reduced version of your problem instead of posting the entire file. With a smaller program it is much easier to debug. Not to mention that taking out all the file read details, etc, it is much easier for other people to reproduce your bug and that also I do not know if your teacher will find it cool that you are posting the homework code on the internet from where your colleagues can copy :)

  • Relax buddy, go no, that’s just a part of the code, and wrong by the way :)

2 answers

3


First of all, look the observation of hugomg how to calculate the password size. It should be strlen(password) and not sizeof(password).

Your problem is in how you are treating the range limits (in the case of the password for sure, and most likely in the case of the file as well). When you encrypt it:

indexPass++;
if(indexPass == sizeof(password)) {
    indexPass = 0;
}

You warrant that indexPass never be equal to sizeof(password) [when it is used], at most 1 less than it. And how it starts (and starts again) from scratch, then the range being actually used is:

[0, sizeof(password)[

Already when you decrypt:

indexPass--;
if(indexPass == 0) {
    indexPass = sizeof(password);
}

You make sure it never equals zero, at most 1 more, and you start and start again from sizeof(password):

]0, sizeof(password)]

The consequence you should already imagine: the first character of the password is never used, and the null terminator (\0) at the end of the password is sometimes used (which in the case of a Vigenère cipher means that the character will be unchanged).

Anyway, this is irrelevant, because the way you are implementing the algorithm is not necessary to run the password "backwards" - if the first character of the message was combined with the first character of the key, the first character of the cipher must be combined also with the first character of the key... So that in your decrypt function you should use the same loop to scroll through the password you used in the encryption process.

(and if you were really to go back and forth, there would still be the problem of padding - unless the file size was multiple of the password size, only part it would be used near the end of the file. Further complicating its implementation...)

As for the file problem, I don’t have enough experience with C to say for sure, but most likely is of the same nature: the fseek(encryptedFile, index, SEEK_END) puts the position - in my opinion - not in its last byte, but 1 beyond it (again, by the convention of closed intervals at the beginning and open at the end). In addition, a quick look at their codes showed an inconsistent use of SEEK_END and SEEK_SET (I don’t know if it’s on purpose, as I said I have little practical experience with C).

Encryption:

  while(index >= 0L){
      fseek(sourceFile, index, SEEK_SET);

Decryption:

  while(index >= 0L) {
      fseek(encryptedFile, index, SEEK_END);

I suggest you check it out.

  • Thank you for the reply my friend, she helped me a lot, and I noticed another thing I was doing wrong, in the statement speaks that and for me to reverse a block of the password tamnaho and to jam, and so on, I’m reimplementando here, thank you very much and a great hug

2

One mistake you have in your code is that sizeof(password) does not contain the number of letters of the password. It will be the size of the pointer, which will probably always be 4.

In C you must always pass the size of your vectors as a separate parameter.

  • Wow, I didn’t even get that detail! In any case, when using null-terminated strings [as input] I don’t see much need to use a separate parameter - strlen should suffice. (the funny thing is that by coincidence AP used an 8 letter password on a 64 bit architecture... : P)

  • 1

    You are right but in general it is better to test whether the current character is null instead of using strlen. A very common mistake is to put a strlen inside a loop to see if it "arrived at the end", which turns out to be very bad for performance (strlen needs to scan the entire string every time you call)

  • Look thanks for the answer, I read that I could use the sizeof in the password, because it is a pointer, I do not know if it is right.

  • It’s just the opposite of what they told you. You can use the sizeof in an array that you reference directly but once you convert this array to a pointer or pass the array to some other function you lose the information of the size of the original array.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.