Necesitará algo que sea correcto por construcción, es decir, una función de permutación:esta es una función que hace un mapeo reversible uno a uno de un número entero (su contador secuencial) a otro. Algunos ejemplos (cualquier combinación de estos también debería trabajo):
- invirtiendo algunos de los bits (por ejemplo, usando un XOR, ^ en PHP)
- intercambiando los lugares de los bits (($i &0xc)>> 2 | ($i &0x3) <<2), o simplemente invirtiendo el orden de todos los bits
- agregando un módulo de valor constante a su rango máximo (debe ser un factor de dos, si está combinando esto con los anteriores)
Ejemplo:esta función convertirá 0, 1, 2, 3, 5, .. en 13, 4, 12, 7, 15, .. para números hasta 15:
$i=($input+97) & 0xf;
$result=((($i&0x1) << 3) + (($i&0xe) >> 1)) ^ 0x5;
EDITAR
Una forma más sencilla sería usar un generador lineal congruente (LCG, que generalmente se usa para generar números aleatorios), que se define mediante una fórmula de la forma:
X_n+1 = (a * X_n + c) mod m
Para buenos valores de a, c y m, la secuencia de X_0, X_1 .. X_m-1 contendrá todos los números entre 0 y m-1 exactamente una vez. Ahora puede comenzar desde un índice que aumenta linealmente y usar el siguiente valor en la secuencia LCG como su clave "secreta".
EDITAR2
Implementación:puede diseñar sus propios parámetros LCG , pero si se equivoca, no cubrirá el rango completo (y por lo tanto tendrá duplicados), así que usaré un conjunto de parámetros publicado y probado aquí de este artículo :
a = 16807, c = 0, m = 2147483647
Esto le da un rango de 2**31. Con pack() puede obtener el entero resultante como una cadena, base64_encode() lo convierte en una cadena legible (de hasta 6 caracteres significativos, 6 bits por byte), por lo que esta podría ser su función:
substr(base64_encode(pack("l", (16807 * $index) % 2147483647)), 0, 6)