微信的抢红包算法PHP版

在抢红包这个场景中,大都使用的是修正后的随机算法,从统计学意义上来讲要达到先抢后抢得到的红包是差不多的。

微信红包算法的核心是:每次随机的基础是剩余金额除以剩余个数得到的平均值的两倍。

class Test
{
    public $remainSize = 20;
    public $remainMoney = '10.00';
    public $min = '0.01';
    public $scale = 2;

    public function getRandomMoney(): string
    {
        if ($this->remainSize <= 0 || bccomp($this->remainMoney, "0") < 1) {
            return "0.00";
        }
        bcscale($this->scale);
        if ($this->remainSize == 1) {
            $this->remainSize = 0;
            return $this->remainMoney;
        }
        
        // 核心算法 start
        $max = bcmul(bcdiv($this->remainMoney, strval($this->remainSize)), "2");
        $money = bcmul(rand(0, 100) / 100, $max);
        // 核心算法 end
        
        if (bccomp($money, $this->min) < 1) {
            $money = $this->min;
        }

        $this->remainSize--;
        $this->remainMoney = bcsub($this->remainMoney, $money);
        return $money;
    }
}

测试代码:

function run()
{
    $o = new Test();
    for ($i = 0; $i < 30; $i++) {
        echo $o->getRandomMoney(), PHP_EOL;
    }
}

运行两次后得到的结果为:

在这里插入图片描述
在这里插入图片描述
可见,其波动性还是挺大的,并且也没有证据表示先抢还是后抢会占优势。

分别运行 2000 次和 3000 次看看统计规律

function run2()
{
    $sum = [];
    bcscale(2);
    for ($k = 0; $k < 2000; $k++) {
        $o = new Test();
        for ($i = 0; $i < 30; $i++) {
            $t = $o->getRandomMoney();
            if (isset($sum[$i])) {
                $sum[$i] = bcadd($sum[$i], $t);
            } else {
                $sum[$i] = $t;
            }
        }
    }

    foreach ($sum as $v) {
        echo $v, PHP_EOL;
    }
}

2000 次
在这里插入图片描述
3000次
在这里插入图片描述
可见次数越多越趋近于平均值 1000 元。而这个值正好是 2000 * 10 / 20

如果将 2 改成 1.5 ,将会是前低后高的趋势
在这里插入图片描述
如果将 2 改成 3 ,将会是前高后低的趋势

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
微信抢红包算法涉及到微信支付和微信红包接口的调用,需要进行授权认证和支付操作,因此需要使用微信官方提供的SDK进行开发。 以下是一个基本的微信抢红包算法的示例代码: ```php <?php require_once "WxPayApi.php"; // 引入微信支付SDK // 微信支付配置参数 $config = new WxPayConfig(); $config->SetAppId("YOUR_APPID"); $config->SetMchId("YOUR_MCHID"); $config->SetKey("YOUR_KEY"); $config->SetNotifyUrl("YOUR_NOTIFY_URL"); // 获取红包信息 $redpack = $_POST["redpack"]; // 前端传递的红包信息 $redpack_info = json_decode($redpack, true); // 解析红包信息 // 构造红包支付请求参数 $input = new WxPayUnifiedOrder(); $input->SetBody("红包支付"); // 商品描述 $input->SetOut_trade_no($redpack_info["redpack_id"]); // 商户订单号 $input->SetTotal_fee($redpack_info["total_amount"] * 100); // 总金额,单位为分 $input->SetSpbill_create_ip($_SERVER["REMOTE_ADDR"]); // 终端IP $input->SetNotify_url($config->GetNotifyUrl()); // 通知地址 $input->SetTrade_type("JSAPI"); // 交易类型 $input->SetOpenid($redpack_info["openid"]); // 用户标识 // 调用统一下单API获取预支付交易会话标识 $wxpay_api = new WxPayApi($config); $result = $wxpay_api->unifiedOrder($input); if ($result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS") { // 构造红包接口请求参数 $redpack_input = new WxPayRedPack(); $redpack_input->SetMch_billno($redpack_info["redpack_id"]); // 商户订单号 $redpack_input->SetSend_name("微信红包"); // 商户名称 $redpack_input->SetRe_openid($redpack_info["openid"]); // 用户openid $redpack_input->SetTotal_amount($redpack_info["total_amount"] * 100); // 付款金额,单位为分 $redpack_input->SetTotal_num(1); // 红包发放总人数 $redpack_input->SetWishing("恭喜发财,大吉大利"); // 红包祝福语 $redpack_input->SetClient_ip($_SERVER["REMOTE_ADDR"]); // Ip地址 $redpack_input->SetAct_name("微信红包"); // 活动名称 $redpack_input->SetRemark("微信红包"); // 备注信息 // 调用红包接口发放红包 $result = $wxpay_api->sendRedPack($redpack_input); if ($result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS") { echo "红包发送成功!"; } else { echo "红包发送失败!"; } } else { echo "统一下单失败!"; } ``` 需要注意的是,该示例代码仅供参考,实际开发中需要根据具体业务场景进行适当的修改和调整。另外,微信红包接口需要在微信商户平台进行开通和配置,具体操作请参考微信官方文档和开发者文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值