[英]Modifying PHP rand function
出於測試和學習的目的,我想修改https://github.com/php/php-src:ext / standard / rand.c中的php rand和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函數稱為echo rand(3000,4000);
它總是返回3000
。
修改此功能的方法是什么? 為什么有TSRMLS_D
而不是范圍參數?
從PHP調用的實際函數是聲明為PHP_FUNCTION(rand)
php_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本身的情況下完成。
查看php_rand.h中的RAND_RANGE宏定義。 它對輸入值進行一些額外的置換/加擾,使其適合您指定的范圍。
如果你真的希望rand()函數返回3264,即使它不適合傳遞給rand()的參數,在rand.c中刪除這個塊:
if (argc == 2) {
RAND_RANGE(number, min, max, PHP_RAND_MAX);
}
如果您仍想考慮最小值/最大值,那么如果您指定不包含硬編碼的最小值/最大值,您將需要弄清楚您想要實際執行的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.