@@ -95,6 +95,14 @@ public static function register_for( $pdo ): self {
9595 '_helper_like_to_glob_pattern ' => '_helper_like_to_glob_pattern ' ,
9696 );
9797
98+ /**
99+ * Seed instances used for the LCG pseudo-random generator (RAND).
100+ *
101+ * @var int|null
102+ */
103+ private $ rand_seed1 = null ;
104+ private $ rand_seed2 = null ;
105+
98106 /**
99107 * A helper function to throw an error from SQLite expressions.
100108 *
@@ -178,8 +186,40 @@ public function md5( $field ) {
178186 *
179187 * @return int
180188 */
181- public function rand () {
182- return mt_rand ( 0 , 1 );
189+ public function rand ( $ seed = null ) {
190+ $ max_value = 0x3FFFFFFF ; // 1073741823
191+
192+ if ( null !== $ seed ) {
193+ /*
194+ * Initialize MySQL's internal 30-bit seeds.
195+ * These constants match MySQL's my_rnd_init() implementation.
196+ */
197+ $ n = (int ) $ seed ;
198+ $ this ->rand_seed1 = ( $ n * 0x10001 + 55555555 ) % $ max_value ;
199+ $ this ->rand_seed2 = ( $ n * 0x10000001 ) % $ max_value ;
200+
201+ // Ensure seeds are positive.
202+ if ( $ this ->rand_seed1 < 0 ) {
203+ $ this ->rand_seed1 += $ max_value ;
204+ }
205+ if ( $ this ->rand_seed2 < 0 ) {
206+ $ this ->rand_seed2 += $ max_value ;
207+ }
208+ }
209+
210+ if ( null !== $ this ->rand_seed1 && null !== $ this ->rand_seed2 ) {
211+ /*
212+ * MySQL's LCG (Linear Congruential Generator) recurrence:
213+ * seed1 = (seed1 * 3 + seed2) % 0x3FFFFFFF
214+ * seed2 = (seed1 + seed2 + 33) % 0x3FFFFFFF
215+ */
216+ $ this ->rand_seed1 = ( $ this ->rand_seed1 * 3 + $ this ->rand_seed2 ) % $ max_value ;
217+ $ this ->rand_seed2 = ( $ this ->rand_seed1 + $ this ->rand_seed2 + 33 ) % $ max_value ;
218+
219+ return (float ) $ this ->rand_seed1 / (float ) $ max_value ;
220+ }
221+
222+ return mt_rand ( 0 , mt_getrandmax () ) / mt_getrandmax ();
183223 }
184224
185225 /**
0 commit comments