2025-01-12 04:36:52 +08:00

60 lines
1.4 KiB
Plaintext

---
title: "Generating Secure Random Numbers in R"
date: "`r Sys.Date()`"
vignette: >
%\VignetteEngine{knitr::rmarkdown}
%\VignetteIndexEntry{Generating Secure Random Numbers in R}
\usepackage[utf8]{inputenc}
output:
html_document
---
```{r, echo = FALSE, message = FALSE}
knitr::opts_chunk$set(comment = "")
library(openssl)
```
The `rand_bytes` function binds to [RAND_bytes](https://docs.openssl.org/1.1.1/man3/RAND_bytes/) in OpenSSL to generate cryptographically strong pseudo-random bytes. See the OpenSSL documentation for what this means.
```{r}
rnd <- rand_bytes(10)
print(rnd)
```
Bytes are 8 bit and hence can have `2^8 = 256` possible values.
```{r}
as.numeric(rnd)
```
Each random byte can be decomposed into 8 random bits (booleans)
```{r}
x <- rand_bytes(1)
as.logical(rawToBits(x))
```
## Secure Random Numbers
`rand_num` is a simple (2 lines) wrapper to `rand_bytes` to generate random numbers (doubles) between 0 and 1.
```{r}
rand_num(10)
```
To map random draws from [0,1] into a probability density, we can use a [Cumulative Distribution Function](https://en.wikipedia.org/wiki/Cumulative_distribution_function). For example we can combine `qnorm` and `rand_num` to simulate `rnorm`:
```{r}
# Secure rnorm
x <- qnorm(rand_num(1000), mean = 100, sd = 15)
hist(x)
```
Same for discrete distributions:
```{r}
# Secure rbinom
y <- qbinom(rand_num(1000), size = 20, prob = 0.1)
hist(y, breaks = -.5:(max(y)+1))
```