Skip to content

Commit e06d17c

Browse files
committed
Use secure integers to shuffle
1 parent 1313169 commit e06d17c

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

jp_diceware.html

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,27 @@ <h1>🎲 Word Roller</h1>
8383
console.error(err);
8484
});
8585

86+
function getSecureRandomInt(max) {
87+
const range = 2 ** 32;
88+
const maxMultiple = Math.floor(range / max) * max;
89+
90+
let rand;
91+
do {
92+
rand = crypto.getRandomValues(new Uint32Array(1))[0];
93+
} while (rand >= maxMultiple); // reject biased tail
94+
95+
return rand % max;
96+
}
97+
98+
function secureShuffle(array) {
99+
const shuffled = array.slice();
100+
for (let i = shuffled.length - 1; i > 0; i--) {
101+
const j = getSecureRandomInt(i + 1); // unbiased
102+
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
103+
}
104+
return shuffled;
105+
}
106+
86107
function rollWords() {
87108
const resultEl = document.getElementById('result');
88109
const num = parseInt(document.getElementById('numWords').value);
@@ -98,11 +119,7 @@ <h1>🎲 Word Roller</h1>
98119
}
99120

100121
// Shuffle and select random entries
101-
const shuffled = csvData
102-
.map(line => ({ line, sort: Math.random() }))
103-
.sort((a, b) => a.sort - b.sort)
104-
.map(obj => obj.line)
105-
.slice(0, num);
122+
const shuffled = secureShuffle(csvData).slice(0, num);
106123

107124
// Extract columns 2 and 4
108125
const output = shuffled.map(row => {

0 commit comments

Comments
 (0)