Du skal bruge noget, der er korrekt af konstruktion, dvs. en permutationsfunktion:dette er en funktion, der udfører en en-til-en, reversibel mapping af et heltal (din sekventielle tæller) til et andet. Nogle eksempler (enhver kombination af disse bør også arbejde):
- invertering af nogle af bits (f.eks. ved at bruge en XOR, ^ i PHP)
- bytte steder af bits (($i &0xc)>> 2 | ($i &0x3) <<2), eller bare vende rækkefølgen af alle bits
- tilføj en konstant værdi modulo dit maksimale område (skal være en faktor på to, hvis du kombinerer dette med dem ovenfor)
Eksempel:denne funktion konverterer 0, 1, 2, 3, 5, .. til 13, 4, 12, 7, 15, .. for tal op til 15:
$i=($input+97) & 0xf;
$result=((($i&0x1) << 3) + (($i&0xe) >> 1)) ^ 0x5;
REDIGER
En nemmere måde ville være at bruge en lineær kongruential generator (LCG, som normalt bruges til at generere tilfældige tal), som er defineret af en formel på formen:
X_n+1 = (a * X_n + c) mod m
For gode værdier af a, c og m vil sekvensen af X_0, X_1 .. X_m-1 indeholde alle tal mellem 0 og m-1 nøjagtigt én gang. Nu kan du starte fra et lineært stigende indeks og bruge næste værdi i LCG-sekvensen som din "hemmelige" nøgle.
EDIT2
Implementering:Du kan designe dine egne LCG-parametre , men hvis du tager fejl, vil den ikke dække hele rækkevidden (og dermed have dubletter), så jeg vil bruge et offentliggjort og afprøvet sæt parametre her fra dette papir :
a = 16807, c = 0, m = 2147483647
Dette giver dig en rækkevidde på 2**31. Med pack() kan du få det resulterende heltal som en streng, base64_encode() gør det til en læsbar streng (på op til 6 signifikante tegn, 6 bits pr. byte), så dette kunne være din funktion:
substr(base64_encode(pack("l", (16807 * $index) % 2147483647)), 0, 6)