3

テストと学習の目的で、 https ://github.com/php/php-src :ext / standard/rand.cにあるphprand関数とmt_rand関数を変更したいと思いました。

rand関数が呼び出されるたびに固定出力を提供したかったので、この目的のためにコードを変更しました

PHPAPI long php_rand(TSRMLS_D)
{
    long ret;

    if (!BG(rand_is_seeded)) {
        php_srand(GENERATE_SEED() TSRMLS_CC);
    }

#ifdef ZTS
    ret = php_rand_r(&BG(rand_seed));
#else
# if defined(HAVE_RANDOM)
    ret = random();
# elif defined(HAVE_LRAND48)
    ret = lrand48();
# else
    ret = rand();
# endif
#endif

    // ignoring the results coming from the calls above and 
    // returning a constant value 
    ret = 3264;

    return ret;
}

編集済み

./configure
make
make install

そして最後にrand関数をasecho rand(3000,4000);と呼び、それは常に。を返します3000

この関数を変更する方法は何でしょうか?TSRMLS_D範囲パラメータはあるがないのはなぜですか?

4

2 に答える 2

2

PHPから呼び出される実際の関数は、宣言された関数であり、変更PHP_FUNCTION(rand)した関数を呼び出しphp_rand()ます。次のことを行います。

PHP_FUNCTION(rand)
{
    long min;
    long max;
    long number;
    int  argc = ZEND_NUM_ARGS();

    if (argc != 0 && zend_parse_parameters(argc TSRMLS_CC, "ll", &min, &max) == FAILURE)
        return;

    number = php_rand(TSRMLS_C);
    if (argc == 2) {
        RAND_RANGE(number, min, max, PHP_RAND_MAX);
    }

    RETURN_LONG(number);
}

ご覧のとおり、2つのパラメーターを渡すと、RAND_RANGEマクロが呼び出され、の結果がphp_rand()指定された範囲に変換されます。

#define RAND_RANGE(__n, __min, __max, __tmax) \
    (__n) = (__min) + (long) ((double) ( (double) (__max) - (__min) + 1.0) * ((__n) / ((__tmax) + 1.0)))

常に特定の値を出力したい場合はPHP_FUNCTION(rand)、の代わりにを変更することをお勧めしphp_rand()ます。

探しているのが安定した乱数出力だけで、毎回同じ結果が得られる場合でも、正確な結果を気にしない場合はsrand(0)、プログラムの最初に呼び出して、ランダムをシードすることができます。定数値の乱数ジェネレーター。これは、乱数ジェネレーターが常に同じ乱数シーケンスを提供することを意味します。これはテスト目的に役立ち、PHP自体にパッチを適用せずに実行できます。

于 2012-11-19T19:04:11.323 に答える
0

php_rand.hで定義されているRAND_RANGEマクロを見てください。指定した範囲内に収まるように、入力値の追加の順列/スクランブリングを実行します。

rand()に渡されたパラメーターに収まらない場合でもrand()関数が3264を返すようにしたい場合は、rand.cでこのブロックを削除してください。

    if (argc == 2) {
    RAND_RANGE(number, min, max, PHP_RAND_MAX);
}

それでも最小/最大を検討したい場合は、ハードコードされた数値を含まない最小/最大を指定した場合に、実際に何をしたいかを理解する必要があります。

于 2012-11-19T18:57:14.810 に答える