60 lines
1.4 KiB
Plaintext
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))
|
||
|
```
|