mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-12 05:59:10 +00:00
Fold LIBC_RAND into LIBC_STDIO/TINYMATH/INTRIN
This commit is contained in:
parent
05b8f82371
commit
8a0a2c0c36
183 changed files with 149 additions and 322 deletions
|
@ -20,6 +20,7 @@
|
|||
#include "libc/errno.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
int __fflush_impl(FILE *f) {
|
||||
|
|
30
libc/stdio/g_rando.S
Normal file
30
libc/stdio/g_rando.S
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.bss
|
||||
.align 8
|
||||
g_rando:
|
||||
.quad 0
|
||||
.endobj g_rando,globl
|
||||
.previous
|
||||
|
||||
.init.start 100,_init_g_rando
|
||||
movb $1,g_rando(%rip)
|
||||
.init.end 100,_init_g_rando
|
28
libc/stdio/getentropy.c
Normal file
28
libc/stdio/getentropy.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
|
||||
/**
|
||||
* Returns random seeding bytes, the XNU/OpenBSD way.
|
||||
* @see getrandom()
|
||||
*/
|
||||
int getentropy(void *buf, size_t size) {
|
||||
return getrandom(buf, size, GRND_RANDOM);
|
||||
}
|
146
libc/stdio/getrandom.c
Normal file
146
libc/stdio/getrandom.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/nexgen32e/kcpuids.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/vendor.internal.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/nexgen32e/x86info.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/xorshift.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static bool have_getrandom;
|
||||
|
||||
/**
|
||||
* Returns cryptographic random data.
|
||||
*
|
||||
* This random number seed generator obtains information from:
|
||||
*
|
||||
* - getrandom() on Linux
|
||||
* - RtlGenRandom() on Windows
|
||||
* - getentropy() on XNU and OpenBSD
|
||||
* - sysctl(KERN_ARND) on FreeBSD and NetBSD
|
||||
*
|
||||
* The following flags may be specified:
|
||||
*
|
||||
* - GRND_RANDOM: Halt the entire system while I tap an entropy pool
|
||||
* so small that it's hard to use statistics to test if it's random
|
||||
* - GRND_NONBLOCK: Do not wait for i/o events or me to jiggle my
|
||||
* mouse, and instead return immediately the moment data isn't
|
||||
* available, even if the result needs to be -1 w/ EAGAIN
|
||||
*
|
||||
* This function is safe to use with fork() and vfork(). It will also
|
||||
* close any file descriptor it ends up needing before it returns.
|
||||
*
|
||||
* @note this function could block a nontrivial time on old computers
|
||||
* @note this function is indeed intended for cryptography
|
||||
* @note this function takes around 900 cycles
|
||||
* @asyncsignalsafe
|
||||
* @restartable
|
||||
* @vforksafe
|
||||
*/
|
||||
ssize_t getrandom(void *p, size_t n, unsigned f) {
|
||||
char cf;
|
||||
ssize_t rc;
|
||||
uint64_t x;
|
||||
int fd, cmd[2];
|
||||
size_t i, j, m;
|
||||
const char *via;
|
||||
sigset_t neu, old;
|
||||
if (n > 256) n = 256;
|
||||
if ((f & ~(GRND_RANDOM | GRND_NONBLOCK))) return einval();
|
||||
if (IsWindows()) {
|
||||
via = "RtlGenRandom";
|
||||
if (RtlGenRandom(p, n)) {
|
||||
rc = n;
|
||||
} else {
|
||||
rc = __winerr();
|
||||
}
|
||||
} else if (IsFreebsd() || IsNetbsd()) {
|
||||
via = "KERN_ARND";
|
||||
if (IsFreebsd()) {
|
||||
cmd[0] = 1; /* CTL_KERN */
|
||||
cmd[1] = 37; /* KERN_ARND */
|
||||
} else {
|
||||
cmd[0] = 1; /* CTL_KERN */
|
||||
cmd[1] = 81; /* KERN_ARND */
|
||||
}
|
||||
m = n;
|
||||
if ((rc = sysctl(cmd, 2, p, &m, 0, 0)) != -1) {
|
||||
rc = m;
|
||||
}
|
||||
} else if (have_getrandom) {
|
||||
via = "getrandom";
|
||||
if ((rc = sys_getrandom(p, n, f & (GRND_RANDOM | GRND_NONBLOCK))) != -1) {
|
||||
if (!rc && (IsXnu() || IsOpenbsd())) {
|
||||
rc = n;
|
||||
}
|
||||
}
|
||||
} else if ((fd = __sys_openat(
|
||||
AT_FDCWD,
|
||||
(via = (f & GRND_RANDOM) ? "/dev/random" : "/dev/urandom"),
|
||||
O_RDONLY | ((f & GRND_NONBLOCK) ? O_NONBLOCK : 0), 0)) !=
|
||||
-1) {
|
||||
rc = sys_read(fd, p, n);
|
||||
sys_close(fd);
|
||||
} else {
|
||||
rc = enosys();
|
||||
}
|
||||
STRACE("getrandom(%p, %'zu, %#x) via %s → %'ld% m", p, n, f, via, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static textstartup void getrandom_init(void) {
|
||||
int e, rc;
|
||||
e = errno;
|
||||
struct sigaction sa, oldsa;
|
||||
if (IsBsd()) {
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaction(SIGSYS, &sa, &oldsa);
|
||||
}
|
||||
if (!(rc = sys_getrandom(0, 0, 0))) {
|
||||
have_getrandom = true;
|
||||
}
|
||||
STRACE("sys_getrandom(0,0,0) → %d% m", rc);
|
||||
if (IsBsd()) {
|
||||
sigaction(SIGSYS, &oldsa, 0);
|
||||
}
|
||||
errno = e;
|
||||
}
|
||||
|
||||
const void *const g_getrandom_init[] initarray = {getrandom_init};
|
|
@ -11,6 +11,8 @@ extern char g_stdinbuf[BUFSIZ];
|
|||
extern char g_stdoutbuf[BUFSIZ];
|
||||
extern char g_stderrbuf[BUFSIZ];
|
||||
|
||||
hidden extern uint64_t g_rando;
|
||||
|
||||
int __fflush_impl(FILE *) hidden;
|
||||
int __fflush_register(FILE *) hidden;
|
||||
void __fflush_unregister(FILE *) hidden;
|
||||
|
|
14
libc/stdio/lcg.internal.h
Normal file
14
libc/stdio/lcg.internal.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LCG_H_
|
||||
#define COSMOPOLITAN_LIBC_LCG_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline uint64_t KnuthLinearCongruentialGenerator(uint64_t prev[1]) {
|
||||
/* Knuth, D.E., "The Art of Computer Programming," Vol 2,
|
||||
Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998,
|
||||
p. 106 (line 26) & p. 108 */
|
||||
prev[0] = prev[0] * 6364136223846793005 + 1442695040888963407;
|
||||
return prev[0]; /* be sure to shift! */
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LCG_H_ */
|
45
libc/stdio/lemur64.c
Normal file
45
libc/stdio/lemur64.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
/**
|
||||
* Returns linear congruential deterministic pseudorandom data, e.g.
|
||||
*
|
||||
* uint64_t x = lemur64();
|
||||
*
|
||||
* You can generate different types of numbers as follows:
|
||||
*
|
||||
* int64_t x = lemur64() >> 1; // make positive signed integer
|
||||
* double x = _real1(lemur64()); // make float on [0,1]-interval
|
||||
*
|
||||
* If you want a fast pseudorandom number generator that seeds itself
|
||||
* automatically on startup and fork() then consider rand64(). If you
|
||||
* want true random data then consider rdseed, rdrand, and getrandom.
|
||||
*
|
||||
* @return 64 bits of pseudorandom data
|
||||
* @note this is Lemire's Lehmer generator
|
||||
* @note this function takes at minimum 1 cycle
|
||||
* @note this function passes bigcrush and practrand
|
||||
* @note this function is not intended for cryptography
|
||||
* @see rand64(), rngset(), _real1(), _real2(), _real3()
|
||||
*/
|
||||
uint64_t lemur64(void) {
|
||||
static uint128_t s = 2131259787901769494;
|
||||
return (s *= 15750249268501108917ull) >> 64;
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/temp.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/rand/lcg.internal.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/stdio/lcg.internal.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/temp.h"
|
||||
#include "libc/str/str.h"
|
||||
|
|
146
libc/stdio/mt19937.c
Normal file
146
libc/stdio/mt19937.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ │
|
||||
│ Copyright (C) 2004, Makoto Matsumoto and Takuji Nishimura, │
|
||||
│ All rights reserved. │
|
||||
│ │
|
||||
│ Redistribution and use in source and binary forms, with or without │
|
||||
│ modification, are permitted provided that the following conditions │
|
||||
│ are met: │
|
||||
│ │
|
||||
│ 1. Redistributions of source code must retain the above copyright │
|
||||
│ notice, this list of conditions and the following disclaimer. │
|
||||
│ │
|
||||
│ 2. Redistributions in binary form must reproduce the above │
|
||||
│ copyright notice, this list of conditions and the following │
|
||||
│ disclaimer in the documentation and/or other materials │
|
||||
│ provided with the distribution. │
|
||||
│ │
|
||||
│ 3. The names of its contributors may not be used to endorse or │
|
||||
│ promote products derived from this software without specific │
|
||||
│ prior written permission. │
|
||||
│ │
|
||||
│ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS │
|
||||
│ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT │
|
||||
│ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR │
|
||||
│ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT │
|
||||
│ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, │
|
||||
│ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT │
|
||||
│ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, │
|
||||
│ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY │
|
||||
│ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT │
|
||||
│ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE │
|
||||
│ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/likely.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
mt19937 (BSD-3)\\n\
|
||||
Copyright 1997-2004 Makoto Matsumoto and Takuji Nishimura\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/*
|
||||
* A C-program for MT19937-64 (2004/9/29 version).
|
||||
* Coded by Takuji Nishimura and Makoto Matsumoto.
|
||||
*
|
||||
* This is a 64-bit version of Mersenne Twister pseudorandom number
|
||||
* generator.
|
||||
*
|
||||
* Before using, initialize the state by using init_genrand64(seed)
|
||||
* or init_by_array64(init_key, key_length).
|
||||
*
|
||||
* References:
|
||||
* T. Nishimura, ``Tables of 64-bit Mersenne Twisters''
|
||||
* ACM Transactions on Modeling and
|
||||
* Computer Simulation 10. (2000) 348--357.
|
||||
* M. Matsumoto and T. Nishimura,
|
||||
* ``Mersenne Twister: a 623-dimensionally equidistributed
|
||||
* uniform pseudorandom number generator''
|
||||
* ACM Transactions on Modeling and
|
||||
* Computer Simulation 8. (Jan. 1998) 3--30.
|
||||
*
|
||||
* Any feedback is very welcome.
|
||||
* http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||
* email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces)
|
||||
*/
|
||||
|
||||
#define NN 312
|
||||
#define MM 156
|
||||
#define LM 0x7fffffff
|
||||
#define UM 0xffffffff80000000
|
||||
|
||||
static int mti = NN + 1;
|
||||
static uint64_t mt[NN];
|
||||
static const uint64_t mag01[2] = {0, 0xb5026f5aa96619e9};
|
||||
|
||||
/**
|
||||
* Initializes mt[NN] with small seed value.
|
||||
*
|
||||
* @see mt19937(), Smt19937()
|
||||
*/
|
||||
void _smt19937(uint64_t seed) {
|
||||
mt[0] = seed;
|
||||
for (mti = 1; mti < NN; mti++) {
|
||||
mt[mti] = 0x5851f42d4c957f2d * (mt[mti - 1] ^ (mt[mti - 1] >> 62)) + mti;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes mt[NN] with array.
|
||||
*
|
||||
* @param K is the array for initializing keys
|
||||
* @param n is its length
|
||||
* @see mt19937(), smt19937()
|
||||
*/
|
||||
void _Smt19937(uint64_t K[], size_t n) {
|
||||
size_t i, j, k;
|
||||
_smt19937(19650218);
|
||||
for (i = 1, j = 0, k = MAX(NN, n); k; k--) {
|
||||
mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * 0x369dea0f31a53f85)) +
|
||||
K[j] + j;
|
||||
if (++i >= NN) mt[0] = mt[NN - 1], i = 1;
|
||||
if (++j >= n) j = 0;
|
||||
}
|
||||
for (k = NN - 1; k; k--) {
|
||||
mt[i] =
|
||||
(mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * 0x27bb2ee687b0b0fd)) - i;
|
||||
if (++i >= NN) mt[0] = mt[NN - 1], i = 1;
|
||||
}
|
||||
mt[0] = 0x8000000000000000; /* assures non-zero initial array */
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates random integer on [0, 2^64)-interval.
|
||||
*
|
||||
* This uses the Mersenne Twister pseudorandom number generator.
|
||||
*
|
||||
* @see smt19937(), Smt19937()
|
||||
*/
|
||||
uint64_t _mt19937(void) {
|
||||
int i;
|
||||
uint64_t x;
|
||||
if (mti >= NN) {
|
||||
if (mti == NN + 1) _smt19937(5489);
|
||||
for (i = 0; i < NN - MM; i++) {
|
||||
x = (mt[i] & UM) | (mt[i + 1] & LM);
|
||||
mt[i] = mt[i + MM] ^ (x >> 1) ^ mag01[x & 1];
|
||||
}
|
||||
for (; i < NN - 1; i++) {
|
||||
x = (mt[i] & UM) | (mt[i + 1] & LM);
|
||||
mt[i] = mt[i + (MM - NN)] ^ (x >> 1) ^ mag01[x & 1];
|
||||
}
|
||||
x = (mt[NN - 1] & UM) | (mt[0] & LM);
|
||||
mt[NN - 1] = mt[MM - 1] ^ (x >> 1) ^ mag01[x & 1];
|
||||
mti = 0;
|
||||
}
|
||||
x = mt[mti++];
|
||||
x ^= (x >> 29) & 0x5555555555555555;
|
||||
x ^= (x << 17) & 0x71d67fffeda60000;
|
||||
x ^= (x << 37) & 0xfff7eee000000000;
|
||||
x ^= (x >> 43);
|
||||
return x;
|
||||
}
|
42
libc/stdio/rand.c
Normal file
42
libc/stdio/rand.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/internal.h"
|
||||
#include "libc/stdio/lcg.internal.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
/**
|
||||
* Returns 31-bit linear congruential pseudorandom number, e.g.
|
||||
*
|
||||
* int x = rand();
|
||||
* assert(x >= 0);
|
||||
*
|
||||
* This function always returns a positive number. If srand() isn't
|
||||
* called, then it'll return the same sequence each time your program
|
||||
* runs. Faster and more modern alternatives exist to this function.
|
||||
*
|
||||
* This function is not thread safe in the sense that multiple threads
|
||||
* might simultaneously generate the same random values.
|
||||
*
|
||||
* @note this function does well on bigcrush and practrand
|
||||
* @note this function is not intended for cryptography
|
||||
* @see lemur64(), rand64(), rdrand()
|
||||
*/
|
||||
int rand(void) {
|
||||
return KnuthLinearCongruentialGenerator(&g_rando) >> 33;
|
||||
}
|
43
libc/stdio/rand.h
Normal file
43
libc/stdio/rand.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_RAND_RAND_H_
|
||||
#define COSMOPOLITAN_LIBC_RAND_RAND_H_
|
||||
#define RAND_MAX __INT_MAX__
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § random ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
int rand(void);
|
||||
void srand(uint64_t);
|
||||
double poz(double);
|
||||
double pochisq(double, int);
|
||||
void rt_init(int);
|
||||
void rt_add(void *, int);
|
||||
void rt_end(double *, double *, double *, double *, double *);
|
||||
char *strfry(char *);
|
||||
int getentropy(void *, size_t);
|
||||
ssize_t getrandom(void *, size_t, unsigned);
|
||||
char *initstate(unsigned, char *, size_t);
|
||||
char *setstate(char *);
|
||||
long random(void);
|
||||
void srandom(unsigned);
|
||||
|
||||
uint64_t lemur64(void);
|
||||
uint64_t rand64(void);
|
||||
uint64_t vigna(void);
|
||||
uint64_t vigna_r(uint64_t[hasatleast 1]);
|
||||
void svigna(uint64_t);
|
||||
uint64_t rdrand(void);
|
||||
uint64_t rdseed(void);
|
||||
void _smt19937(uint64_t);
|
||||
void _Smt19937(uint64_t[], size_t);
|
||||
uint64_t _mt19937(void);
|
||||
double _real1(uint64_t);
|
||||
double _real2(uint64_t);
|
||||
double _real3(uint64_t);
|
||||
double MeasureEntropy(const char *, size_t);
|
||||
void *rngset(void *, size_t, uint64_t (*)(void), size_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_RAND_RAND_H_ */
|
0
libc/stdio/rand.mk
Executable file
0
libc/stdio/rand.mk
Executable file
128
libc/stdio/random.c
Normal file
128
libc/stdio/random.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
Copyright 2005-2014 Rich Felker, et. al.\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/*
|
||||
* this code uses the same lagged fibonacci generator as the
|
||||
* original bsd random implementation except for the seeding
|
||||
* which was broken in the original
|
||||
*/
|
||||
|
||||
static uint32_t init[] = {
|
||||
0x00000000, 0x5851f42d, 0xc0b18ccf, 0xcbb5f646, 0xc7033129, 0x30705b04,
|
||||
0x20fd5db4, 0x9a8b7f78, 0x502959d8, 0xab894868, 0x6c0356a7, 0x88cdb7ff,
|
||||
0xb477d43f, 0x70a3a52b, 0xa8e4baf1, 0xfd8341fc, 0x8ae16fd9, 0x742d2f7a,
|
||||
0x0d1f0796, 0x76035e09, 0x40f7702c, 0x6fa72ca5, 0xaaa84157, 0x58a0df74,
|
||||
0xc74a0364, 0xae533cc4, 0x04185faf, 0x6de3b115, 0x0cab8628, 0xf043bfa4,
|
||||
0x398150e9, 0x37521657,
|
||||
};
|
||||
|
||||
static int n = 31;
|
||||
static int i = 3;
|
||||
static int j = 0;
|
||||
static uint32_t *x = init + 1;
|
||||
|
||||
static uint32_t lcg31(uint32_t x) {
|
||||
return (1103515245 * x + 12345) & 0x7fffffff;
|
||||
}
|
||||
|
||||
static uint64_t lcg64(uint64_t x) {
|
||||
return 6364136223846793005ull * x + 1;
|
||||
}
|
||||
|
||||
static void *savestate(void) {
|
||||
x[-1] = (n << 16) | (i << 8) | j;
|
||||
return x - 1;
|
||||
}
|
||||
|
||||
static void loadstate(uint32_t *state) {
|
||||
x = state + 1;
|
||||
n = x[-1] >> 16;
|
||||
i = (x[-1] >> 8) & 0xff;
|
||||
j = x[-1] & 0xff;
|
||||
}
|
||||
|
||||
void srandom(unsigned seed) {
|
||||
int k;
|
||||
uint64_t s = seed;
|
||||
if (!n) {
|
||||
x[0] = s;
|
||||
return;
|
||||
}
|
||||
i = n == 31 || n == 7 ? 3 : 1;
|
||||
j = 0;
|
||||
for (k = 0; k < n; k++) {
|
||||
s = lcg64(s);
|
||||
x[k] = s >> 32;
|
||||
}
|
||||
/* make sure x contains at least one odd number */
|
||||
x[0] |= 1;
|
||||
}
|
||||
|
||||
char *initstate(unsigned seed, char *state, size_t size) {
|
||||
void *old;
|
||||
if (size < 8) return 0;
|
||||
old = savestate();
|
||||
if (size < 32) {
|
||||
n = 0;
|
||||
} else if (size < 64) {
|
||||
n = 7;
|
||||
} else if (size < 128) {
|
||||
n = 15;
|
||||
} else if (size < 256) {
|
||||
n = 31;
|
||||
} else {
|
||||
n = 63;
|
||||
}
|
||||
x = (uint32_t *)state + 1;
|
||||
srandom(seed);
|
||||
savestate();
|
||||
return old;
|
||||
}
|
||||
|
||||
char *setstate(char *state) {
|
||||
void *old;
|
||||
old = savestate();
|
||||
loadstate((uint32_t *)state);
|
||||
return old;
|
||||
}
|
||||
|
||||
long random(void) {
|
||||
long k;
|
||||
if (!n) return (x[0] = lcg31(x[0]));
|
||||
x[i] += x[j];
|
||||
k = x[i] >> 1;
|
||||
if (++i == n) i = 0;
|
||||
if (++j == n) j = 0;
|
||||
return k;
|
||||
}
|
81
libc/stdio/rdrand.c
Normal file
81
libc/stdio/rdrand.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/asmflag.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
|
||||
STATIC_YOINK("rdrand_init");
|
||||
|
||||
static dontinline uint64_t rdrand_failover(void) {
|
||||
int f;
|
||||
size_t i;
|
||||
ssize_t r;
|
||||
volatile uint64_t b;
|
||||
register uint64_t x;
|
||||
for (f = GRND_RANDOM | GRND_NONBLOCK, i = 0; i < 8; i += r) {
|
||||
if ((r = getrandom((char *)&b + i, 8 - i, f)) <= 0) {
|
||||
if (r == -1 && errno == EINTR) {
|
||||
r = 0;
|
||||
} else if (r == -1 && errno == EAGAIN) {
|
||||
r = 0;
|
||||
f = 0;
|
||||
} else {
|
||||
return rand64();
|
||||
}
|
||||
}
|
||||
}
|
||||
x = b;
|
||||
b = 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves 64-bits of hardware random data from RDRAND instruction.
|
||||
*
|
||||
* If RDRAND isn't available (we check CPUID and we also disable it
|
||||
* automatically for microarchitectures where it's slow or buggy) then
|
||||
* we try getrandom(), RtlGenRandom(), or sysctl(KERN_ARND). If those
|
||||
* aren't available then we try /dev/urandom and if that fails, we try
|
||||
* getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid().
|
||||
*
|
||||
* @note this function could block a nontrivial time on old computers
|
||||
* @note this function is indeed intended for cryptography
|
||||
* @note this function takes around 300 cycles
|
||||
* @see rngset(), rdseed(), rand64()
|
||||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
uint64_t rdrand(void) {
|
||||
int i;
|
||||
char cf;
|
||||
uint64_t x;
|
||||
if (X86_HAVE(RDRND)) {
|
||||
for (i = 0; i < 10; ++i) {
|
||||
asm volatile(CFLAG_ASM("rdrand\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) return x;
|
||||
asm volatile("pause");
|
||||
}
|
||||
}
|
||||
return rdrand_failover();
|
||||
}
|
43
libc/stdio/rdrand_init.c
Normal file
43
libc/stdio/rdrand_init.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/kcpuids.h"
|
||||
#include "libc/nexgen32e/vendor.internal.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/nexgen32e/x86info.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
textstartup void rdrand_init(int argc, char **argv, char **envp,
|
||||
intptr_t *auxv) {
|
||||
extern unsigned kMutableCpuids[KCPUIDS_LEN][4] asm("kCpuids");
|
||||
/*
|
||||
* Clear RDRAND on AMD models before Zen and then some
|
||||
* since it's not only slow but can freeze after sleep
|
||||
* https://bugzilla.redhat.com/show_bug.cgi?id=1150286
|
||||
*/
|
||||
if ((X86_HAVE(RDRND) || X86_HAVE(RDSEED)) &&
|
||||
(IsAuthenticAMD() &&
|
||||
(kX86CpuFamily < 0x17 ||
|
||||
(kX86CpuFamily == 0x17 &&
|
||||
(0x70 <= kX86CpuModel && kX86CpuModel <= 0x7F))))) {
|
||||
kMutableCpuids[KCPUIDS_1H][KCPUIDS_ECX] &= ~(1u << 30);
|
||||
kMutableCpuids[KCPUIDS_7H][KCPUIDS_EBX] &= ~(1u << 18);
|
||||
}
|
||||
}
|
||||
|
||||
const void *const g_rdrand_init[] initarray = {rdrand_init};
|
56
libc/stdio/rdseed.c
Normal file
56
libc/stdio/rdseed.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/asmflag.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
|
||||
/**
|
||||
* Retrieves 64-bits of true random data from RDSEED instruction.
|
||||
*
|
||||
* If RDSEED isn't available, we'll try RDRAND (which we automatically
|
||||
* disable for microarchitectures where it's known to be slow or buggy).
|
||||
* If RDRAND isn't available then we try getrandom(), RtlGenRandom(), or
|
||||
* sysctl(KERN_ARND). If those aren't available then we try /dev/urandom
|
||||
* and if that fails, we use RDTSC and getpid().
|
||||
*
|
||||
* @note this function could block a nontrivial time on old computers
|
||||
* @note this function is indeed intended for cryptography
|
||||
* @note this function takes around 800 cycles
|
||||
* @see rngset(), rdrand(), rand64()
|
||||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
uint64_t rdseed(void) {
|
||||
int i;
|
||||
char cf;
|
||||
uint64_t x;
|
||||
if (X86_HAVE(RDSEED)) {
|
||||
for (i = 0; i < 10; ++i) {
|
||||
asm volatile(CFLAG_ASM("rdseed\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) return x;
|
||||
asm volatile("pause");
|
||||
}
|
||||
}
|
||||
return rdrand();
|
||||
}
|
30
libc/stdio/real1.c
Normal file
30
libc/stdio/real1.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
/**
|
||||
* Generates number on [0,1]-real-interval, e.g.
|
||||
*
|
||||
* double x = _real1(lemur64())
|
||||
*
|
||||
* @see lemur64(), mt19937()
|
||||
*/
|
||||
double _real1(uint64_t x) {
|
||||
return 1. / 9007199254740991. * (x >> 11);
|
||||
}
|
30
libc/stdio/real2.c
Normal file
30
libc/stdio/real2.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
/**
|
||||
* Generates number on [0,1)-real-interval, e.g.
|
||||
*
|
||||
* double x = _real2(lemur64())
|
||||
*
|
||||
* @see lemur64(), mt19937()
|
||||
*/
|
||||
double _real2(uint64_t x) {
|
||||
return 1. / 9007199254740992. * (x >> 11);
|
||||
}
|
30
libc/stdio/real3.c
Normal file
30
libc/stdio/real3.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
/**
|
||||
* Generates number on (0,1)-real-interval, e.g.
|
||||
*
|
||||
* double x = _real3(lemur64())
|
||||
*
|
||||
* @see lemur64(), mt19937()
|
||||
*/
|
||||
double _real3(uint64_t x) {
|
||||
return 1. / 4503599627370496. * ((x >> 12) + .5);
|
||||
}
|
94
libc/stdio/rngset.c
Normal file
94
libc/stdio/rngset.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
* Fills memory with random bytes, e.g.
|
||||
*
|
||||
* char buf[512];
|
||||
* rngset(buf, sizeof(buf), 0, 0);
|
||||
*
|
||||
* If reseed is zero then the internal PRNG is disabled and bytes are
|
||||
* simply copied in little-endian order from the seed function. If seed
|
||||
* is NULL then the reseed parameter is used as the seed value for the
|
||||
* internal PRNG. If seed!=NULL and reseed>8 then reseed is the number
|
||||
* of bytes after which the seed() function should be called again, to
|
||||
* freshen up the PRNG.
|
||||
*
|
||||
* The main advantage of this generator is that it produces data at 13
|
||||
* gigabytes per second since Vigna's Algorithm vectorizes better than
|
||||
* alternatives, going even faster than xorshift.
|
||||
*
|
||||
* @return original buf
|
||||
*/
|
||||
noasan void *rngset(void *b, size_t n, uint64_t seed(void), size_t reseed) {
|
||||
size_t m;
|
||||
uint64_t i, x, t = 0;
|
||||
unsigned char *p = b;
|
||||
if (IsAsan()) {
|
||||
__asan_verify(b, n);
|
||||
}
|
||||
if (!seed) {
|
||||
t = reseed;
|
||||
reseed = -1;
|
||||
} else if (reseed < 8) {
|
||||
reseed = 8;
|
||||
}
|
||||
while (n) {
|
||||
if (seed) t = seed();
|
||||
if (!seed || reseed > 8) {
|
||||
n -= (m = reseed < n ? reseed : n);
|
||||
while (m >= 8) {
|
||||
x = (t += 0x9e3779b97f4a7c15);
|
||||
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
|
||||
x = (x ^ (x >> 31));
|
||||
__builtin_memcpy(p, &x, 8);
|
||||
p += 8;
|
||||
m -= 8;
|
||||
}
|
||||
while (m--) {
|
||||
*p++ = t;
|
||||
t >>= 8;
|
||||
}
|
||||
} else if (n >= 8) {
|
||||
p[0] = (0x00000000000000FF & t) >> 000;
|
||||
p[1] = (0x000000000000FF00 & t) >> 010;
|
||||
p[2] = (0x0000000000FF0000 & t) >> 020;
|
||||
p[3] = (0x00000000FF000000 & t) >> 030;
|
||||
p[4] = (0x000000FF00000000 & t) >> 040;
|
||||
p[5] = (0x0000FF0000000000 & t) >> 050;
|
||||
p[6] = (0x00FF000000000000 & t) >> 060;
|
||||
p[7] = (0xFF00000000000000 & t) >> 070;
|
||||
p += 8;
|
||||
n -= 8;
|
||||
} else {
|
||||
while (n) {
|
||||
*p++ = t;
|
||||
t >>= 8;
|
||||
--n;
|
||||
}
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
26
libc/stdio/srand.c
Normal file
26
libc/stdio/srand.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
extern uint64_t g_rando;
|
||||
|
||||
/**
|
||||
* Seeds random number generator that's used by rand().
|
||||
*/
|
||||
void(srand)(uint64_t seed) { g_rando = seed; }
|
|
@ -29,8 +29,8 @@ LIBC_STDIO_A_DIRECTDEPS = \
|
|||
LIBC_INTRIN \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
|
@ -57,6 +57,10 @@ o//libc/stdio/appendw.o: private \
|
|||
OVERRIDE_CFLAGS += \
|
||||
-Os
|
||||
|
||||
o/$(MODE)/libc/stdio/mt19937.o: private \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-ffunction-sections
|
||||
|
||||
LIBC_STDIO_LIBS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)))
|
||||
LIBC_STDIO_SRCS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_STDIO_HDRS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_HDRS))
|
||||
|
|
29
libc/stdio/strfry.c
Normal file
29
libc/stdio/strfry.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/shuffle.internal.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Jumbles up string.
|
||||
*/
|
||||
char *strfry(char *s) {
|
||||
shuffle(rand, s, strlen(s));
|
||||
return s;
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/temp.h"
|
||||
#include "libc/str/str.h"
|
||||
|
|
78
libc/stdio/vigna.c
Normal file
78
libc/stdio/vigna.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/rand.h"
|
||||
|
||||
static uint64_t g_vigna;
|
||||
|
||||
/**
|
||||
* Returns deterministic pseudorandom data, e.g.
|
||||
*
|
||||
* uint64_t x = vigna();
|
||||
*
|
||||
* You can generate different types of numbers as follows:
|
||||
*
|
||||
* int64_t x = vigna() >> 1; // make positive signed integer
|
||||
* double x = _real1(vigna()); // make float on [0,1]-interval
|
||||
*
|
||||
* You can seed this random number generator using:
|
||||
*
|
||||
* svigna(rdseed());
|
||||
*
|
||||
* You may use the reentrant version of this function:
|
||||
*
|
||||
* static uint64_t s = 0;
|
||||
* uint64_t x = svigna_r(&s);
|
||||
*
|
||||
* If you want to fill a buffer with data then rngset() implements
|
||||
* vigna's algorithm to do that extremely well:
|
||||
*
|
||||
* char buf[4096];
|
||||
* rngset(buf, sizeof(buf), vigna, 0);
|
||||
*
|
||||
* If you want a fast pseudorandom number generator that seeds itself
|
||||
* automatically on startup and fork() then consider rand64(). If you
|
||||
* want true random data then consider rdseed, rdrand, and getrandom.
|
||||
*
|
||||
* @return 64 bits of pseudorandom data
|
||||
* @note this function is not intended for cryptography
|
||||
* @note this function passes bigcrush and practrand
|
||||
* @note this function takes at minimum 4 cycles
|
||||
*/
|
||||
uint64_t vigna(void) {
|
||||
return vigna_r(&g_vigna);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns pseudorandom data.
|
||||
* @see vigna() for easy api
|
||||
*/
|
||||
uint64_t vigna_r(uint64_t state[hasatleast 1]) {
|
||||
uint64_t z = (state[0] += 0x9e3779b97f4a7c15);
|
||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seeds vigna() pseudorandom number generator.
|
||||
* @see vigna(), vigna_r()
|
||||
*/
|
||||
void svigna(uint64_t seed) {
|
||||
g_vigna = seed;
|
||||
}
|
15
libc/stdio/xorshift.h
Normal file
15
libc/stdio/xorshift.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_RAND_XORSHIFT_H_
|
||||
#define COSMOPOLITAN_LIBC_RAND_XORSHIFT_H_
|
||||
|
||||
#define kMarsagliaXorshift64Seed 88172645463325252
|
||||
#define kMarsagliaXorshift32Seed 2463534242
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
uint32_t MarsagliaXorshift32(uint32_t[hasatleast 1]);
|
||||
uint64_t MarsagliaXorshift64(uint64_t[hasatleast 1]);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_RAND_XORSHIFT_H_ */
|
28
libc/stdio/xorshift32.c
Normal file
28
libc/stdio/xorshift32.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/xorshift.h"
|
||||
|
||||
uint32_t MarsagliaXorshift32(uint32_t state[hasatleast 1]) {
|
||||
uint32_t x = state[0];
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
state[0] = x;
|
||||
return x;
|
||||
}
|
28
libc/stdio/xorshift64.c
Normal file
28
libc/stdio/xorshift64.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/xorshift.h"
|
||||
|
||||
uint64_t MarsagliaXorshift64(uint64_t state[hasatleast 1]) {
|
||||
uint64_t x = state[0];
|
||||
x ^= x << 13;
|
||||
x ^= x >> 7;
|
||||
x ^= x << 17;
|
||||
state[0] = x;
|
||||
return x;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue