consideri il primo 3. Per esprimere appieno tutte le uscite possibili, pensare in questo modo ...
bias + step mod prime
Il bias
è solo un pregiudizio offset. step
è un accumulatore (se è 1
ad esempio, sarebbe solo 0, 1, 2
in sequenza, mentre 2
risulterebbe in 0, 2, 4
) e prime
è il numero primo su cui vogliamo generare le permutazioni.
Ad esempio. Una semplice sequenza di 0, 1, 2
sarebbe ...
0 + 0 mod 3 = 0
0 + 1 mod 3 = 1
0 + 2 mod 3 = 2
Modifica di un paio di quelle variabili per un secondo, prenderemo bias
di 1
e step
di 2
(solo per l'illustrazione) ...
1 + 2 mod 3 = 0
1 + 4 mod 3 = 2
1 + 6 mod 3 = 1
Noterete che abbiamo prodotto una sequenza completamente diversa. Nessun numero all'interno del set si ripete e tutti i numeri sono rappresentati (è bidirezionale). Ogni combinazione unica di offset e bias comporterà una delle possibili permutazioni del set di prime!
. Nel caso di un prime
di 3
vedrete che ci sono diversi 6
permuations possibili:
0,1,2
0,2,1
1,0,2
1,2,0
2,0,1
2,1,0
Se fate i conti sulle variabili di cui sopra non sarete che si traduce negli stessi obblighi di informazione .. .
1/3! = 1/6 = 1.66..
... vs ...
1/3 (bias) * 1/2 (step) => 1/6 = 1.66..
Restrizioni sono semplici, bias
deve essere all'interno di 0..P-1
e step
deve essere entro 1..P-1
(mi è stato funzionale solo usando 0..P-2
e aggiungendo 1
sull'aritmetica nel mio lavoro). Oltre a questo, funziona con tutti i numeri primi, non importa quanto grande e permuterà tutti i possibili set di questi senza la necessità di memoria oltre un paio di interi (ognuno richiede tecnicamente meno bit del primo stesso).
Nota con attenzione che questo generatore non è destinato a essere utilizzato per generare insiemi che non sono in numero primo. È del tutto possibile farlo, ma non è raccomandato per scopi di sicurezza in quanto introdurrebbe un attacco di temporizzazione.
Detto questo, se si desidera utilizzare questo metodo per generare una sequenza di insiemi che non è un numero primo, si hanno due scelte.
Primo (e il più semplice/più economico), scegli il numero primo più grande della dimensione impostata che stai cercando e fai in modo che il generatore scarti semplicemente tutto ciò che non appartiene. Ancora una volta, pericolo, questa è una pessima idea se si tratta di un'applicazione sensibile alla sicurezza.
Secondo (di gran lunga il più complicato e costoso), è possibile riconoscere che tutti i numeri sono composti da numeri primi e creano più generatori che quindi producono un prodotto per ciascun elemento dell'insieme. In altre parole, lo 6
n
implicherebbe tutti i possibili generatori di primi che potrebbero corrispondere a 6
(in questo caso, 2
e 3
), moltiplicato in sequenza. Questo è sia costoso (anche se matematicamente più elegante) e presenta anche un attacco di temporizzazione quindi è ancora meno consigliato.
Infine, se è necessario un generatore per bias
eo step
... perché non si utilizza un altro della stessa famiglia :). All'improvviso sei estremamente vicino alla creazione di veri campioni semplici-casuali (che di solito non sono facili).
Come casuale deve essere? Ad esempio, l'enumerazione potrebbe iniziare dallo stesso stato e generare la stessa sequenza come un generatore di numeri casuali "normale" o deve essere diversa ogni volta? – gbulmer
Ho appena scoperto questo articolo: https://en.wikipedia.org/wiki/Pseudorandom_permutation Quindi questo processo di usare una funzione che mappa le chiavi delle permutazioni è chiamato '** permutazione pseudocasuale **', e la domanda è come per selezionare/implementare/utilizzare un algoritmo che implementa tale funzione. L'articolo menziona anche il collegamento tra cifrari a blocchi ideali e permutazione pseudocasuale ideale. –
Un po 'datato ma ho una soluzione per te che non implica "buttare via roba solo perché non abbiamo ottenuto quello che vogliamo" ** iif ** 'N' è primo. Sono molto riluttante a postarlo (dato che sto ancora lavorando a un CSRNG basato sul concetto) ma lo farò come risposta, ma se sei ancora interessato (e le condizioni descritte sopra corrispondono) sarei disposto . –