Add an "initial_seed" option

The initial seed is used by the RNG, and the intended use is to allow
modifying the generated output without otherwise modifying the
configuration, while still being a static, controllable seed that can be
shared between instances if need be.

Thanks to @buherator@infosec.place for the idea!

Signed-off-by: Gergely Nagy <me@gergo.csillger.hu>
This commit is contained in:
Gergely Nagy 2025-01-19 19:16:04 +01:00
parent 663bcf8dba
commit 764cf9afd0
No known key found for this signature in database
4 changed files with 12 additions and 4 deletions

View file

@ -84,9 +84,12 @@ max = 420
min = 2
max = 5
backlink = true
[generator]
initial_seed = ""
```
When configuring through environment variables, these settings are available via `IOCAINE_GENERATOR__MARKOV__PARAGRAPHS__MIN`, `IOCAINE_GENERATOR__MARKOV__PARAGRAPHS_MAX`, `IOCAINE_GENERATOR__MARKOV__WORDS__MIN`, `IOCAINE_GENERATOR__MARKOV__WORDS__MAX`, `IOCAINE_GENERATOR__LINKS__MIN`, `IOCAINE_GENERATOR__LINKS__MAX`, and `IOCAINE_GENERATOR__LINKS__BACKLINK`, respectively.
When configuring through environment variables, these settings are available via `IOCAINE_GENERATOR__MARKOV__PARAGRAPHS__MIN`, `IOCAINE_GENERATOR__MARKOV__PARAGRAPHS_MAX`, `IOCAINE_GENERATOR__MARKOV__WORDS__MIN`, `IOCAINE_GENERATOR__MARKOV__WORDS__MAX`, `IOCAINE_GENERATOR__LINKS__MIN`, `IOCAINE_GENERATOR__LINKS__MAX`, and `IOCAINE_GENERATOR__LINKS__BACKLINK`, `IOCAINE_GENERATOR__INITIAL_SEED` respectively.
## License & copyright

View file

@ -10,4 +10,6 @@ For a number of reasons, `iocaine` uses a different seed for the markov-chain ge
Such seeding, is, of course, not secure. But we do not need security here, we need each page to render in a stable way. If there's a collision, that happens, it's no big deal, we might end up with a mostly identical page - but we'll remain in the infinite maze, nevertheless.
To provide a way to change the generated content without changing any settings or using different sources, it is possible to set an initial seed, which will be factored into the random number generation.
Every page has the same structure: an optional "back" link (which just points to `../`), followed by a number of markov-chain generated paragraphs of various length, and an unordered list of links at the bottom. Each link is relative to the current page, has a random URI, and random text, too.

View file

@ -63,10 +63,11 @@ fn poison(iocaine: &Iocaine, headers: axum::http::HeaderMap, path: &str) -> Html
.unwrap_or(&default_host)
.to_str()
.unwrap();
let initial_seed = &iocaine.config.generator.initial_seed;
// Generate paragraphs
let mut rng = GobbledyGook::for_url(format!("markov://{}/{}", host, path));
let mut rng = GobbledyGook::for_url(format!("markov://{}/{}#{}", host, path, &initial_seed));
let paragraph_count = rng.gen_range(
iocaine.config.generator.markov.paragraphs.min
..=iocaine.config.generator.markov.paragraphs.max,
@ -101,13 +102,13 @@ fn poison(iocaine: &Iocaine, headers: axum::http::HeaderMap, path: &str) -> Html
// Generate links
let mut links = String::new();
let rng = GobbledyGook::for_url(format!("titles://{}/{}", host, path));
let rng = GobbledyGook::for_url(format!("titles://{}/{}#{}", host, path, initial_seed));
let titles = iocaine
.chain
.generate(rng)
.take(iocaine.config.generator.links.max as usize * 5);
let mut rng = GobbledyGook::for_url(format!("links://{}/{}", host, path));
let mut rng = GobbledyGook::for_url(format!("links://{}/{}#{}", host, path, initial_seed));
let link_count =
rng.gen_range(iocaine.config.generator.links.min..=(iocaine.config.generator.links.max));

View file

@ -38,6 +38,8 @@ pub struct GeneratorConfig {
pub markov: MarkovGeneratorConfig,
#[serde(default)]
pub links: LinkGeneratorConfig,
#[serde(default)]
pub initial_seed: String,
}
#[derive(Clone, Debug, Deserialize, Default)]