php中session_id的生成


生成函数为php_session_create_id,看代码:

gettimeofday(&tv, NULL);
先获取当前时间,精确到毫微秒;

//看有没有$_SERVER['REMOTE_ADDR']
if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &array) == SUCCESS &&
        Z_TYPE_PP(array) == IS_ARRAY &&
        zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS
    ) {
        remote_addr = Z_STRVAL_PP(token);
    }

//格式化
spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);

IP地址+秒+毫微秒|php_combined_lcg函数返回的值;

看下php_combined_lcg这个函数
if (!LCG(seeded)) {
        lcg_seed(TSRMLS_C);
    }

    MODMULT(53668, 40014, 12211, 2147483563L, LCG(s1));
    MODMULT(52774, 40692, 3791, 2147483399L, LCG(s2));

    z = LCG(s1) - LCG(s2);
    if (z < 1) {
        z += 2147483562;
    }

    return z * 4.656613e-10;

LCG表示LCG模块的全局变量,具体干什么的还没细看^_^
测试环境数据{s1 = 0, s2 = 0, seeded = 0}

再看MODMULT的定义
#define MODMULT(a, b, c, m, s) q = s/a;s=b*(s-a*q)-c*q;if(s<0)s+=m

为什么是这个算法,可以参考这里,乘余发生器算法:http://bbs.csdn.net/topics/60236316

最后再作MD5处理,这个算法可以在php.ini中处理,好像目前只支持md5和sha1算法;
注意最后结果算法出的字符串和php中计算的每两个字节的顺序可能不一样,C语言算出来是b06cd855f3dfe8846a68557b613b7ed9,而PHP算出来是0bc68d553ffd8e48a68655b716b3e79d


最终生成的长度还受session.session.hash_bits_per_character决定,这个默认是4,生出来的是32个字符,如果是6,则生成的长度为24


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM