-
Notifications
You must be signed in to change notification settings - Fork 11.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[9.x] Use secure randomness in Arr:random and Arr:shuffle #46105
Changes from 3 commits
6e7534e
9f39ac6
a0d9d0a
b223c3b
1474192
55b8d17
d074c06
63ddf4e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -635,28 +635,14 @@ public static function random($array, $number = null, $preserveKeys = false) | |
} | ||
|
||
if (is_null($number)) { | ||
return $array[array_rand($array)]; | ||
return head(array_slice($array, random_int(0, $count - 1), 1)); | ||
} | ||
|
||
if ((int) $number === 0) { | ||
return []; | ||
} | ||
|
||
$keys = array_rand($array, $number); | ||
|
||
$results = []; | ||
|
||
if ($preserveKeys) { | ||
foreach ((array) $keys as $key) { | ||
$results[$key] = $array[$key]; | ||
} | ||
} else { | ||
foreach ((array) $keys as $key) { | ||
$results[] = $array[$key]; | ||
} | ||
} | ||
|
||
return $results; | ||
return array_slice(static::shuffle($array), 0, $number, $preserveKeys); | ||
} | ||
|
||
/** | ||
|
@@ -708,15 +694,24 @@ public static function set(&$array, $key, $value) | |
*/ | ||
public static function shuffle($array, $seed = null) | ||
{ | ||
if (is_null($seed)) { | ||
shuffle($array); | ||
} else { | ||
if (! is_null($seed)) { | ||
mt_srand($seed); | ||
shuffle($array); | ||
mt_srand(); | ||
|
||
return $array; | ||
} | ||
|
||
return $array; | ||
$keys = array_keys($array); | ||
$shuffled = []; | ||
|
||
for ($i = count($keys) - 1; $i >= 0; $i--) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given a zero-based array, the Fisher-Yates algorithm iterates from Therefore, it should be: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I just noticed that in 9f39ac6 you tweaked the original algorithm, so I can't say for sure… There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, the core counts down to Since it shouldn't be preserving keys, I will go back to the original algorithm. |
||
$j = random_int(0, $i); | ||
$shuffled[$keys[$j]] = $array[$keys[$j]]; | ||
$keys[$j] = $keys[$i]; | ||
} | ||
|
||
return $shuffled; | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your current implementation of
Arr::shuffle()
changed from not preserving the keys, to preserving the keys. Changing it back to not preserving the keys, the above line inArr::random()
which makes use ofArr::shuffle()
and array_slice() (withpreserve_keys
parameter) would no longer work, the code would need to be adjusted.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, my bad. I added in preserving keys because I needed it for the
Arr:random($num)
usage, and overlooked the fact that shuffle didn't preserve them. I'll split them out sorandom()
can preserve it's keys andshuffle()
doesn't.