← Back

ofxStringSeedGenerator

github.com/n1ckfg/ofxStringSeedGenerator · @n1ckfg
OF 0.12 Algorithms

Generates choices based on a cryptographic hex seed using the SSoT protocol, with a provenance block documenting the decision-making process.

0 0 Last commit 19d ago Created 19d ago

README

ofxStringSeedGenerator



An openFrameworks port of StringSeedGenerator, an implementation of the SSoT (String Seed of Thought) protocol: every discretionary choice is derived from a cryptographic hex seed with arithmetic anyone can check, and a provenance block records how each choice was made.

Based on Misaki & Akiba (2025), String Seed of Thought: Prompting LLMs for Distribution-Faithful and Diverse Generation, arxiv 2510.21150.

Tested with oF 0.12.1 on macOS.

Usage



#include "ofxStringSeedGenerator.h"

ofxStringSeed ss;
ss.addAxis("shape", { "circle", "square", "triangle" });
ss.addAxis("color", { "red", "blue", "green", "yellow" });

std::string seed = ofxStringSeed::generateSeed(ss.requiredSeedBytes());
auto results = ss.resolve(seed);

for (const auto & r : results) {
	ofLogNotice() << r.axis << " -> " << r.choice << " (index " << r.index << ")";
}
ofLogNotice() << ofxStringSeed::provenance(seed, results);


SSoT provenance
  seed: edc19ab7
  axis 1 (shape, n=3): int(edc1,16)=60865, 60865 % 3 = 1 -> square
  axis 2 (color, n=4): int(9ab7,16)=39607, 39607 % 4 = 3 -> yellow


Any line can be checked from a shell: python3 -c 'print(int("edc1", 16) % 3)'.

API



MethodDescription
static generateSeed(numBytes = 8)Random lower-case hex string from the platform CSPRNG, two characters per byte.
addAxis(name, candidates)Registers an axis. Needs at least 2 candidates; throws std::invalid_argument otherwise. Chainable.
clearAxes(), getAxes()Removes or returns the registered axes.
requiredSeedLength(), requiredSeedBytes()Hex characters or bytes needed for one non-overlapping 4-character slice per axis.
resolve(seed)Returns one Result { axis, hexSlice, intValue, n, index, choice } per axis. Non-hex characters in the seed are ignored.
static provenance(seed, results, meta = {})Provenance block. Meta { piece, version, date } fills the header; empty fields are left out.
static groupedProvenance(seed, results, groupSize, groupLabel, meta)Provenance with axes grouped under labels, e.g. per shape.
static sanitizeSeed(seed), getSlice(seed, i), mapToIndex(slice, n)The individual steps of resolve().
A seed shorter than requiredSeedLength() wraps around, which correlates axes. Use requiredSeedBytes() when generating seeds.

Differences from stringseed.js



Otherwise the output is identical: for the same axes and seed, resolve(), provenance() and groupedProvenance() produce the same text as the JavaScript version, byte for byte.

Example



example/ is a port of the original visual demo (index.html). Five shapes each get six axes (type, color, size, rotation, x and y position) resolved from a 120-character seed, and the provenance block is shown next to the canvas.

The example uses the default GL 2.1 renderer, because its glow shaders are GLSL 1.20.

Get this addon

HTTPS
SSH