# Thread: Beginner's Programming Challenge 18

1. ## Beginner's Programming Challenge 18

Hi all, as I am the winner of Beginner's Programming Challenge 17 I have the honour of bringing to you Beginner's Programming Challenge 18.

This time the challenge involves some basic cryptography. You must implement the Vigenère cipher in a programming language of your choice. Your program must prompt the user for a plaintext (the message) and a key (the password) and it should output the corresponding cyphertext (the encrypted message). For the sake of simplicity both the message and the key must contain only uppercase letters of the English alphabet.

For bonus points your program should also be able to decrypt a message given a cyphertext and a key.

This is a beginner's challenge, so the source code shouldn't be hard to read. Also please include plenty of comments.

http://en.wikipedia.org/wiki/Caesar_cipher
http://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher

Best of luck to all.

Rouslan
Last edited by roccivic; January 18th, 2011 at 10:08 PM.

2. ## Re: Beginner's Programming Challenge 18

Code:
```import Data.Char
import System(getArgs)

data Crypt = Encrypt | Decrypt deriving (Eq)

-- Takes two characters, one from the original string
-- and one from the corresponding index of the key string.
-- Returns the encrypted (or decrypted) character.
vigenere :: Crypt -> Char -> Char -> Char
vigenere e old key = chr \$ 65 + ((p_i `f` k_i) `mod` 26)
where p_i = (ord old) - 65
k_i = (ord key) - 65
f   = if e == Encrypt then (+) else (-)

-- Expects 3 command line arguments, the password, the key
-- and an 'e' or 'd' if you want to encrypt or decrypt
-- respectively. The password will be cycled as necessary
-- to be the same length as the source text
main = do
args <- getArgs
let [source, pass, x] = take 3 args
password = take (length source) (cycle pass)
e = case (head x) of
'e' -> Encrypt
'd' -> Decrypt
in putStrLn \$ zipWith (vigenere e) source password```
Here's a similar approach in Python, whited out for the time being:

Code:
```import sys
import operator
from itertools import cycle, islice

def vigenere(f, old, key):
p_i = ord(old) - 65
k_i = ord(key) - 65

return chr(65 + (f(p_i, k_i) % 26))

def main():
[source, passw, x] = sys.argv[1:4]
if x == "e":
elif x == "d":
f = operator.sub

s = ""
for i in xrange(len(source)):

print s

main()
```
Last edited by schauerlich; January 22nd, 2011 at 12:47 AM.

3. Dipped in Ubuntu
Join Date
May 2009
Beans
525

## Re: Beginner's Programming Challenge 18

Originally Posted by schauerlich
Code:
```import Data.Char
import System(getArgs)

-- Takes two characters, one from the original string
-- and the corresponding character of the key string.
-- To encrypt, f should be (+); to decrypt, (-)
vigenere :: (Int -> Int -> Int) -> Char -> Char -> Char
vigenere f old key = chr \$ 65 + ((f p_i k_i) `mod` 26)
where p_i = (ord old) - 65
k_i = (ord key) - 65

-- Expects 3 command line arguments, the password, the key
-- and an 'e' or 'd' if you want to encrypt or decrypt
-- respectively. The password will be cycled as necessary
-- to be the same length as the source text
main = do
args <- getArgs
let [source, pass, x] = take 3 args
password = take (length source) (cycle pass)
f = case (head x) of
'e' -> (+)
'd' -> (-)
in putStrLn \$ zipWith (vigenere f) source password```
what language is that?

4. ## Re: Beginner's Programming Challenge 18

It looks like Haskell to me...

5. ## Re: Beginner's Programming Challenge 18

Just wanted to get rid of a bad number of posts, bump!

6. First Cup of Ubuntu
Join Date
Dec 2010
Location
Denmark
Beans
2
Distro
Xubuntu

## Re: Beginner's Programming Challenge 18

Python solution.
Code:
```import string,sys

letters = string.uppercase

def vigenere(p,k,d):
if d:
i = ( ord(p) - ord(k) - 130) % len(letters)
else:
i = ( ord(p) + ord(k) - 130) % len(letters)
return letters[i]

if len(sys.argv)<4:
print "Usage:",sys.argv[0],"[plaintext|ciphertext] key [encrypt|decrypt]"
print "Example:",sys.argv[0]," attackatdawn lemon encrypt"
sys.exit(1)

text = sys.argv[1].upper()
key = sys.argv[2].upper()

decrypt = False

if sys.argv[3]=='decrypt':
decrypt = True

c=0
result = ''
for t in text:
result = result + vigenere(t,key[c % len(key)],decrypt)
c = c + 1

print result```

7. ## Re: Beginner's Programming Challenge 18

Here my shot at it in Java, I decided to implement it by actually creating the cypher table and looking up the characters.

Code:
```public class Cypher {

private static final int ROWS = 26;
private static final int COLS = 26;
private static final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static char[][] table;

//takes 2 args: text, key and 'e' or 'd'
public static void main(String[] args) {
//init the table
table = new char[ROWS][COLS];
for (int r = 0, offset = 0; r < ROWS; r++, offset++) {
for (int c = 0, pos = offset; c < COLS; c++, pos++) {
if (pos == alphabet.length()) {
pos = 0;
}
table[r][c] = alphabet.charAt(pos);
}
}
//Make string upper case
args[0] = args[0].toUpperCase();
args[1] = args[1].toUpperCase();
//append key if needed
while (args[0].length() > args[1].length()) {
args[1] += args[1];
}
args[1] = args[1].substring(0, args[0].length()+1);
//loop through each character and encrypt/decrypt
int pos = 0;
StringBuilder output = new StringBuilder(args[0].length());
for (int i = 0; i < args[0].length(); i++) {
if (args[2].equalsIgnoreCase("e")) {
output.append(encryptChar(args[0].charAt(i), args[1].charAt(i)));
} else if (args[2].equalsIgnoreCase("d")) {
output.append(decryptChar(args[0].charAt(i), args[1].charAt(i)));
}
}
System.out.println(output.toString()); //print output
}

//Encrypt character by looking up in table
private static char encryptChar(char orig, char key) {
int r = 0;
int c = 0;
for (; c < COLS; c++) {
if (table[c][0] == orig) {break;}
}
for (; r < ROWS; r++) {
if (table[0][r] == key) {break;}
}
return table[r][c];
}

//Decrypt character by looking up in table
private static char decryptChar(char crypted, char key) {
int r = 0;
for (; r < ROWS; r++) {
if (table[0][r] == key) {break;}
}
int c = 0;
for (; c < COLS; c++) {
if (table[c][r] == crypted) {break;}
}
return table[0][c];
}
}```
Last edited by KdotJ; January 19th, 2011 at 03:07 AM.

8. ## Re: Beginner's Programming Challenge 18

Originally Posted by unknownPoster
what language is that?

9. ## Re: Beginner's Programming Challenge 18

Bump, since there are hardly any entries.

10. ## Re: Beginner's Programming Challenge 18

Originally Posted by schauerlich
Bump, since there are hardly any entries.
This was posted the same week university started back up for me, maybe others are busy as well?

Here's an encrypter in Go. I'll add the decrypter tomorrow if I have time.

Code:
```// UFBPC 18
// @TAGS { UFBPC }
package main

import "fmt"
import "bufio"
import "os"

func main() {

fmt.Printf("Enter Message: ")
mess = mess[0:len(mess)-1] // trim off newline

fmt.Printf("Enter Key: ")
key = key[0:len(key)-1]

enc := ""
for i:=0; i<len(mess); i++ {
enc += vig(mess[i], key[0])
key = cycle(key)
}

fmt.Printf("Encrypted: %s\n", enc)
}

func cycle(in string) string {
ret := in[1:]
ret += in[0:1];
return ret
}

func vig( m, k uint8 ) string {
p_i := m - 65
k_i := k - 65
u_i := (65 + (p_i + k_i) % 26)
return string(u_i);
}```
Instructions for getting a Go compiler going: http://golang.org/doc/install.html
Not as easy as something pre-packaged but it's pretty straight forward none the less.
Last edited by Queue29; January 24th, 2011 at 05:42 AM.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•