Skip to content

Instantly share code, notes, and snippets.

@CraigRodrigues
Created June 1, 2016 02:45
Show Gist options
  • Save CraigRodrigues/5b4fd2e2d29c9a2746d566fd589431ea to your computer and use it in GitHub Desktop.
Save CraigRodrigues/5b4fd2e2d29c9a2746d566fd589431ea to your computer and use it in GitHub Desktop.
My solution to CS50 pset2 - "Parlez-vous français?"
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
/**
* Vigenere.c
*
* A program that encrypts messages using Vigenère’s cipher. This program
* must accept a single command-line argument: a keyword, k, composed entirely
* of alphabetical characters. If your program is executed without any
* command-line arguments, with more than one command-line argument, or with one
* command-line argument that contains any non-alphabetical character, your
* program should complain and exit immediately, with main returning 1
* (thereby signifying an error that our own tests can detect). Otherwise, your
* program must proceed to prompt the user for a string of plaintext, p, which
* it must then encrypt according to Vigenère’s cipher with k, ultimately
* printing the result and exiting, with main returning 0.
*
* */
int main(int argc, string argv[])
{
// check for 2 arguments only
if (argc != 2)
{
printf("Nope\n");
return 1;
}
// check if argument is all alpha char (no punct) - use loop and isalpha
for (int i = 0; i < strlen(argv[1]); i++)
{
if (isalpha(argv[1][i]) == 0)
{
printf("Nope\n");
return 1;
}
}
// prompt user for codeword
string codeword = GetString();
int j = 0;
// loop through the codeword. If not a letter than print unmodified.
for (int i = 0, n = strlen(codeword); i < n; i++)
{
// to keep looping through the key continously
j = j % strlen(argv[1]);
// check if the char is alpha
if (isalpha(codeword[i]))
{
// only 4 types of outcomes
if (islower(codeword[i]) && islower(argv[1][j]))
printf("%c", (((codeword[i] - 97) + (argv[1][j] - 97)) % 26) + 97);
else if (isupper(codeword[i]) && islower(argv[1][j]))
printf("%c", (((codeword[i] - 65) + (argv[1][j] - 97)) % 26) + 65);
else if (islower(codeword[i]) && isupper(argv[1][j]))
printf("%c", (((codeword[i] - 97) + (argv[1][j] - 65)) % 26) + 97);
else if (isupper(codeword[i]) && isupper(argv[1][j]))
printf("%c", (((codeword[i] - 65) + (argv[1][j] - 65)) % 26) + 65);
j++;
}
else
{
printf("%c", codeword[i]);
}
}
printf("\n");
}
@CraigRodrigues
Copy link
Author

CraigRodrigues commented Jun 1, 2016

Steps:

  1. Accept command-line argument to be used as a keyword.
  2. Loop through the inputted string to make sure it is all alpha characters.
  3. If not then throw an error (return 1).
  4. Prompt user for plaintext string codeword(s).
  5. Loop through the codeword char by char.
  6. If the char is a letter then take the first char of the keyword and use that char as the key for encrypting that particular letter.
  7. The keyword loop should continue and wraparound on itself until the codeword is full encrypted.
  8. Blank spaces and special characters should be printed out as is and they keyword key should not be incremented or used for those characters.
  9. The key characters should be standardized to 26 and start at 0. So 'a' and 'A' are 0. 'b' and 'B' are 1, etc.
  10. Preserve the case for the encrypted codeword characters.
  11. Print new line at the very end.
  12. Return 1.

Notes:

  • How could I make the code formula into a function?
  • isalpha is very useful for this problem.
  • Thought I may need ispunct, but the keyword shouldn't contain any special characters anyway.
  • atoi is not needed, although I thought it was from Caesar.
  • It took a bit for me to figure out how to have the keyword continually loop, but it's the exact same method as converting the ASCII to standard 26 count alphabet.
  • Factoring out the main formulas was a PITA.
  • There are only 4 different types of outcomes available for each codeword character and keyword key configuration.
  • I didn't fully read the instructions and had A = 1 and B = 2 to start and that messed me up for a bit.
  • I am not sure how I could use a function in place of the encrypting formula. I want to come back to this later after I learn more. I feel like it could be cleaned up!

@alexkoss02
Copy link

What is the importance of J why was it introduced?

@marieurbina
Copy link

J is because there are two string arrays to loop through: the codeword, which is looped through with strlen on line 46, as well as argv[1], the command line argument word the programmer (Craig) types in. argv[1] is the keyword or k in the comments on line 10.
For each letter in the codeword, codeword[i], the arg[1] also clicks to the next letter in itself, argv[1][j].
If I understand correctly, J functions like an inner loop, a loop within a loop.
Hope this helps.

Now I'm trying to understand line 49 better? Is that like starting a while loop? Anyone?

@practicaltexan
Copy link

j = j % strlen(argv[1]);

This is where he modifies the length of J to the length of argv. Once J hits the length of argv it will re-start back over at the first char.

If this wasn't there, j would continue to increase with every char past the strlen of argv. This is a limiter and so needs to be reset prior to going into the if/else if functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment