🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Carl Ellison Wed, 16 Dec 1992 18:39
reposting of tran
#2259
Author: Carl Ellison
Date: Wed, 16 Dec 1992 18:39
251 lines
7677 bytes
I have made reference to a UNIX program called tran, several times, and was
finally asked where to find it.  It had been posted on sci.crypt
a while ago.  I've since modified it a little and decided to re-post it.
The original posting was by setzer@math.ncsu.edu (William Setzer).
Many thanks to him for this code.

--Carl

P.S.  To try it, unpack this shar file into a blank directory then
use the command

	make test

(also available,  "make clean", "make all", "make tran").

---- Cut Here and unpack ----
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  Makefile
#	  foo
#	  rnd.c
#	  tran.c
#
if test -f Makefile; then echo "File Makefile exists"; else
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
Xall: tran
X
Xtran: tran.c rnd.c
X	cc -o tran -O rnd.c tran.c
X
Xtest: tmp all
X	tran < tmp > tmpo ; more tmpo ; mv tmpo tmp
X
Xtmp: foo
X	cp foo tmp
X
Xclean:
X	rm -f tmp tmpo tran tran.o rnd.o
SHAR_EOF
chmod 0644 Makefile || echo "restore of Makefile fails"
set `wc -c Makefile`;Sum=$1
if test "$Sum" != "182"
then echo original size 182, current size $Sum;fi
fi
if test -f foo; then echo "File foo exists"; else
echo "x - extracting foo (Text)"
sed 's/^X//' << 'SHAR_EOF' > foo &&
Xabcdefghijklmnopqrstuvwxyz0123456789-!@#$%^&*()_+[]{}'"`~;:,.<>/?|
SHAR_EOF
chmod 0664 foo || echo "restore of foo fails"
set `wc -c foo`;Sum=$1
if test "$Sum" != "67"
then echo original size 67, current size $Sum;fi
fi
if test -f rnd.c; then echo "File rnd.c exists"; else
echo "x - extracting rnd.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > rnd.c &&
X/* source/rnd.c: random number generator
X
X   Copyright (c) 1989-91 James E. Wilson
X
X   This software may be copied and distributed for educational, research, and
X   not for profit purposes provided that this copyright and statement are
X   included in all such copies. */
X
X/* This routine is straight out of the umoria5.3.1 distribution, except
X   that I hacked out the moria-specific stuff.  -WPS- */
X 
X/* Define this to compile as a standalone test */
X
X/* This alg uses a prime modulus multiplicative congruential generator
X   (PMMLCG), also known as a Lehmer Grammer, which satisfies the following
X   properties
X
X   (i)	 modulus: m - a large prime integer
X   (ii)	 multiplier: a - an integer in the range 2, 3, ..., m - 1
X   (iii) z[n+1] = f(z[n]), for n = 1, 2, ...
X   (iv)	 f(z) = az mod m
X   (v)	 u[n] = z[n] / m, for n = 1, 2, ...
X
X   The sequence of z's must be initialized by choosing an initial seed
X   z[1] from the range 1, 2, ..., m - 1.  The sequence of z's is a pseudo-
X   random sequence drawn without replacement from the set 1, 2, ..., m - 1.
X   The u's form a psuedo-random sequence of real numbers between (but not
X   including) 0 and 1.
X
X   Schrage's method is used to compute the sequence of z's.
X   Let m = aq + r, where q = m div a, and r = m mod a.
X   Then f(z) = az mod m = az - m * (az div m) =
X	     = gamma(z) + m * delta(z)
X   Where gamma(z) = a(z mod q) - r(z div q)
X   and	 delta(z) = (z div q) - (az div m)
X
X   If r < q, then for all z in 1, 2, ..., m - 1:
X   (1) delta(z) is either 0 or 1
X   (2) both a(z mod q) and r(z div q) are in 0, 1, ..., m - 1
X   (3) absolute value of gamma(z) <= m - 1
X   (4) delta(z) = 1 iff gamma(z) < 0
X
X   Hence each value of z can be computed exactly without overflow as long
X   as m can be represented as an integer.
X */
X
X/* a good random number generator, correct on any machine with 32 bit
X   integers, this algorithm is from:
X
XStephen K. Park and Keith W. Miller, "Random Number Generators:
X	Good ones are hard to find", Communications of the ACM, October 1988,
X	vol 31, number 10, pp. 1192-1201.
X
X   If this algorithm is implemented correctly, then if z[1] = 1, then
X   z[10001] will equal 1043618065
X
X   Has a full period of 2^31 - 1.
X   Returns integers in the range 1 to 2^31-1.
X */
X
X#define RNG_M 2147483647L  /* m = 2^31 - 1 */
X#define RNG_A 16807L
X#define RNG_Q 127773L	   /* m div a */
X#define RNG_R 2836L	   /* m mod a */
X
X/* 32 bit seed */
Xstatic long rnd_seed;
X
Xvoid set_rnd_seed (seedval)
Xlong seedval;
X{
X  /* set seed to value between 1 and m-1 */
X
X  rnd_seed = (seedval % (RNG_M - 1)) + 1;
X}
X
X/* returns a pseudo-random number from set 1, 2, ..., RNG_M - 1 */
Xlong rnd()
X{
X  register long low, high, test;
X
X  high = rnd_seed / RNG_Q;
X  low = rnd_seed % RNG_Q;
X  test = RNG_A * low - RNG_R * high;
X  if (test > 0)
X    rnd_seed = test;
X  else
X    rnd_seed = test + RNG_M;
X  return rnd_seed;
X}
SHAR_EOF
chmod 0644 rnd.c || echo "restore of rnd.c fails"
set `wc -c rnd.c`;Sum=$1
if test "$Sum" != "2872"
then echo original size 2872, current size $Sum;fi
fi
if test -f tran.c; then echo "File tran.c exists"; else
echo "x - extracting tran.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > tran.c &&
X/* modified from the original posting, by Carl Ellison, to remove */
X/* the password and therefore keep this from being an encryption program */
X/* The original code was written by setzer@math.ncsu.edu (William Setzer) */
X
X#include <stdio.h>
X
Xextern void set_rnd_seed();
Xextern long rnd();
X
X#define BLOCKSIZE 8192
X
Xlong  perm[BLOCKSIZE];
Xchar buf[BLOCKSIZE];
X
XFILE *my_fopen(file, type)
Xchar *file, *type;
X{
X  FILE *fp;
X
X  if (fp = fopen(file, type))
X    return fp;
X  (void) fprintf(stderr, "Can't open '%s'\n", file);
X  exit(1);
X}
X
Xmain(argc, argv)
Xlong argc;
Xchar **argv;
X{
X  register long i, len;
X  register FILE *infp, *outfp;
X  long savlen, pos, key;
X  char tmp;
X
X  infp  = (argc > 1) ? my_fopen(argv[1], "r") : stdin;
X  outfp = (argc > 2) ? my_fopen(argv[2], "w") : stdout;
X
X  len = fread(buf, 1, BLOCKSIZE, infp);
X  key = lstr2int(buf,len);
X  set_rnd_seed(key);
X
X  do {
X    savlen = len;
X
X    for (i = 0; i < len; i++)
X      perm[i] = i;
X    
X#define swap(A,B)  tmp = A; A = B; B = tmp;
X
X    while (len > 1)
X      {
X	pos = 1 + rnd() % (len - 1);
X	swap( buf[perm[0]], buf[perm[pos]] );
X
X	perm[0]   = perm[(pos == len - 2) ? len - 1 : len - 2];
X	perm[pos] = perm[len - 1];
X	len -= 2;
X      }
X    fwrite(buf, 1, savlen, outfp);
X  } while (len = fread(buf, 1, BLOCKSIZE, infp));
X}
X
X/* Make an integer out of a string.  Do a poor job of it.
X * Note that since this function is called on a block of transposed
X * text and used to construct an "rng key", it mustn't be sensitive
X * to the position of characters  in `str'.
X */
Xlong lstr2int(str,len)
Xchar *str;
Xlong len;
X{
X  long sum = 0;
X  long i ;
X
X  for ( i = 0 ; i < len ; i++ )
X    sum += *str++;
X
X  return sum;
X}
X
SHAR_EOF
chmod 0644 tran.c || echo "restore of tran.c fails"
set `wc -c tran.c`;Sum=$1
if test "$Sum" != "1670"
then echo original size 1670, current size $Sum;fi
fi
exit 0
-- 
-- <<Disclaimer: All opinions expressed are my own, of course.>>
-- Carl Ellison						cme@sw.stratus.com
-- Stratus Computer Inc.	M3-2-BKW		TEL: (508)460-2783
-- 55 Fairbanks Boulevard ; Marlborough MA 01752-1298	FAX: (508)624-7488
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads