Budete potřebovat něco, co je konstrukčně správné, tj. permutační funkci:je to funkce, která provádí reverzibilní mapování jedna ku jedné z jednoho celého čísla (vašeho sekvenčního čítače) na druhé. Některé příklady (jakákoli jejich kombinace by také měla práce):
- invertování některých bitů (např. pomocí XOR, ^ v PHP)
- záměna míst bitů (($i &0xc)>> 2 | ($i &0x3) <<2), nebo jen obrácení pořadí všech bitů
- přidání konstantní hodnoty modul do vašeho maximálního rozsahu (musí být dvojnásobný, pokud to kombinujete s výše uvedenými)
Příklad:tato funkce převede 0, 1, 2, 3, 5, .. na 13, 4, 12, 7, 15, .. pro čísla do 15:
$i=($input+97) & 0xf;
$result=((($i&0x1) << 3) + (($i&0xe) >> 1)) ^ 0x5;
UPRAVIT
Jednodušší způsob by bylo použití lineárního kongruenciálního generátoru (LCG, který se obvykle používá pro generování náhodných čísel), který je definován vzorcem ve tvaru:
X_n+1 = (a * X_n + c) mod m
Za dobré hodnoty a, c a m, posloupnost X_0, X_1 .. X_m-1 bude obsahovat všechna čísla mezi 0 a m-1 právě jednou. Nyní můžete začít s lineárně rostoucím indexem a použít další hodnotu v sekvenci LCG jako váš „tajný“ klíč.
UPRAVIT2
Implementace:Můžete si navrhnout vlastní parametry LCG , ale pokud se mýlíte, nepokryje to celý rozsah (a tedy budou mít duplikáty), takže použiji publikovanou a vyzkoušenou sadu parametrů zde z tento článek :
a = 16807, c = 0, m = 2147483647
To vám dává rozsah 2**31. Pomocí pack() můžete získat výsledné celé číslo jako řetězec, base64_encode() z něj dělá čitelný řetězec (až 6 platných znaků, 6 bitů na bajt), takže toto by mohla být vaše funkce:
substr(base64_encode(pack("l", (16807 * $index) % 2147483647)), 0, 6)