home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / sci / crypt / 5742 < prev    next >
Encoding:
Internet Message Format  |  1992-12-16  |  7.2 KB

  1. Path: sparky!uunet!noc.near.net!transfer.stratus.com!ellisun.sw.stratus.com!cme
  2. From: cme@ellisun.sw.stratus.com (Carl Ellison)
  3. Newsgroups: sci.crypt
  4. Subject: reposting of tran
  5. Date: 16 Dec 1992 18:39:36 GMT
  6. Organization: Stratus Computer, Software Engineering
  7. Lines: 251
  8. Distribution: world
  9. Message-ID: <1gnt58INN8um@transfer.stratus.com>
  10. NNTP-Posting-Host: ellisun.sw.stratus.com
  11.  
  12. I have made reference to a UNIX program called tran, several times, and was
  13. finally asked where to find it.  It had been posted on sci.crypt
  14. a while ago.  I've since modified it a little and decided to re-post it.
  15. The original posting was by setzer@math.ncsu.edu (William Setzer).
  16. Many thanks to him for this code.
  17.  
  18. --Carl
  19.  
  20. P.S.  To try it, unpack this shar file into a blank directory then
  21. use the command
  22.  
  23.     make test
  24.  
  25. (also available,  "make clean", "make all", "make tran").
  26.  
  27. ---- Cut Here and unpack ----
  28. #!/bin/sh
  29. # shar:    Shell Archiver  (v1.22)
  30. #
  31. #    Run the following text with /bin/sh to create:
  32. #      Makefile
  33. #      foo
  34. #      rnd.c
  35. #      tran.c
  36. #
  37. if test -f Makefile; then echo "File Makefile exists"; else
  38. echo "x - extracting Makefile (Text)"
  39. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  40. Xall: tran
  41. X
  42. Xtran: tran.c rnd.c
  43. X    cc -o tran -O rnd.c tran.c
  44. X
  45. Xtest: tmp all
  46. X    tran < tmp > tmpo ; more tmpo ; mv tmpo tmp
  47. X
  48. Xtmp: foo
  49. X    cp foo tmp
  50. X
  51. Xclean:
  52. X    rm -f tmp tmpo tran tran.o rnd.o
  53. SHAR_EOF
  54. chmod 0644 Makefile || echo "restore of Makefile fails"
  55. set `wc -c Makefile`;Sum=$1
  56. if test "$Sum" != "182"
  57. then echo original size 182, current size $Sum;fi
  58. fi
  59. if test -f foo; then echo "File foo exists"; else
  60. echo "x - extracting foo (Text)"
  61. sed 's/^X//' << 'SHAR_EOF' > foo &&
  62. Xabcdefghijklmnopqrstuvwxyz0123456789-!@#$%^&*()_+[]{}'"`~;:,.<>/?|
  63. SHAR_EOF
  64. chmod 0664 foo || echo "restore of foo fails"
  65. set `wc -c foo`;Sum=$1
  66. if test "$Sum" != "67"
  67. then echo original size 67, current size $Sum;fi
  68. fi
  69. if test -f rnd.c; then echo "File rnd.c exists"; else
  70. echo "x - extracting rnd.c (Text)"
  71. sed 's/^X//' << 'SHAR_EOF' > rnd.c &&
  72. X/* source/rnd.c: random number generator
  73. X
  74. X   Copyright (c) 1989-91 James E. Wilson
  75. X
  76. X   This software may be copied and distributed for educational, research, and
  77. X   not for profit purposes provided that this copyright and statement are
  78. X   included in all such copies. */
  79. X
  80. X/* This routine is straight out of the umoria5.3.1 distribution, except
  81. X   that I hacked out the moria-specific stuff.  -WPS- */
  82. X/* Define this to compile as a standalone test */
  83. X
  84. X/* This alg uses a prime modulus multiplicative congruential generator
  85. X   (PMMLCG), also known as a Lehmer Grammer, which satisfies the following
  86. X   properties
  87. X
  88. X   (i)     modulus: m - a large prime integer
  89. X   (ii)     multiplier: a - an integer in the range 2, 3, ..., m - 1
  90. X   (iii) z[n+1] = f(z[n]), for n = 1, 2, ...
  91. X   (iv)     f(z) = az mod m
  92. X   (v)     u[n] = z[n] / m, for n = 1, 2, ...
  93. X
  94. X   The sequence of z's must be initialized by choosing an initial seed
  95. X   z[1] from the range 1, 2, ..., m - 1.  The sequence of z's is a pseudo-
  96. X   random sequence drawn without replacement from the set 1, 2, ..., m - 1.
  97. X   The u's form a psuedo-random sequence of real numbers between (but not
  98. X   including) 0 and 1.
  99. X
  100. X   Schrage's method is used to compute the sequence of z's.
  101. X   Let m = aq + r, where q = m div a, and r = m mod a.
  102. X   Then f(z) = az mod m = az - m * (az div m) =
  103. X         = gamma(z) + m * delta(z)
  104. X   Where gamma(z) = a(z mod q) - r(z div q)
  105. X   and     delta(z) = (z div q) - (az div m)
  106. X
  107. X   If r < q, then for all z in 1, 2, ..., m - 1:
  108. X   (1) delta(z) is either 0 or 1
  109. X   (2) both a(z mod q) and r(z div q) are in 0, 1, ..., m - 1
  110. X   (3) absolute value of gamma(z) <= m - 1
  111. X   (4) delta(z) = 1 iff gamma(z) < 0
  112. X
  113. X   Hence each value of z can be computed exactly without overflow as long
  114. X   as m can be represented as an integer.
  115. X */
  116. X
  117. X/* a good random number generator, correct on any machine with 32 bit
  118. X   integers, this algorithm is from:
  119. X
  120. XStephen K. Park and Keith W. Miller, "Random Number Generators:
  121. X    Good ones are hard to find", Communications of the ACM, October 1988,
  122. X    vol 31, number 10, pp. 1192-1201.
  123. X
  124. X   If this algorithm is implemented correctly, then if z[1] = 1, then
  125. X   z[10001] will equal 1043618065
  126. X
  127. X   Has a full period of 2^31 - 1.
  128. X   Returns integers in the range 1 to 2^31-1.
  129. X */
  130. X
  131. X#define RNG_M 2147483647L  /* m = 2^31 - 1 */
  132. X#define RNG_A 16807L
  133. X#define RNG_Q 127773L       /* m div a */
  134. X#define RNG_R 2836L       /* m mod a */
  135. X
  136. X/* 32 bit seed */
  137. Xstatic long rnd_seed;
  138. X
  139. Xvoid set_rnd_seed (seedval)
  140. Xlong seedval;
  141. X{
  142. X  /* set seed to value between 1 and m-1 */
  143. X
  144. X  rnd_seed = (seedval % (RNG_M - 1)) + 1;
  145. X}
  146. X
  147. X/* returns a pseudo-random number from set 1, 2, ..., RNG_M - 1 */
  148. Xlong rnd()
  149. X{
  150. X  register long low, high, test;
  151. X
  152. X  high = rnd_seed / RNG_Q;
  153. X  low = rnd_seed % RNG_Q;
  154. X  test = RNG_A * low - RNG_R * high;
  155. X  if (test > 0)
  156. X    rnd_seed = test;
  157. X  else
  158. X    rnd_seed = test + RNG_M;
  159. X  return rnd_seed;
  160. X}
  161. SHAR_EOF
  162. chmod 0644 rnd.c || echo "restore of rnd.c fails"
  163. set `wc -c rnd.c`;Sum=$1
  164. if test "$Sum" != "2872"
  165. then echo original size 2872, current size $Sum;fi
  166. fi
  167. if test -f tran.c; then echo "File tran.c exists"; else
  168. echo "x - extracting tran.c (Text)"
  169. sed 's/^X//' << 'SHAR_EOF' > tran.c &&
  170. X/* modified from the original posting, by Carl Ellison, to remove */
  171. X/* the password and therefore keep this from being an encryption program */
  172. X/* The original code was written by setzer@math.ncsu.edu (William Setzer) */
  173. X
  174. X#include <stdio.h>
  175. X
  176. Xextern void set_rnd_seed();
  177. Xextern long rnd();
  178. X
  179. X#define BLOCKSIZE 8192
  180. X
  181. Xlong  perm[BLOCKSIZE];
  182. Xchar buf[BLOCKSIZE];
  183. X
  184. XFILE *my_fopen(file, type)
  185. Xchar *file, *type;
  186. X{
  187. X  FILE *fp;
  188. X
  189. X  if (fp = fopen(file, type))
  190. X    return fp;
  191. X  (void) fprintf(stderr, "Can't open '%s'\n", file);
  192. X  exit(1);
  193. X}
  194. X
  195. Xmain(argc, argv)
  196. Xlong argc;
  197. Xchar **argv;
  198. X{
  199. X  register long i, len;
  200. X  register FILE *infp, *outfp;
  201. X  long savlen, pos, key;
  202. X  char tmp;
  203. X
  204. X  infp  = (argc > 1) ? my_fopen(argv[1], "r") : stdin;
  205. X  outfp = (argc > 2) ? my_fopen(argv[2], "w") : stdout;
  206. X
  207. X  len = fread(buf, 1, BLOCKSIZE, infp);
  208. X  key = lstr2int(buf,len);
  209. X  set_rnd_seed(key);
  210. X
  211. X  do {
  212. X    savlen = len;
  213. X
  214. X    for (i = 0; i < len; i++)
  215. X      perm[i] = i;
  216. X    
  217. X#define swap(A,B)  tmp = A; A = B; B = tmp;
  218. X
  219. X    while (len > 1)
  220. X      {
  221. X    pos = 1 + rnd() % (len - 1);
  222. X    swap( buf[perm[0]], buf[perm[pos]] );
  223. X
  224. X    perm[0]   = perm[(pos == len - 2) ? len - 1 : len - 2];
  225. X    perm[pos] = perm[len - 1];
  226. X    len -= 2;
  227. X      }
  228. X    fwrite(buf, 1, savlen, outfp);
  229. X  } while (len = fread(buf, 1, BLOCKSIZE, infp));
  230. X}
  231. X
  232. X/* Make an integer out of a string.  Do a poor job of it.
  233. X * Note that since this function is called on a block of transposed
  234. X * text and used to construct an "rng key", it mustn't be sensitive
  235. X * to the position of characters  in `str'.
  236. X */
  237. Xlong lstr2int(str,len)
  238. Xchar *str;
  239. Xlong len;
  240. X{
  241. X  long sum = 0;
  242. X  long i ;
  243. X
  244. X  for ( i = 0 ; i < len ; i++ )
  245. X    sum += *str++;
  246. X
  247. X  return sum;
  248. X}
  249. X
  250. SHAR_EOF
  251. chmod 0644 tran.c || echo "restore of tran.c fails"
  252. set `wc -c tran.c`;Sum=$1
  253. if test "$Sum" != "1670"
  254. then echo original size 1670, current size $Sum;fi
  255. fi
  256. exit 0
  257. -- 
  258. -- <<Disclaimer: All opinions expressed are my own, of course.>>
  259. -- Carl Ellison                        cme@sw.stratus.com
  260. -- Stratus Computer Inc.    M3-2-BKW        TEL: (508)460-2783
  261. -- 55 Fairbanks Boulevard ; Marlborough MA 01752-1298    FAX: (508)624-7488
  262.