Closed HenrikBengtsson closed 2 years ago
Gist in R:
#' Linear Congruential Generator
#'
#' @return
#' An integer in `{0, 1, ..., modulus-1}`.
#'
#' @reference
#' https://en.wikipedia.org/wiki/Linear_congruential_generator
lcg <- local({
.seed <- NULL
function(modulus = 2^31, a = 1103515245, c = 12345, seed = NULL) {
stopifnot(
length(modulus) == 1L, is.numeric(modulus), !is.na(modulus),
length(a) == 1L, is.numeric(a), !is.na(a),
length(c) == 1L, is.numeric(c), !is.na(c)
)
if (!is.null(seed)) {
stopifnot(length(seed) == 1L, is.numeric(seed), !is.na(seed))
.seed <<- seed
}
if (is.null(.seed)) {
stop("Argument 'seed' must be specified at least once")
}
.seed <<- (a * .seed + c) %% modulus
.seed
}
})
lcg_integer <- function(min, max, seed = NULL) {
stopifnot(
length(min) == 1L, is.numeric(min), !is.na(min),
length(max) == 1L, is.numeric(max), !is.na(max),
min <= max
)
lcg(seed = seed) %% (max - min) + min
}
lcg_port <- function(min = 1024, max = 65535, seed = NULL) {
random_integer(min = min, max = max, seed = seed)
}
## Initiate
> lcg(seed = 42)
[1] 1250496027
## Draw random ports from the LCG RNG stream
> lcg_port()
[1] 4760
> lcg_port()
[1] 7673
Moved to a standalone project: https://github.com/HenrikBengtsson/port4me. The idea is then to either depend on port4me as an external tool, or incorporate it as internal code (100% Bash).
By implementing a good-enough RNG based on Linear Congruential Generator (LCG) we can:
freeport
that is 100% reproducible regardless of language (e.g. Bash, Python, R)With a generic
freeport
tool, we can re-use it here in the RSC, and later for a Jupyter Lab Controller, etc. The user (UID) will be able to produce reproducible pseudo-random port sequences, that can be seeded by both UID and the software label, e.g.($UID, software_id)
and($UID, software_id)
, where we can generate a semi-uniquesoftware_id
from the software label (e.g.rsc
,jlc
, ...) using some basic hash algorithm, e.g. the Java convention (https://github.com/HenrikBengtsson/R.oo/blob/d8cbc39888e996284d5f3d057d0ad96460fd3497/R/hashCode.R#L22-L27)