2016-07-06 25 views
5

Ho bisogno di generare ID univoci per più frasi in una narrazione più lunga (in cui più utenti possono eseguire la stessa azione, allo stesso tempo, su macchine diverse).Genera e concatena 3 valori Math.random() più casuali di 1 valore Math.random()?

ho pensato di fare new Date().getTime() (e, forse, concatenando una username), ma come gli id ​​sono stati generati in un ciclo, mentre l'iterazione di frasi, ho trovato i duplicati sono stati creati (come generazione potrebbe avvenire allo stesso millisecondo).

Così Attualmente sto giocando intorno con:

var random1 = Math.floor((Math.random() * 10000) + 1).toString(36); 
var random2 = Math.floor((Math.random() * 10000) + 1); 
var random3 = Math.floor((Math.random() * 10000) + 1); 
var id = random1 + random2 + random3; 
// generates things like: 
// 1h754278042 
// 58o83798349 
// 3ls28055962 

Mi venne in mente anche se (è vero, come qualcuno che non ha riflettuto/casuali questioni di crittografia/unici molto), che forse unendo tre numeri casuali isn' t più casuale di un numero casuale?

È la generazione e il concatenamento di 3 valori Math.random() più casuali rispetto al valore 1 Math.random()?

questa risposta (https://security.stackexchange.com/a/124003) afferma:

Se il generatore di numeri casuali davvero produce dati casuali, allora non lo farà materia.

Ma non sono sicuro di come si applica l'utilizzo di Math.random().

Edit:

Scenario è il lato client sul web e non per la sicurezza, solo per garantire che ogni frase ha un ID univoco nel database.

Edit:

ho finito di attuazione:

function guid() { 
    function s4() { 
    return Math.floor((1 + Math.random()) * 0x10000) 
     .toString(16) 
     .substring(1); 
    } 
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' + 
    s4() + '-' + s4() + s4() + s4(); 
} 

var id = guid(); 

Da: https://stackoverflow.com/a/105074/1063287

Vedere anche commentare la risposta:

In realtà, la RFC permette UUID creati a caso numeri. Devi solo spostare un paio di bit per identificarlo come tale. Vedere la sezione 4.4. Algoritmi per la creazione di un UUID da Truly casuale o pseudo-casuale di numeri: rfc-archive.org/getrfc.php?rfc=4122

+0

Questo esegue il lato client sul Web e hai in programma di usarlo per sicurezza? – Liam

+0

Sì lato client sul web, e non per sicurezza - solo per garantire che ogni frase abbia un ID univoco nel database. – user1063287

+7

@ user1063287 'Matematica.random() 'scopo non è quello di fornire univocità –

risposta

0

È complicato.

A causa di nel modo specifico che si sta utilizzando il generatore di numeri casuali, è possibile che la prima stringa sia la stessa mentre la seconda o la terza stringa sono differenti. Ciò significa che produci stringhe più uniche di quelle che otterresti con una singola chiamata a Math.random(). Stringhe più uniche implicano meno collisioni, che è ciò a cui miravi.

Per confermare, è sufficiente scaricare molte di queste stringhe in un file e quindi ordinarle e vedere se il secondo e il terzo valore cambiano sempre con il primo valore o se possono essere modificati indipendentemente (è necessario aggiungere separatori all'output per vederlo).

Questo è un artefatto del modo in cui lo stato PRNG è nascosto; e dopo alcuni appendi smetterà di funzionare. Dovrebbe (no garanzie!) Essere dopo così tante iterazioni che non sarai in grado di testarlo facilmente, quindi non cercare di elaborarlo empiricamente.

Se si ha un algoritmo di generatore davvero primitiva allora si potrebbe scoprire che ogni volta random1 è stato pari a X, poi random2 sarebbe sempre uguale a Y e random3 sarebbe sempre uguale a Z; quindi se hai avuto una collisione in X, allora implicitamente anche Y e Z si scontrano e quindi non aiutano.

Ma la maggior parte dei PRNG (e anche la struttura del codice quando si prendono solo 10000 valori distinti da ciascuna chiamata), hanno uno stato molto più grande di quello che rivelano in una singola chiamata. Ciò significa che anche se random1 è X, random2 e random3 sono ancora completamente imprevedibili e le collisioni sono rese meno probabili dalla loro presenza.

Tuttavia, dal momento in cui si arriva a random100 si dovrebbe iniziare a vedere che si può intuire cosa si baserà sui valori di tutti gli altri randomX s e non renderà la stringa più unica.

Quindi l'intero problema si esaurisce in una tana di coniglio di qualità seme e dimensioni dello stato. Fondamentalmente, è plausibile che il generatore di numeri casuali sia così debole da poter produrre solo quattro miliardi di stringhe univoche e probabilmente molto meno in situazioni realistiche. La funzione random() non è stata concepita per risolvere il problema GUID, quindi c'è il rischio che si guasti in modo spettacolare.

1

Math.random() restituisce un valore numero con segno positivo, maggiore o uguale a 0, ma inferiore a 1, scelto a caso o pseudo a caso con distribuzione approssimativamente uniforme su quell'intervallo, utilizzando un algoritmo o una strategia dipendente dall'implementazione.

Ecco implementazione del V8:

uint32_t V8::Random() { 

// Random number generator using George Marsaglia's MWC algorithm. 
static uint32_t hi = 0; 
static uint32_t lo = 0; 

// Initialize seed using the system random(). If one of the seeds 
// should ever become zero again, or if random() returns zero, we 
// avoid getting stuck with zero bits in hi or lo by reinitializing 
// them on demand. 
if (hi == 0) hi = random(); 
if (lo == 0) lo = random(); 

// Mix the bits. 
hi = 36969 * (hi & 0xFFFF) + (hi >> 16); 
lo = 18273 * (lo & 0xFFFF) + (lo >> 16); 
return (hi << 16) + (lo & 0xFFFF); 
} 

Fonte: http://dl.packetstormsecurity.net/papers/general/Google_Chrome_3.0_Beta_Math.random_vulnerability.pdf

In altre parole 3 valori casuali ane non piu 'random' di 1.

+0

Tale implementazione è stata [riparata] (http://v8project.blogspot.com/2015/12/theres-mathrandom-and-then-theres.html) l'anno scorso. – sh1

+0

Si prega di essere specifici e dare una definizione di "(più) casuale" se anche si deve metterlo tra virgolette. – Bergi

2

L'unica cosa che si cambia concatenando 3 uniformemente le stringhe casuali distribuite rappresentano un intervallo più ampio di valori possibili. La distribuzione è ancora uniforme, quindi non è più "casuale" ma riduce significativamente il rischio di collisioni. Il numero di valori possibili sarebbe quindi di 36^12, o 4.7383813e + 18.

Otterrete lo stesso effetto concatenando 12 cifre di 36 basi (0-9, A-Z).

+0

In realtà l'algoritmo scelto dall'OP per concatenare le stringhe non era uniforme, in quanto non garantiva una lunghezza costante ... – Bergi