/*
Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/
/* configure all options BEFORE including system stuff. */
#include "config.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;
}