核心函數
<?php
/**
* 將字串在指定長度範圍內隨機分割
* @param int $minLen 最小片段長度
* @param int $maxLen 最大片段長度
* @param string $str 待分割字串
* @return array 分割後的片段陣列
*/
function randomSplit($minLen, $maxLen, $str) {
if ($minLen < 1 || $maxLen < $minLen) {
throw new InvalidArgumentException('長度參數無效');
}
$result = [];
$length = strlen($str);
$pos = 0;
while ($pos < $length) {
$remaining = $length - $pos;
$chunkLen = min(mt_rand($minLen, $maxLen), $remaining);
$result[] = substr($str, $pos, $chunkLen);
$pos += $chunkLen;
}
return $result;
}
// 使用範例
$text = 'This is a example to test the RandomSplit function.';
$parts = randomSplit(1, 7, $text);
echo "原字串長度:" . strlen($text) . "\n";
echo "分割片段數:" . count($parts) . "\n";
print_r($parts);
/* 可能輸出:
Array
(
[0] => This
[1] => is a
[2] => exampl
[3] => e to t
[4] => est th
[5] => e Rand
[6] => omSpli
[7] => t func
[8] => tion.
)
*/
?>
進階版:支援多位元組字串(UTF-8 中文)
<?php
function mbRandomSplit($minLen, $maxLen, $str, $encoding = 'UTF-8') {
if (!extension_loaded('mbstring')) {
throw new RuntimeException('需要 mbstring 擴充套件');
}
$len = mb_strlen($str, $encoding);
$result = [];
$pos = 0;
while ($pos < $len) {
$remaining = $len - $pos;
$chunkLen = min(mt_rand($minLen, $maxLen), $remaining);
$result[] = mb_substr($str, $pos, $chunkLen, $encoding);
$pos += $chunkLen;
}
return $result;
}
// 中文測試
$chinese = '這是一個中文測試字串,用來驗證多位元組分割功能。';
$parts = mbRandomSplit(2, 10, $chinese);
print_r($parts);
/* 可能輸出:
Array
(
[0] => 這是一個
[1] => 中文測試
[2] => 字串,用
[3] => 來驗證多
[4] => 位元組分
[5] => 割功能。
)
*/
?>
應用場景
- 測試資料生成:模擬不定長度輸入、分包傳輸
- 加密/編碼演示:區塊加密前的隨機分塊
- 文字遊戲/謎題:將答案打亂分割
- 壓縮算法測試:生成不同塊大小的測試資料
- 網路封包模擬:模擬 MTU 限制下的分片
擴充:加權隨機分割
<?php
function weightedRandomSplit($str, array $weights) {
// $weights = [長度 => 權重] 例:[1=>10, 2=>20, 3=>30, 5=>40]
$totalWeight = array_sum($weights);
$len = strlen($str);
$result = [];
$pos = 0;
while ($pos < $len) {
$remaining = $len - $pos;
// 過濾超過剩餘長度的選項
$validWeights = array_filter($weights, fn($l) => $l <= $remaining, ARRAY_FILTER_USE_KEY);
if (empty($validWeights)) $validWeights = [min(array_keys($weights)) => 1];
$rand = mt_rand(1, array_sum($validWeights));
$accum = 0;
$chunkLen = null;
foreach ($validWeights as $l => $w) {
$accum += $w;
if ($rand <= $accum) {
$chunkLen = $l;
break;
}
}
$chunkLen ??= min(array_keys($validWeights));
$result[] = substr($str, $pos, $chunkLen);
$pos += $chunkLen;
}
return $result;
}
?>
效能提示
- 使用
mt_rand() 而非 rand()(速度更快、隨機品質更好)
- 大量分割時預先分配陣列大小:
$result = []; $result[] = ... PHP 會自動優化
- 多位元組版本若效能敏感,考慮先轉為字符陣列再操作