From 6268a229b1091c361b17028d3d54417190c791e0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sat, 6 Mar 2010 00:03:27 +0200 Subject: [PATCH] nrand48 replacement This is the POSIX linear congruential pseudo-random generator with 48-bits of state. It is non-secure/reproducible and thread-safe. rand() is not thread-safe and *ahem* must not be used in VLC code. rand_r() is thread-safe but obsoleted in POSIX.2008. For secure random numbers, use the slower vlc_rand_bytes(). vlc_rand_bytes() can also be used to generate the seed if you are short on idea for a 48-bits pseudo-random value. --- compat/nrand48.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- include/vlc_fixups.h | 5 +++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 compat/nrand48.c diff --git a/compat/nrand48.c b/compat/nrand48.c new file mode 100644 index 0000000000..9498ef0e62 --- /dev/null +++ b/compat/nrand48.c @@ -0,0 +1,46 @@ +/***************************************************************************** + * nrand48.c: POSIX nrand48() replacement + ***************************************************************************** + * Copyright © 2010 Rémi Denis-Courmont + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * 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 Lesser 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. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +long nrand48 (unsigned short subi[3]) +{ + const uint64_t a = UINT64_C(0x5DEECE66D16); + const unsigned c = 13; + const uint64_t mask = UINT64_C(0xFFFFFFFFFFFF); // 48 bits + + uint64_t x = ((uint64_t)subi[0] << 32) + | ((uint32_t)subi[1] << 16) + | subi[2]; + + x *= a; + x += c; + x &= mask; + + subi[0] = (x >> 32) & 0xFFFF; + subi[1] = (x >> 16) & 0xFFFF; + subi[2] = (x >> 0) & 0XFFFF; + + return x >> 16; +} diff --git a/configure.ac b/configure.ac index 6344b7d601..e100440304 100644 --- a/configure.ac +++ b/configure.ac @@ -548,7 +548,7 @@ need_libc=false dnl Check for usual libc functions AC_CHECK_FUNCS([ctime_r daemon fcntl fdopendir fork getenv getpwuid_r gettimeofday isatty lstat memalign posix_fadvise posix_madvise posix_memalign putenv setenv setlocale stricmp strnicmp tdestroy uselocale]) -AC_REPLACE_FUNCS([asprintf atof atoll getcwd getpid gmtime_r lldiv localtime_r rewind strcasecmp strcasestr strdup strlcpy strncasecmp strndup strnlen strsep strtof strtok_r strtoll swab vasprintf]) +AC_REPLACE_FUNCS([asprintf atof atoll getcwd getpid gmtime_r lldiv localtime_r nrand48 rewind strcasecmp strcasestr strdup strlcpy strncasecmp strndup strnlen strsep strtof strtok_r strtoll swab vasprintf]) AC_CHECK_FUNCS(fdatasync,, [AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.]) ]) diff --git a/include/vlc_fixups.h b/include/vlc_fixups.h index b05c809781..8e24e0f3c1 100644 --- a/include/vlc_fixups.h +++ b/include/vlc_fixups.h @@ -239,4 +239,9 @@ struct pollfd # define tdestroy vlc_tdestroy #endif +/* Random numbers */ +#ifndef HAVE_NRAND48 +long nrand48 (unsigned short subi[3]); +#endif + #endif /* !LIBVLC_FIXUPS_H */ -- 2.39.2