1993-05-29 - Re: Modified Vigenere encryption?

Header Data

From: stig@netcom.com (Stig)
To: cypherpunks@toad.com
Message Hash: 8507cf198266a606dc501ac0dac0799aa27e9bd85b6e9ee89849c4435ead585d
Message ID: <9305290603.AA16770@netcom.netcom.com>
Reply To: <9305280735.AA22115@malibu.sfu.ca>
UTC Datetime: 1993-05-29 06:03:42 UTC
Raw Date: Fri, 28 May 93 23:03:42 PDT

Raw message

From: stig@netcom.com (Stig)
Date: Fri, 28 May 93 23:03:42 PDT
To: cypherpunks@toad.com
Subject: Re: Modified Vigenere encryption?
In-Reply-To: <9305280735.AA22115@malibu.sfu.ca>
Message-ID: <9305290603.AA16770@netcom.netcom.com>
MIME-Version: 1.0
Content-Type: text/plain



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 */





Thread