[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Modified Vigenere encryption?
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, [email protected], PGP public key by finger */
/* fingerprint = 32 DF B9 19 AE 28 D1 7A A3 9D 0B 1A 33 13 4D 7F */