Będziesz potrzebować czegoś, co jest poprawne konstrukcyjnie, tj. funkcji permutacji:jest to funkcja, która wykonuje odwracalne mapowanie jeden do jednego jednej liczby całkowitej (twojego licznika sekwencyjnego) na drugą. Kilka przykładów (dowolna ich kombinacja powinna również praca):
- odwracanie niektórych bitów (np. za pomocą XOR, ^ w PHP)
- zamienianie miejscami bitów (($i &0xc)>> 2 | ($i &0x3) <<2) lub po prostu odwracanie kolejności wszystkich bitów
- dodanie stałej wartości modulo do maksymalnego zasięgu (musi być współczynnikiem dwa, jeśli łączysz to z powyższymi)
Przykład:ta funkcja przekonwertuje 0, 1, 2, 3, 5, .. na 13, 4, 12, 7, 15, .. dla liczb do 15:
$i=($input+97) & 0xf;
$result=((($i&0x1) << 3) + (($i&0xe) >> 1)) ^ 0x5;
EDYTUJ
Łatwiejszym sposobem byłoby użycie liniowego generatora kongruencji (LCG, który jest zwykle używany do generowania liczb losowych), który jest zdefiniowany wzorem w postaci:
X_n+1 = (a * X_n + c) mod m
Dla dobrych wartości a, c i m, ciąg X_0, X_1 .. X_m-1 będzie zawierał wszystkie liczby od 0 do m-1 dokładnie raz. Teraz możesz zacząć od liniowo rosnącego indeksu i użyć następnego wartość w sekwencji LCG jako "tajny" klucz.
EDYTUJ2
Implementacja:możesz projektować własne parametry LCG , ale jeśli się pomylisz, nie obejmie pełnego zakresu (a zatem będzie miał duplikaty), więc użyję opublikowanego i wypróbowanego zestawu parametrów tutaj z ten artykuł :
a = 16807, c = 0, m = 2147483647
Daje to zakres 2**31. Dzięki pack() możesz uzyskać wynikową liczbę całkowitą jako ciąg, base64_encode() sprawia, że jest to czytelny ciąg (do 6 znaków znaczących, 6 bitów na bajt), więc może to być Twoja funkcja:
substr(base64_encode(pack("l", (16807 * $index) % 2147483647)), 0, 6)