Backend Development 11 min read

Analysis and Implementation of Various WeChat Red Packet Distribution Algorithms in PHP

This article examines three main algorithms—ordinary random, double‑mean, and line‑segment—for distributing WeChat red packets, provides PHP implementations, validates the randomness of array_rand, and compares their performance to guide developers in choosing a fair and efficient solution.

Architect
Architect
Architect
Analysis and Implementation of Various WeChat Red Packet Distribution Algorithms in PHP

In this article the author explores the main algorithms used for distributing WeChat red packets, presenting ordinary random, double‑mean, and line‑segment methods, and provides PHP implementations for each.

Ordinary random simply picks a random amount from the remaining total, which can lead to unfairness; the PHP function LeftMoneyRedbag demonstrates this approach.

function LeftMoneyRedbag($Moneys, $userNums, $isEveryHave = 1, $baseMoney = 1) {
    if ($Moneys <= 0 || $userNums <= 0) {
        return ['code'=>-3,'msg'=>'红包金额或拆红包总人数不合法'];
    }
    if ($isEveryHave && $userNums > $Moneys) {
        return ['code'=>-4,'msg'=>'红包数量不足'];
    }
    if ($isEveryHave) {
        $Moneys = $Moneys - ($userNums * $baseMoney);
    }
    $userMoney = [];
    $leftMoneys = $Moneys;
    $leftUserNums = $userNums;
    while ($leftUserNums > 1) {
        $RandVal = 0;
        if ($leftMoneys > 0) {
            $RandVal = mt_rand(0, $leftMoneys);
            $leftMoneys -= $RandVal;
        }
        $userMoney[] = $isEveryHave ? ($baseMoney + $RandVal) : $RandVal;
        $leftUserNums--;
    }
    $userMoney[] = $isEveryHave ? ($baseMoney + $leftMoneys) : $leftMoneys;
    return ['code'=>0,'msg'=>'success','redbag'=>$userMoney];
}

The double‑mean algorithm uses twice the average of the remaining money as the upper bound, offering a more balanced distribution; its implementation is shown in doubleMeanRedbag .

function doubleMeanRedbag($Moneys, $userNums, $isEveryHave = 1, $baseMoney = 1) {
    if ($Moneys <= 0 || $userNums <= 0) {
        return ['code'=>-3,'msg'=>'红包金额或拆红包总人数不合法'];
    }
    if ($isEveryHave && $userNums > $Moneys) {
        return ['code'=>-4,'msg'=>'红包数量不足'];
    }
    if ($isEveryHave) {
        $Moneys = $Moneys - ($userNums * $baseMoney);
    }
    $userMoney = [];
    $leftMoneys = $Moneys;
    $leftUserNums = $userNums;
    while ($leftUserNums > 1) {
        $RandVal = 0;
        if ($leftMoneys > 0) {
            $doubleMeans = ceil($leftMoneys / $leftUserNums * 2);
            $RandVal = mt_rand(0, $doubleMeans);
            $leftMoneys -= $RandVal;
        }
        $userMoney[] = $isEveryHave ? ($baseMoney + $RandVal) : $RandVal;
        $leftUserNums--;
    }
    $userMoney[] = $isEveryHave ? ($baseMoney + $leftMoneys) : $leftMoneys;
    return ['code'=>0,'msg'=>'success','redbag'=>$userMoney];
}

The line‑segment method treats the total amount as a line and randomly selects N‑1 cut points; an optimized version leverages array_rand to generate unique cut points efficiently.

function lineSegmentOptimize($Moneys, $userNums, $isEveryHave = 1) {
    if ($Moneys <= 0 || $userNums <= 0) {
        return ['code'=>-3,'msg'=>'红包金额或拆红包总人数不合法'];
    }
    if ($isEveryHave && $userNums > $Moneys) {
        return ['code'=>-4,'msg'=>'红包数量不足'];
    }
    $cutPoints = [];
    $userMoney = [];
    if ($isEveryHave) {
        $MoneysArr = array_fill(1, $Moneys - 1, 0);
    } else {
        $MoneysArr = array_fill(0, $Moneys + 1, 0);
    }
    if ($userNums == 1) {
        $userMoney[] = $Moneys;
        return ['code'=>0,'msg'=>'success','redbag'=>$userMoney];
    }
    $cutPoints = array_rand($MoneysArr, $userNums - 1);
    sort($cutPoints);
    $lastVal = 0;
    foreach ($cutPoints as $randPoint) {
        $diff = $randPoint - $lastVal;
        $userMoney[] = $diff;
        $lastVal = $randPoint;
    }
    $userMoney[] = $Moneys - $lastVal;
    return ['code'=>0,'msg'=>'success','redbag'=>$userMoney];
}

A series of experiments verify the randomness and de‑duplication behavior of array_rand and compare the runtime of the three algorithms, showing that the optimized line‑segment approach can outperform the double‑mean method while maintaining fairness.

Finally, the article summarizes the trade‑offs between fairness and performance, providing practical guidance for developers implementing red‑packet distribution logic.

performanceBackend DevelopmentphpRed PacketRandom Algorithm
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.