C Implementation to generate Pseudo Random Numbers
From LTwiki-Wiki for LTspice
See http://www.teaser.fr/~amajorel/noise/ and
The Maxim Application Note
/*
* lfsr.c
*/
/*
This file is copyright Andre Majorel 2007-2008.
This program is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published by the
Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <inttypes.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void err (const char *fmt, ...);
int main (int argc, char *argv[])
{
uint32_t r = 0x12345678;
uint32_t tapsmask = 0x80000062;
char output_format = 'h';
/*
* Parse the command line
*/
if (argc == 2 && strcmp (argv[1], "--help") == 0)
{
printf (
"Usage:\n"
" lfsr --help\n"
" lfsr [-bh] [-s num] [-t num]\n"
"Options:\n"
" -b Binary dump in native endianness of state to stdout\n"
" -h Hex dump of state to stdout (this is the default)\n"
" -s num Seed value (default 0x%08lx)\n"
" -t num Taps mask (default 0x%08lx)\n"
, (unsigned long) r
, (unsigned long) tapsmask
);
exit (0);
}
{
int g;
while ((g = getopt (argc, argv, "bhs:t:")) != EOF)
{
if (g == 'b')
output_format = 'b';
else if (g == 'h')
output_format = 'h';
else if (g == 's')
r = strtoul (optarg, NULL, 0); /* FIXME catch errors */
else if (g == 't')
tapsmask = strtoul (optarg, NULL, 0); /* FIXME catch errors */
else if (g == '?')
exit (1);
else
{
err ("unhandled option -%c, report this bug", g);
exit (3);
}
}
}
if (argc > optind)
{
err ("too many arguments, try lfsr --help");
exit (1);
}
/*
* Crunch
*/
fprintf (stderr, "lfsr: seed %08lX\n", (unsigned long) r);
fprintf (stderr, "lfsr: taps mask %08lX\n", (unsigned long) tapsmask);
for (;;)
{
if (output_format == 'h')
{
if (printf ("%08lx\n", (unsigned long) r) < 1)
{
err ("-: write error");
exit (2);
}
}
else if (output_format == 'b')
{
if (fwrite ((char *) &r, sizeof r, 1, stdout) != 1)
{
err ("-: write error");
exit (2);
}
}
if (r & 1)
r = (1 << 31) | ((r ^ tapsmask) >> 1);
else
r >>= 1;
}
return 0;
}
static void err (const char *fmt, ...)
{
va_list argp;
fflush (stdout); /* FIXME catch errors */
fputs ("lfsr: ", stderr); /* FIXME catch errors */
va_start (argp, fmt);
vfprintf (stderr, fmt, argp); /* FIXME catch errors */
va_end (argp);
fputc ('\n', stderr); /* FIXME catch errors */
}