用 openssl_random_pseudo_bytes() 替换 rand()

replace rand() with openssl_random_pseudo_bytes()(用 openssl_random_pseudo_bytes() 替换 rand())
本文介绍了用 openssl_random_pseudo_bytes() 替换 rand()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要替换 PHP 的 rand() 函数,该函数使用强加密随机数生成器.

I need a replacement for PHP's rand() function that uses a cryptographically strong random number generator.

openssl_random_pseudo_bytes() 函数可让您访问强随机数生成器,但它会将其数据输出为字节字符串.相反,我需要一个介于 0 和 X 之间的整数.

The openssl_random_pseudo_bytes() function gets you access to the strong random number generator, but it outputs its data as a byte string. Instead, I need an integer between 0 and X.

我想关键是将 openssl_random_pseudo_bytes() 的输出转换为整数,然后您可以对其进行任何您需要的数学运算.我可以想到一些从字节字符串转换为整数的蛮力"方法,但我希望得到一些……优雅的东西.

I imagine the key is to get the output of openssl_random_pseudo_bytes() into an integer, then you can do any math on it that you need to. I can think of a few "brute force" ways of converting from a byte string to an integer, but I was hoping for something ... elegant.

推荐答案

使用提供的建议,我使用 OpenSSL 创建了一个替代 rand() 的插件.我会把它包括在这里以供后代使用.

Using provided suggestions, I've created a drop-in replacement for rand() using OpenSSL. I'll include it here for posterity.

$pedantic 选项通过在结果不会在可能的范围内均匀分布时重新开始来提供无偏差的结果.

The $pedantic option gives bias-free results by starting over when results won't be evenly distributed across the possible range.

function crypto_rand($min,$max,$pedantic=True) {
    $diff = $max - $min;
    if ($diff <= 0) return $min; // not so random...
    $range = $diff + 1; // because $max is inclusive
    $bits = ceil(log(($range),2));
    $bytes = ceil($bits/8.0);
    $bits_max = 1 << $bits;
    // e.g. if $range = 3000 (bin: 101110111000)
    //  +--------+--------+
    //  |....1011|10111000|
    //  +--------+--------+
    //  bits=12, bytes=2, bits_max=2^12=4096
    $num = 0;
    do {
        $num = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes))) % $bits_max;
        if ($num >= $range) {
            if ($pedantic) continue; // start over instead of accepting bias
            // else
            $num = $num % $range;  // to hell with security
        }
        break;
    } while (True);  // because goto attracts velociraptors
    return $num + $min;
}

这篇关于用 openssl_random_pseudo_bytes() 替换 rand()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Convert JSON integers and floats to strings(将JSON整数和浮点数转换为字符串)
in php how do I use preg replace to turn a url into a tinyurl(在php中,如何使用preg替换将URL转换为TinyURL)
all day appointment for ics calendar file wont work(ICS日历文件的全天约会不起作用)
trim function is giving unexpected values php(Trim函数提供了意外的值php)
Basic PDO connection to MySQL(到MySQL的基本PDO连接)
PHP number_format returns 1.00(Php number_Format返回1.00)