Implement a program that encrypts messages using Vigenère’s cipher, per the below.

$ ./vigenere ABC
plaintext:  HELLO
ciphertext: HFNLP


Vigenère’s cipher improves upon Caesar’s cipher by encrypting messages using a sequence of keys (or, put another way, a keyword). In other words, if p is some plaintext and k is a keyword (i.e., an alphbetical string, whereby A represents 0, B represents 1, C represents 2, …​, and Z represents 25), then each letter, ci, in the ciphertext, c, is computed as:

\[c_i = (p_i + k_j) \bmod 26\]

Note this cipher’s use of kj as opposed to just k. And if k is shorter than p, then the letters in k must be reused cyclically as many times as it takes to encrypt p.

In other words, if Vigenère himself wanted to say HELLO to someone confidentially, using a keyword of, say, ABC, he would encrypt the H with a key of 0 (i.e., A), the E with a key of 1 (i.e., B), and the first L with a key of 2 (i.e., C), at which point he’d be out of letters in the keyword, and so he’d reuse (part of) it to encrypt the second L with a key of 0 (i.e., A) again, and the O with a key of 1 (i.e., B) again. And so he’d write HELLO as HFNLP.

Table 1. Encrypting HELLO with a keyword of ABC (reused cyclically as ABCAB) yields HFNLP.







+ key











= ciphertext







Design and implement a program that encrypts messages using Vigenère’s cipher.

  • Implement your program in a file called vigenere.c in a directory called vigenere.

  • Your 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 print an error (of your choice) and exit immediately, with main returning 1 (thereby signifying an error).

  • Otherwise, your program must proceed to prompt the user for a string of plaintext, p, (as by a prompt for plaintext:) which it must then encrypt according to Vigenère’s cipher with k, ultimately printing the result (prepended with ciphertext: and ending with a newline) and exiting, with main returning 0.

  • With respect to the characters in k, you must treat A and a as 0, B and b as 1, …​ , and Z and z as 25.

  • Your program must only apply Vigenère’s cipher to a character in p if that character is a letter. All other characters (numbers, symbols, spaces, punctuation marks, etc.) must be outputted unchanged. Moreover, if your code is about to apply the jth character of k to the ith character of p, but the latter proves to be a non-alphabetical character, you must wait to apply that jth character of k to the next alphabetical character in p; you must not yet advance to the next character in k.

  • Your program must preserve the case of each letter in p.



Your program should behave per the examples below. Assumed that the underlined text is what some user has typed.

$ ./vigenere 13
Usage: ./vigenere k
$ ./vigenere
Usage: ./vigenere k
$ ./vigenere bacon and eggs
Usage: ./vigenere k
$ ./vigenere bacon
plaintext: Meet me at the park at eleven am
ciphertext: Negh zf av huf pcfx bt gzrwep oz


To help you test vigenere, we’ve written a program called devigenere for you that also takes one and only one command-line argument (a keyword) but whose job is to take ciphertext as input and produce plaintext as output. To use our program, execute

~cs50/pset2/devigenere k

at your prompt, where k is some keyword. Presumably you’ll want to paste your program’s output as input to our program; be sure, of course, to use the same key. Note that you do not need to implement devigenere yourself, only vigenere.


check50 cs50/2017/x/vigenere

Staff’s Solution



Not sure where to begin? As luck would have it, this program’s pretty similar to caesar! Only this time, you need to decide which character in k to use as you iterate from character to character in p.


None so far! Reload this page periodically to check if any arise!


  • 2017-02-01

    • Clarified requirement of a newline at the end of the ciphered text.

  • 2016-09-15

    • Clarified usage of user prompts.

  • 2016-09-14

    • Added tl;dr, FAQs, Changelog.

  • 2016-09-09

    • Initial release.