I must've missed it. Will some kind soul forward to me a description of Vigenere?
Also, what are the weaknesses of the Playfair cypher? My texts mention it, but don't say much of anything other than how it works...
Well, a while ago I saw a description of playfair in a novel and it was simple enough that I coded it... I guess I had lots of free time. Don't pick on my code. It's old. Stig /** * playfair.c -- implementation of the playfair cipher * written by stig, 10-mar-91 * * --- TO COMPILE (put this in your makefile) --- * unpf pf: playfair.c * cc $(CFLAGS) -o pf playfair.c * - rm unpf * ln pf unpf * * --- THIS PROGRAM works as a filter--- * pf keyword <message_file >code_file * unpf keyword <code_file * * --- THIS CIPHER uses a 5x5 alphabet square to encode letter pairs * * K E Y W O * R D a b c * f g h i l (i and j are folded into each other) * m n p q s * t u v x z * * 1) prepare the input by removing punctuation, * fold 'j' into 'i' * break up repeated letters with 'x' and/or 'z' * group letters into pairs * * My name is stig (or jonathan) ----> my na me is xs ti go ri on at ha nz * * 2) transform each letter pair using the alphabet square: * (i may be written as either i or j) * a) letters appear in the same row -- replace them with letters to * the right. letter to right of rightmost letter is first letter * of the row. (hi -> il (or jl)) * b) letters appear in the same column -- replace them with letters * below. (ha -> ph) * c) otherwise -- replace each letter with the letter occupying the * same row in the grid and the column of the other letter in the * pair. (my -> pk) * * MY NA ME IS XS TI GO RI ON AT HA NZ * pk pd nk lq zq xf le bf es rv ph su */ #include <ctype.h> #include <strings.h> #include <assert.h> #include <stdio.h> char *Key = 0; char Square[26] = " "; /* 25 spaces */ #define pos(row,col) Square[ (row)*5 + (col) ] #define findrow(c) ((int)(index(Square,c)-Square)/5) #define findcol(c) ((int)(index(Square,c)-Square)%5) #define jtoi(c) (((c)=='j') ? 'i' : (c)) #define ENCODE 1 #define DECODE 4 build_square() { char *key = Key, c; int i = 0; assert(key && *key); while (*key) { *key = tolower(*key); *key = jtoi(*key); if (isalpha(*key) && !index(Square, *key)) Square[i++] = (*key); ++key; } for (c = 'a'; c <= 'z'; ++c) { if (c == 'j' || index(Square, c)) continue; Square[i++] = c; } assert(i == 25); } /* read stdin, place processed data in buf */ prepare(buf, mode) char *buf; int mode; { int c, last = 0; /* last character */ char splitter = 'x'; /* separates repeated letters, 'x' or 'z' */ while ((c = getchar()) != EOF) { if (!isalpha(c)) continue; c = tolower(c); c = jtoi(c); if (c == last && mode == ENCODE) { *buf++ = splitter; splitter = (splitter == 'x') ? 'z' : 'x'; } last = c; *buf++ = c; } *buf = 0; } extern long random(); outchar(c, mode) char c; int mode; { if (c == 'i' && mode == ENCODE && (random() & 4)) c = 'j'; putchar(c); } transform(buf, ofs) char *buf; int ofs; /* 1 encodes, 4 decodes */ { int r1, c1, r2, c2; for (; *buf; buf += 2) { r1 = findrow(buf[0]); c1 = findcol(buf[0]); if (!buf[1]) { buf[2] = 0; buf[1] = 'a'+(random()%26); } r2 = findrow(buf[1]); c2 = findcol(buf[1]); if (r1 == r2) { outchar(pos(r1, (c1 + ofs) % 5), ofs); outchar(pos(r2, (c2 + ofs) % 5), ofs); } else if (c1 == c2) { outchar(pos((r1 + ofs) % 5, c1), ofs); outchar(pos((r2 + ofs) % 5, c2), ofs); } else { outchar(pos(r1, c2), ofs); outchar(pos(r2, c1), ofs); } } putchar('\n'); } main(argn, argv) int argn; char **argv; { char buf[BUFSIZ]; char *cmd; int mode; srandom(getpid()); if (argn != 2) { fprintf(stderr, "Playfair en/decoder\nusage: %s keyword\n", argv[0]); exit(1); } Key = argv[1]; cmd = rindex(argv[0], '/'); cmd = (cmd) ? cmd + 1 : argv[0]; mode = (cmd[0] == 'u') ? DECODE : ENCODE; if (mode == DECODE) printf("NOTE: 'i' may be 'j', 'x' or 'z' may be extra.\n\n"); build_square(); prepare(buf, mode); transform(buf, mode); return (0); } /* Jonathan Stigelman, Stig@netcom.com, PGP public key by finger */ /* fingerprint = 32 DF B9 19 AE 28 D1 7A A3 9D 0B 1A 33 13 4D 7F */