sampson@attctc.Dallas.TX.US (Steve Sampson) (01/06/90)
Archive-name: dynsub/v1.01
Original-posting-by: sampson@attctc.Dallas.TX.US (Steve Sampson)
Original-subject: Dynamic Substitution (debugged)
Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)
[This is an experimental alt.sources re-posting from the newsgroup(s)
sci.crypt. Comments on this service to emv@math.lsa.umich.edu 
(Edward Vielmetti).]
My earlier bug question was answered by Yves Gallot who determined
that I needed 'unsigned char' for it to work.  In case anyone is
interested in trying Terry Ritter's Dynamic Substitution algorithm:
/*
 *	dynsub.c
 *
 *	Dynamic Substitution Cipher Filter
 *
 *	Evaluation Version 1.01, January 1990
 *
 *	Copyright (c) November 5, 1989, By Terry F. Ritter
 *	All Rights Reserved
 *
 *	Modified for Turbo-C by sampson@attctc.dallas.tx.us (steve)
 *	with help from cernvax!galloty@relay.EU.net (yves gallot)
 */
#include <stdio.h>
#ifdef __TURBOC__
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
#else
#define	random(x)	(rand() % (x))
#endif
#define	BSIZE	256
unsigned char	f[BSIZE], finv[BSIZE], buf[BSIZE];
void ExchangeChars(x, y)
unsigned char	*x, *y;
{
	unsigned char	t;
	t = *x;
	*x = *y;
	*y = t;
}
void DynSubInit()
{
	register int	i;
	for (i = 0; i < BSIZE; i++)
		f[i] = (unsigned char)i;
	for (i = 0; i < BSIZE; i++)
		ExchangeChars(&f[i], &f[random(BSIZE)]);
}
void InvDynSubInit()
{
	register int	i;
	DynSubInit();
	for (i = 0; i < BSIZE; i++)
		finv[f[i]] = (unsigned char)i;
}
unsigned char DynSubF(xi)
unsigned char	xi;
{
	unsigned char	t;
	t = f[xi];
	ExchangeChars(&f[xi], &f[random(BSIZE)]);
	return t;
}
unsigned char InvDynSubF(yi)
unsigned char	yi;
{
	unsigned char	j, xi, yj;
	xi = finv[yi];
	j  = random(BSIZE);
	yj = f[j];
	ExchangeChars(&finv[yi], &finv[yj]);
	ExchangeChars(&f[xi], &f[j]);
	return xi;
}
void encipher()
{
	register int	i, got;
	DynSubInit();
	for (;;)  {
		if ((got = fread(buf, sizeof(char), BSIZE, stdin)) < 1)
			return;
		for (i = 0;  i < got; i++)
			buf[i] = DynSubF(buf[i]);
		fwrite(buf, sizeof(char), got, stdout);
	}
}
void decipher()
{
	register int	i, got;
	InvDynSubInit();
	for (;;)  {
		if ((got = fread(buf, sizeof(char), BSIZE, stdin)) < 1)
			return;
		for (i = 0; i < got; i++)
			buf[i] = InvDynSubF(buf[i]);
		fwrite(buf, sizeof(char), got, stdout);
	}
}
main(argc, argv)
int	argc;
char	**argv;
{
#ifdef __TURBOC__
        /*
         *      Change stdin/stdout to binary mode, big buffers
         */
        setmode(0, O_BINARY);
        setmode(1, O_BINARY);
	setvbuf(stdin,  NULL, _IOFBF, BSIZE);
	setvbuf(stdout, NULL, _IOFBF, BSIZE);
#endif
	if (argc == 3)  {
		argv++;
		srand(atoi(*argv));
	} else
		srand(1);
	argv++;
	if (**argv == 'd')
		decipher();
	else if (**argv == 'e')
		encipher();
	else  {
		puts("Usage: dynsub [key 0 - 65536] e|d <infile >outfile");
		exit(1);
	}
	exit(0);
}