/
umud/DOC/
umud/DOC/examples/
umud/DOC/internals/
umud/DOC/wizard/
umud/MISC/
umud/MISC/dbchk/
umud/RWHO/rwhod/
/*
	Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/

#ifndef	lint
static	char	RCSid[] = "$Header: /usr/users/mjr/hacks/umud/RCS/rot.c,v 1.1 91/07/04 17:32:30 mjr Rel $";
#endif

/* configure all options BEFORE including system stuff. */
#include	"config.h"


#include	<stdio.h>

/*
just jiggle the text around a little to make it hard to read at a
glance. not a real encryption by any stretch of the imagination.

grabbed from some code off the net, originally by a Molly Kolodny
*/



/* boundaries of the printable set */
#define	LO	' '
#define	HI	'~'

/* size of our cryptospace */
#define	SIZ	(HI - LO)

/* number of rotating knives */
#define	NROT	9
static	int	rot[NROT];


/*
stir the rotating knives.

some kind of hash would make the stirring a lot nicer, but this needs
to be done in a fairly limited manner to prevent it from becoming machine
specific. IE: beware of overflows, and whatnot. any key should always
give the same set of rotation pointers or the objects with anything
encrypted in them will be unusable.
*/
void
rot_init(key)
char	*key;
{
	int	x = 0;
	int	ki = 0;
	int	ri = 0;
	int	hash;
	char	*kp = key;

	for(x = 0; x < NROT; x++)
		rot[x] = 0;

	if(key == (char *)0)
		kp = "otters";

	x = 0;
	hash = *kp;

	while(ri == 0 || ki == 0) {
		if(*kp == '\0')
			ki++, kp = key;
		if(x == NROT)
			ri++, x = 0;

		hash = *kp + (659 * hash) % SIZ;
		rot[x] = (rot[x] + hash) % SIZ;

		x++, kp++;
	}
}




/* stir the text through the rotating knives */
void
rot_encode(s1,s2)
char	*s1;
char	*s2;
{
	int	x, j;

	while(*s1 != '\0') {
		if(*s1 < LO || *s1 > HI) {
			*s2++ = *s1++;
			continue;
		}

		j = *s1 - LO;

		for(x = 0; x < NROT; x++) {
			if((j = j + rot[x]) >= SIZ)
				j = j - SIZ;

			if((rot[x] = rot[x] + (j / 3)) >= SIZ)
				rot[x] = rot[x] - SIZ;
		}

		*s2 = j + LO;
		s1++, s2++;
	}
	*s2 = *s1;
}




/* invert the stirring */
void
rot_decode(s1,s2)
char	*s1;
char	*s2;
{
	int	x, j, sj;

	while(*s1 != '\0') {
		if(*s1 < LO || *s1 > HI) {
			*s2++ = *s1++;
			continue;
		}

		j = *s1 - LO;

		for(x = NROT - 1; x != -1; x--) {
			sj = j;
			if((j = j - rot[x]) < 0)
				j = j + SIZ;

			if((rot[x] = rot[x] + (sj / 3)) >= SIZ)
				rot[x] = rot[x] - SIZ;
		}

		*s2 = j + LO;
		s1++, s2++;
	}
	*s2 = *s1;
}