Încerc să obțin un număr aleator, imprevizibil destul de lung (± 20-25 de cifre) folosind Javascript (creat de clientul utilizatorului) cât mai rapid și ușor posibil. Este această soluție suficient de fiabilă, robustă și sigură?
Când pagina online este deschisă, marca temporală din 13 cifre este stocată. Un cronometru determină numărul de milisecunde înainte ca utilizatorul să facă clic pe „OK” (să presupunem că are de citit un text scurt sau orice altceva de făcut). O colecție de 100 de „pixeli” invizibili (1*1px HTML se întinde) este creată cu culori RGBA inițiale fixate aleatoriu (A=0=transparență).
fie d = Data.acum(); // marcaj temporal 13 cifre
fie n = 100 // numărul de „pixeli”
lasă pixeli = ''
pentru (i=0; i<n; i++) {
fie r = Math.floor(Math.random() * 256);
fie g = Math.floor(Math.random() * 256);
fie b = Math.floor(Math.random() * 256);
fie c = 'rgba('+r+','+g+','+b+',0)'
pixeli += '<span id="pix'+i+'" style="background-color:'+c+'"></span>'
}
Odată ce este gata, schimbăm aleatoriu culoarea fiecărui „pixel” la fiecare 100 de secundă
lasă schimbareaColor = setInterval(funcție(){
pentru (i=0; i<n; i++) {
fie r = Math.floor(Math.random() * 256);
fie g = Math.floor(Math.random() * 256);
fie b = Math.floor(Math.random() * 256);
fie c = 'rgba('+r+','+g+','+b+',0)'
document.getElementById('pix'+i).style.backgroundColor = c
}
},10);
Când utilizatorul face clic pe „OK”, funcția este oprită, este determinat un pixel aleatoriu și sunt găsite valorile RGB ale acestuia
fie x = Math.floor(Math.random() * n); // 39
let px = window.getComputedStyle(document.getElementById('pix'+x),null).backgroundColor
fie rgb = px.match(/\d+/g); // pix 39 = [21,13,152]
Apoi înmulțim fiecare valoare RGB cu x * un factor aleator [1 la 5]:
fie r = rgb[0]*(x*Math.floor(Math.random() * 5)+1), // 21 * 39 * 2 = 1638
g = rgb[1]*(x*Math.floor(Math.random() * 5)+1), // 13 * 39 * 1 = 507
b = rgb[2]*(x*Math.floor(Math.random() * 5)+1) // 152 * 39 * 4 = 23712
Adăugând x + temporizatorul + un extras aleatoriu al marcajului de timp obținem:
fie t = Data.now()-d; // temporizator la clic
fie p = Math.floor(Math.random() * 4)+3;
fie z = d.toString().substr(-p) // ultima valoare a marcajului temporal xx (3->7)
fie val = x+''+r+g+b+''+t+z // 39 1368 507 23712 1348 55601
Apoi amestecăm aleatoriu rezultatul:
function shuffle(a) {
fie r = a.lungime, temp, rand;
în timp ce (0 !== r) {
rand = Math.floor(Math.random() * r);
r -= 1;
temp = a[r];
a[r] = a[rand];
a[rand] = temp;
}
returnează a; // 39136850723712134855601 -> 25851963017738613021534
}
Teste -> consola
17:22:34 pix #39 = [21,13,152] 9348234523267751239843
17:22:42 pix #39 = [21,13,152] 109715237240854257137
17:23:02 pix #39 = [21,13,152] 100889146450039658553439
Dacă avem nevoie de un rezultat mai lung (50, 100 de cifre) putem crea 500 de „pixeli” și alegem aleatoriu 10 dintre ei în loc de unul. Sau adăugați o valoare de entropie (mișcarea mouse-ului pe ecran: https://www.grc.com/r&d/js.htm) la valoarea obţinută. Tu ce crezi?