Skip to content

Instantly share code, notes, and snippets.

@rberaldo
Created April 27, 2016 12:20
Show Gist options
  • Save rberaldo/a8ff6929257fbe98d87cd7bc4f0f7e8f to your computer and use it in GitHub Desktop.
Save rberaldo/a8ff6929257fbe98d87cd7bc4f0f7e8f to your computer and use it in GitHub Desktop.
/**
* vigenere.c
*
* Rafael Beraldo
* rberaldo@cabaladada.org
*
* Encrypts text with the Vigenère cipher
*/
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
/* In order for the encryption function to work, we must first get the
alphabetical index of a character by subtracting 65 if it is uppercase and 97
if it is lowercase. That's because in ASCII, they are not 0-indexed. */
#define UPPERCASE_ASCII_SHIFT 65
#define LOWERCASE_ASCII_SHIFT 97
#define SIZE_ALPHABET 26
// Functions
void print_usage(string program);
char encrypt(char letter, int key, int shift);
int main(int argc, string argv[])
{
// Exits if program has less or more than one argument
if (argc != 2)
{
print_usage(argv[0]);
return 1;
}
int key_length = strlen(argv[1]);
char key[key_length];
/** The case of the key shouldn't change anything, so let's make sure it's
* all lowercase. While we're at that, let's also check there aren't any
* non-alpha characters.
*/
for (int i = 0; i < key_length; i++)
{
if (!isalpha(argv[1][i]))
{
print_usage(argv[0]);
return 1;
}
else
{
key[i] = tolower(argv[1][i]);
}
}
string message = GetString();
// Cycle though all characters in message
for (int i = 0, j = 0, message_length = strlen(message); i < message_length; i++)
{
// If character isn't alphabetical, we don't need to touch it
if (!isalpha(message[i]))
{
printf("%c", message[i]);
}
// If it is alphabetical, it can be either upper or lowercase
else if (isupper(message[i]))
{
printf("%c", encrypt(message[i], key[j % key_length], UPPERCASE_ASCII_SHIFT));
j++;
}
else
{
printf("%c", encrypt(message[i], key[j % key_length], LOWERCASE_ASCII_SHIFT));
j++;
}
}
printf("\n");
return 0;
}
////////////////////////////////////////////
/**
* Prints usage information
*/
void print_usage(string program)
{
printf("Usage: %s <keyword>\n", program);
}
/**
* Encrypts a character using a key, shifting to correct for the ASCII table
*/
char encrypt(char letter, int key, int shift)
{
letter -= shift;
return (letter + key - 'a') % SIZE_ALPHABET + shift;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment