You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP生成8位全排列并逐次处理(规避内存溢出问题)

问题描述

我有一组字符集:

0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z

希望生成所有8位格式的密钥:

00000000
00000001
00000002
...
zzzzzzzy
zzzzzzzz

但已找到的方案都会因分配数组导致PHP内存溢出,因此希望通过循环实现(每次生成一个排列,处理后再生成下一个):

// LOOPS
// generate 1 permutation
// do something
// END LOOP

请问有什么实现思路?

实现方案

直接用进制转换法或者多层嵌套循环就能解决,前者代码简洁易扩展,后者直观易懂,以下是具体实现:

方案1:进制转换法(推荐)

把给定的36个字符看成是一套36进制的“数字”,从0循环到36^8 - 1,将每个十进制数转换成36进制后,用字符集映射替换,最后补前导零到8位。这种方式每次只生成一个密钥,完全不会占用大量内存。

代码示例

// 定义字符集
$chars = '0123456789abcdefghijklmnopqrstuvwxyz';
$charTotal = strlen($chars);
$keyLength = 8;
// 计算总共有多少种组合
$maxCount = pow($charTotal, $keyLength);

for ($i = 0; $i < $maxCount; $i++) {
    $num = $i;
    $key = '';
    // 将十进制数转换为自定义36进制
    for ($j = 0; $j < $keyLength; $j++) {
        $remainder = $num % $charTotal;
        $key = $chars[$remainder] . $key;
        $num = floor($num / $charTotal);
    }
    // 补前导零,确保密钥是8位
    $key = str_pad($key, $keyLength, '0', STR_PAD_LEFT);
    
    // 这里写你处理密钥的逻辑,比如输出、写入文件等
    echo $key . PHP_EOL;
}

方案2:多层嵌套循环

如果觉得进制转换不好理解,也可以直接写8层嵌套循环,每一层对应密钥的一位,遍历字符集的所有字符。这种方法逻辑直观,但扩展性差——如果要修改密钥长度,就得手动调整循环层数。

代码示例

$chars = str_split('0123456789abcdefghijklmnopqrstuvwxyz');
$charCount = count($chars);

// 8层循环对应8位密钥的每一位
for ($a = 0; $a < $charCount; $a++) {
    for ($b = 0; $b < $charCount; $b++) {
        for ($c = 0; $c < $charCount; $c++) {
            for ($d = 0; $d < $charCount; $d++) {
                for ($e = 0; $e < $charCount; $e++) {
                    for ($f = 0; $f < $charCount; $f++) {
                        for ($g = 0; $g < $charCount; $g++) {
                            for ($h = 0; $h < $charCount; $h++) {
                                $key = $chars[$a] . $chars[$b] . $chars[$c] . $chars[$d] . $chars[$e] . $chars[$f] . $chars[$g] . $chars[$h];
                                
                                // 处理密钥的逻辑
                                echo $key . PHP_EOL;
                            }
                        }
                    }
                }
            }
        }
    }
}

实用提示

  • 36^8等于2821109907456,也就是超过2.8万亿次循环,实际运行会极慢,建议根据需求添加终止条件,或者分批处理(比如每生成100万条就写入文件并短暂休眠)。
  • 如果需要写入文件,不要每次循环都调用file_put_contents,建议提前用fopen打开文件句柄,每次循环用fwrite写入,最后关闭句柄,能大幅提升效率。

内容的提问来源于stack exchange,提问作者pacionet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:07:27