Jump to content
  • Advertisement
Sign in to follow this  
EvilCloneVlad

Ideas for Encoding

This topic is 2827 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have written a basic program to encode input. It is very simple all it does is shift the letters by one I.E. a -> b. Now that I have the basic program working I would like to implement a better pattern for 'encoding' the characters.

My pattern that I wanted to use atleast for now was to have an array that stored the first 32 digits of PI and having a count of which character I was encoding. For example the first character the program encoded would be shifted up 3 while the second character would be shifted up only 1. I have a decent understanding of how I would go about implementing the pattern, the only thing that I can't think of is how I would manage to have the characters rotate back to the beginning of the alphabet. As an example if I was going to encode the alpha character 'z' and it was told to shift it up 1 character, obviously it would normally give you the next ascii character which happens to be { but I need it to roll back to 'a' so that it stays an alpha character.

Does anyone have any ideas/advice on a way to accomplish this task for any given amount it needs to shift because when it was set to just increase it by 1, I was able to hardcode it to transform 'z' to 'a' and vice versa, but now with the amount it is shifting being changed continuously, I need a way for the program to do it on the fly.

I hope I was clear enough in my explanation of what I am attempting to do. Posted below is my program as it currently stands, only shifting by 1 for everything.


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

char encode(char ch);
char decode(char ch);

int main(int argc, char *argv[])
{
char ch; /* var for current character in input */
char arg_code; /* command line arguement code, E for Encode, D for Decode */

if (argc == 2)
{
arg_code = argv[1][0];
}

arg_code = toupper(arg_code);

if (arg_code == 'E')
{
while ((ch = getchar()) != EOF)
{
ch = encode(ch);
putchar(ch);
}
}
else if (arg_code == 'D')
{
while ((ch = getchar()) != EOF)
{
ch = decode(ch);
putchar(ch);
}
}
else
{
printf("ERROR!");
}

return 0;
}

char encode(char ch)
{
if (isalpha(ch)) /* only encode alpha chars */
{
if (ch == 'z')
{
ch = 'a';
}
else if (ch == 'Z')
{
ch = 'A';
}
else
{
ch = ch+1;
}
}
return ch;
}

char decode(char ch)
{
if (isalpha(ch)) /* only decode alpha chars */
{
if (ch == 'a')
{
ch = 'z';
}
else if (ch == 'A')
{
ch = 'Z';
}
else
{
ch = ch-1;
}
}
return ch;
}


Share this post


Link to post
Share on other sites
Advertisement
Check out the "%" modulo operator. It returns the integer remainder of an integer division.

To encode ch:
ch = (ch-'a'+ 1)%26 + 'a';

To decode ch:
ch = (ch-'a'+25)%26 + 'a';

The %26 makes sure your result is in the range 0-25.
Subtracting 'a' makes sure the value you are working with is in the range of 0-25 so the % works.
Adding 'a' puts it back to the range 'a'-'z'

Because (-1)%26 can be one of two valid answers, depending on how % is defined by the language, I won't subtract 1.
To get the wrap around you are looking for, I instead add 25.

Share this post


Link to post
Share on other sites
Ok, after seeing your suggestion to use the modulus operator for the 'rollover' problem, i understand exactly what needs to be done to correct that issue. Now I have implemented it based on what I understand. Now for some reason when I run the program it seems to encode the message properly, however when I try to decode the message, depending on what it is decoding sometimes it is not decoding correctly. For example when I use the program to encode the message "I hate this program!" it puts out "L lbyn zmlx yyxjtdu!" which is the correct encoding, and when "L lbyn zmlx yyxjtdu!" is entered into the decoder it correctly decodes it back to "I hate this program!" but if I start with the input of "zzz" into the encoder it properly comes out with "cad" but then when I tell it to decode "cad" it outputs "```"

I have checked over my equations/functions for hours and everything appears to be in order as far as I can tell, I must be missing something however I cannot spot it. Is anyone else able to spot any sort of error in the logic the program uses?


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

char encode(char ch, int shiftBy);
char decode(char ch, int shiftBy);

int main(int argc, char *argv[])
{
int shift[32] = {3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5};
int charCount = 0;
char ch; /* var for current character in input */
char arg_code; /* command line arguement code, E for Encode, D for Decode */

if (argc == 2)
{
arg_code = argv[1][0];
}

arg_code = toupper(arg_code);

if (arg_code == 'E')
{
while ((ch = getchar()) != EOF)
{
if (charCount == 32)
{
charCount = 0;
}

ch = encode(ch, shift[charCount]);
putchar(ch);
charCount++;
}
}
else if (arg_code == 'D')
{
while ((ch = getchar()) != EOF)
{
if (charCount == 32)
{
charCount = 0;
}

ch = decode(ch, shift[charCount]);
putchar(ch);
charCount++;
}
}
else
{
printf("ERROR!");
}

return 0;
}

char encode(char ch, int shiftBy)
{
if (isalpha(ch)) /* only encode alpha chars */
{
if (ch <= 'Z')
{
ch = ch + shiftBy;
if (ch > 'Z')
{
ch = (ch % ('Z' + 1))+ 'A';
}
}
else if (ch <= 'z')
{
ch = ch + shiftBy;
if (ch > 'z')
{
ch = (ch % ('z' + 1))+ 'a';
}
}
}
return ch;
}

char decode(char ch, int shiftBy)
{
if (isalpha(ch)) /* only decode alpha chars */
{
if (ch <= 'Z')
{
ch = ch - shiftBy;
if (ch < 'A')
{
ch + 26;
}
}
else if (ch <= 'z')
{
ch = ch - shiftBy;
if (ch < 'a')
{
ch + 26;
}
}
}
return ch;
}



Share this post


Link to post
Share on other sites
You may want to turn up your compiler's warning level. MSVC, for example, will give a warning for those lines if you ask it nicely.

Share this post


Link to post
Share on other sites
Ok I am back with more problems :(

I got the encoding and decoding issue worked out with your guys' help. Now I was trying to extend the ability of the program and incorporate the ability for it to take an input and output file as an argument, and my program seems to grab the arguments correctly however at the point in my source were I try to read my input from the file it says that my FILE pointer was not declared, however I don't see an issue with the declaration... am I doing something incorrectly in my source?

here is the code I have:


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

char encode(char ch, int shiftBy);
char decode(char ch, int shiftBy);

int main(int argc, char *argv[])
{
int i = 0;
int j = 0;
int shift[32] = {3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5};
int charCount = 0;
char ch; /* var for current character in input */
char fileProcess; /* command line arguement code, E for Encode, D for Decode */
char fileIn[64] = "stdin";
char fileOut[64] = "stdout";


for (i = 1; i < argc; i++)
{
if (strcmp(argv, "-e") == 0)
{
fileProcess = 'e';
}
else if (strcmp(argv, "-d") == 0)
{
fileProcess = 'd';
}
else
{
if (strcmp(argv, "-in") == 0)
{
for (j = 0; j < strlen(argv[i+1]); j++)
{
fileIn[j] = argv[i+1][j];
}

FILE *fin = fopen(argv[i+1], "r");
i++;
}
else if (strcmp(argv, "-out") == 0)
{
for (j = 0; j < strlen(argv[i+1]); j++)
{
fileOut[j] = argv[i+1][j];
}

FILE *fout = fopen(argv[i+1], "w");
i++;
}
}
}


system("pause");

if (strcmp(fileIn, "stdin") == 0 && strcmp(fileOut, "stdout") == 0)
{
while ((ch = getchar()) != EOF)
{
if (charCount == 32)
{
charCount = 0;
}

switch (fileProcess)
{
case 'e':
ch = encode(ch, shift[charCount]);
break;
case 'd':
ch = decode(ch, shift[charCount]);
break;
}

putchar(ch);
charCount++;
}
}
else if (strcmp(fileIn, "stdin") != 0 && strcmp(fileOut, "stdout") == 0)
{
while ((ch = fgetc(fin)) != EOF) <----- HERE IS WHERE THE ERROR IS
{
if (charCount == 32)
{
charCount = 0;
}

switch (fileProcess)
{
case 'e':
ch = encode(ch, shift[charCount]);
break;
case 'd':
ch = decode(ch, shift[charCount]);
break;
}

putchar(ch);
charCount++;

fclose(fin);
}
}
else if (strcmp(fileIn, "stdin") == 0 && strcmp(fileOut, "stdout") != 0)
{
while ((ch = getchar()) != EOF)
{
if (charCount == 32)
{
charCount = 0;
}

switch (fileProcess)
{
case 'e':
ch = encode(ch, shift[charCount]);
break;
case 'd':
ch = decode(ch, shift[charCount]);
break;
}

fputc(ch,fout);
charCount++;
}

fclose(fout);
}
else if (strcmp(fileIn, "stdin") != 0 && strcmp(fileOut, "stdout") != 0)
{
while ((ch = fgetc(fin)) != EOF)
{
if (charCount == 32)
{
charCount = 0;
}

switch (fileProcess)
{
case 'e':
ch = encode(ch, shift[charCount]);
break;
case 'd':
ch = decode(ch, shift[charCount]);
break;
}

fputc(ch,fout);
charCount++;
}

fclose(fout);
fclose(fin);
}




return 0;
}

char encode(char ch, int shiftBy)
{
if (isalpha(ch)) /* only encode alpha chars */
{
if (ch <= 'Z')
{
ch = ch + shiftBy;
if (ch > 'Z')
{
ch = (ch % ('Z' + 1))+ 'A';
}
}
else if (ch <= 'z')
{
ch = ch + shiftBy;
if (ch > 'z')
{
ch = (ch % ('z' + 1))+ 'a';
}
}
}
return ch;
}

char decode(char ch, int shiftBy)
{
if (isalpha(ch)) /* only decode alpha chars */
{
if (ch <= 'Z')
{
ch = ch - shiftBy;
if (ch < 'A')
{
ch = ch + 26;
}
}
else if (ch <= 'z')
{
ch = ch - shiftBy;
if (ch < 'a')
{
ch = ch + 26;
}
}
}
return ch;
}




Share this post


Link to post
Share on other sites
In C++ variables have scope: a range of code where the variable definition is valid. For a local variables extends from where it's defined to the closing brace of the compound statement block that it lives in. For example:

void foo(void) {
int i = 0; // this variable is good for the entire function
for (int j = 0; j < 10; j++) { // variables defined in the for statement are only good for the for block
int k; // also only good for the for block
}
i = j + k; // error: j and k have gone out of scope and can't be used.
if (i > 10) {
int m; // again only good for the rest of the if block
}
i = m; // error
}

Share this post


Link to post
Share on other sites
Thank you for informing me. I knew a little about scope but did not realize that it was also in a statements block that it was limited, i thought it was only functions that the scope stayed in. I guess you learn something new every day.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!