Skip to content

Commit 553be2f

Browse files
committed
add support seed by strings on XorShift128Plus
1 parent 0939122 commit 553be2f

File tree

5 files changed

+77
-11
lines changed

5 files changed

+77
-11
lines changed

ext/random/random.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,18 +1080,36 @@ PHP_FUNCTION(random_int)
10801080
}
10811081
/* }}} */
10821082

1083+
void printb(unsigned int v) {
1084+
unsigned int mask = (int)1 << (sizeof(v) * CHAR_BIT - 1);
1085+
do putchar(mask & v ? '1' : '0');
1086+
while (mask >>= 1);
1087+
printf("\n");
1088+
}
1089+
1090+
10831091
/* {{{ Construct object */
10841092
PHP_METHOD(Random_NumberGenerator_XorShift128Plus, __construct)
10851093
{
10861094
php_random_numbergenerator *generator = Z_RANDOM_NUMBERGENERATOR_P(ZEND_THIS);
1087-
zend_long seed;
1095+
php_random_numbergenerator_state_xorshift128plus *state = generator->state;
1096+
zend_string *str_seed = NULL;
1097+
zend_long int_seed = 0;
10881098

10891099
ZEND_PARSE_PARAMETERS_START(1, 1)
1090-
Z_PARAM_LONG(seed)
1100+
Z_PARAM_STR_OR_LONG(str_seed, int_seed)
10911101
ZEND_PARSE_PARAMETERS_END();
1092-
1093-
if (generator->algo->seed) {
1094-
generator->algo->seed(generator->state, seed);
1102+
1103+
if (str_seed) {
1104+
/* char (8 bit) * 16 = 128 bits */
1105+
if (str_seed->len == 16) {
1106+
memcpy(state->s, str_seed->val, 16);
1107+
} else {
1108+
zend_argument_value_error(1, "state strings must be 16 bytes");
1109+
RETURN_THROWS();
1110+
}
1111+
} else {
1112+
generator->algo->seed(state, int_seed);
10951113
}
10961114
}
10971115
/* }}} */
@@ -1213,6 +1231,20 @@ PHP_METHOD(Random_NumberGenerator_MersenneTwister, __construct)
12131231
}
12141232
/* }}} */
12151233

1234+
/* {{{ Construct object */
1235+
PHP_METHOD(Random_NumberGenerator_CombinedLCG, __construct)
1236+
{
1237+
php_random_numbergenerator *generator = Z_RANDOM_NUMBERGENERATOR_P(ZEND_THIS);
1238+
zend_long seed;
1239+
1240+
ZEND_PARSE_PARAMETERS_START(1, 1)
1241+
Z_PARAM_LONG(seed)
1242+
ZEND_PARSE_PARAMETERS_END();
1243+
1244+
generator->algo->seed(generator->state, seed);
1245+
}
1246+
/* }}} */
1247+
12161248
/* {{{ Construct object */
12171249
PHP_METHOD(Random_NumberGenerator_Secure, __construct)
12181250
{

ext/random/random.stub.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function random_int(int $min, int $max): int {}
2929
{
3030
class XorShift128Plus implements Random\NumberGenerator
3131
{
32-
public function __construct(int $seed) {}
32+
public function __construct(string|int $seed) {}
3333

3434
public function generate(): int {}
3535

@@ -59,7 +59,6 @@ public function __debugInfo(): array {}
5959

6060
class CombinedLCG implements Random\NumberGenerator
6161
{
62-
/** @implementation-alias Random\NumberGenerator\XorShift128Plus::__construct */
6362
public function __construct(int $seed) {}
6463

6564
/** @implementation-alias Random\NumberGenerator\XorShift128Plus::generate */

ext/random/random_arginfo.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: b9fad07117f040bbb936fc2dd449c0babf0eee7a */
2+
* Stub hash: 520b1882e9d2a783b401e2ac028260dbe30360e0 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_lcg_value, 0, 0, IS_DOUBLE, 0)
55
ZEND_END_ARG_INFO()
@@ -33,7 +33,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_random_int, 0, 2, IS_LONG, 0)
3333
ZEND_END_ARG_INFO()
3434

3535
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Random_NumberGenerator_XorShift128Plus___construct, 0, 0, 1)
36-
ZEND_ARG_TYPE_INFO(0, seed, IS_LONG, 0)
36+
ZEND_ARG_TYPE_MASK(0, seed, MAY_BE_STRING|MAY_BE_LONG, NULL)
3737
ZEND_END_ARG_INFO()
3838

3939
#define arginfo_class_Random_NumberGenerator_XorShift128Plus_generate arginfo_mt_getrandmax
@@ -60,7 +60,9 @@ ZEND_END_ARG_INFO()
6060

6161
#define arginfo_class_Random_NumberGenerator_MersenneTwister___debugInfo arginfo_class_Random_NumberGenerator_XorShift128Plus___serialize
6262

63-
#define arginfo_class_Random_NumberGenerator_CombinedLCG___construct arginfo_class_Random_NumberGenerator_XorShift128Plus___construct
63+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Random_NumberGenerator_CombinedLCG___construct, 0, 0, 1)
64+
ZEND_ARG_TYPE_INFO(0, seed, IS_LONG, 0)
65+
ZEND_END_ARG_INFO()
6466

6567
#define arginfo_class_Random_NumberGenerator_CombinedLCG_generate arginfo_mt_getrandmax
6668

@@ -113,6 +115,7 @@ ZEND_METHOD(Random_NumberGenerator_XorShift128Plus, __serialize);
113115
ZEND_METHOD(Random_NumberGenerator_XorShift128Plus, __unserialize);
114116
ZEND_METHOD(Random_NumberGenerator_XorShift128Plus, __debugInfo);
115117
ZEND_METHOD(Random_NumberGenerator_MersenneTwister, __construct);
118+
ZEND_METHOD(Random_NumberGenerator_CombinedLCG, __construct);
116119
ZEND_METHOD(Random_NumberGenerator_Secure, __construct);
117120
ZEND_METHOD(Random_Randomizer, __construct);
118121
ZEND_METHOD(Random_Randomizer, getInt);
@@ -158,7 +161,7 @@ static const zend_function_entry class_Random_NumberGenerator_MersenneTwister_me
158161

159162

160163
static const zend_function_entry class_Random_NumberGenerator_CombinedLCG_methods[] = {
161-
ZEND_MALIAS(Random_NumberGenerator_XorShift128Plus, __construct, __construct, arginfo_class_Random_NumberGenerator_CombinedLCG___construct, ZEND_ACC_PUBLIC)
164+
ZEND_ME(Random_NumberGenerator_CombinedLCG, __construct, arginfo_class_Random_NumberGenerator_CombinedLCG___construct, ZEND_ACC_PUBLIC)
162165
ZEND_MALIAS(Random_NumberGenerator_XorShift128Plus, generate, generate, arginfo_class_Random_NumberGenerator_CombinedLCG_generate, ZEND_ACC_PUBLIC)
163166
ZEND_MALIAS(Random_NumberGenerator_XorShift128Plus, __serialize, __serialize, arginfo_class_Random_NumberGenerator_CombinedLCG___serialize, ZEND_ACC_PUBLIC)
164167
ZEND_MALIAS(Random_NumberGenerator_XorShift128Plus, __unserialize, __unserialize, arginfo_class_Random_NumberGenerator_CombinedLCG___unserialize, ZEND_ACC_PUBLIC)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Random: NumberGenerator: XorShift128Plus: seed by int
3+
--FILE--
4+
<?php declare(strict_types = 1);
5+
6+
$xorshift128plus = new Random\NumberGenerator\XorShift128Plus(\random_int(\PHP_INT_MIN, \PHP_INT_MAX));
7+
8+
try {
9+
$xorshift128plus = new Random\NumberGenerator\XorShift128Plus(1.0);
10+
} catch (\Throwable $e) {
11+
echo $e->getMessage() . PHP_EOL;
12+
}
13+
14+
?>
15+
--EXPECT--
16+
Random\NumberGenerator\XorShift128Plus::__construct(): Argument #1 ($seed) must be of type string|int, float given
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Random: NumberGenerator: XorShift128Plus: seed (state) by string
3+
--FILE--
4+
<?php
5+
6+
$xorshift128plus = new Random\NumberGenerator\XorShift128Plus(\random_bytes(16));
7+
8+
try {
9+
$xorshift128plus = new Random\NumberGenerator\XorShift128Plus('foobar');
10+
} catch (\Throwable $e) {
11+
echo $e->getMessage() . PHP_EOL;
12+
}
13+
14+
?>
15+
--EXPECT--
16+
Random\NumberGenerator\XorShift128Plus::__construct(): Argument #1 ($seed) state strings must be 16 bytes

0 commit comments

Comments
 (0)