各位吾爱的大佬、道友们好!
经常使用蓝奏云分发软件或资料的道友应该深有体会:蓝奏云下载体验虽然不限速,但上传文件有一个问题——**非会员单文件上传限制在 100MB 以内**。
为了彻底解决这个痛点,我用纯原生PHP开发了一套独立的蓝奏云后端REST API 服务。
项目的两大核心精髓:
1. 🚀 突破/破解 100MB 上传限制:任意大文件(如 500MB、2GB+)上传时,程序自动将其切割为伪装切片包(后缀伪装为 `.zip`/`.doc` 等合法扩展名),并在云端自动建立索引归档!
2. ⚡ 自动流式分段下载与无缝拼接合并:解析下载时,API 自动拉取所有切片包,剔除伪装报尾 Padding,无缝拼合还原为原始完整大文件,下载完毕中转缓存自动销毁。
程序无需第三方 Composer 依赖,PHP 7.4/8.x 开箱即用。
同时还附带了一个前端 演示面板 (`index.html`),部署后可以直接在浏览器里体验大文件切片上传、无缝合并下载!
今天把全套后端 API 源码与大文件切片合并算法一并分享给大家!
🔥 核心两大突破性功能
1. 🚀 突破 100MB 上传限制 (伪装切片 + 索引归档)
- 当上传的文件超过 100MB 阈值(可自定义 10~100MB)时,程序会自动在蓝奏云创建一个专属大文件目录。
- 将文件切割为若干个合规大小的切片数据块,并随机赋予合法伪装后缀(如 `.zip`/`.docx`/`.apk`)。
- 切片全部上传完成后,自动生成 `record.txt` JSON 索引文件,记录文件名、总大小及切片列表,完成大文件归档。
2. ⚡自动分段无缝拼接合并下载
- 解析大文件目录时,API 会自动解析 `record.txt` 索引并按顺序获取所有 `part_xxx` 切片的直链。
- 后端逐块下载切片,**自动识别并裁剪切片尾部的 512B 伪装数据**,然后通过流式 Buffering 追加拼合为原始文件。
- 下载接口支持 SSE (Server-Sent Events) 长连接,实时推送【1.分段下载 -> 2.服务器合并校验 -> 3.客户端保存与中转自动销毁】。
🛠️ 核心突破代码解析
1. 大文件切片无缝拼接合并与去除 512B 报尾 Padding
这是大文件无缝合并下载的核心算法。下载时不仅要按索引按顺序拉取切片,还要自动识别并截断切片尾部 512B 的随机防屏蔽 Padding,再进行 4MB 数据流追加拼合:
[PHP] 纯文本查看 复制代码 /**
* 内部下载并无缝合并大文件切片
*/
private function _downBigFile(array $bigFileInfo, string $savePath, bool $overwrite, ?callable $callback): int {
$record = $bigFileInfo['record'];
$files = $bigFileInfo['files'];
$fileName = $record['name'];
$totalSize = (int)$record['size'];
$parts = $record['parts']; // 获取切片索引列表
$filePath = rtrim($savePath, '/\\') . DIRECTORY_SEPARATOR . $fileName;
$outFp = fopen($filePath, 'wb');
if (!$outFp) return self::PATH_ERROR;
$downloadedTotal = 0;
foreach ($parts as $partIndex => $partName) {
$partFile = $this->_findPartFile($partName, $files);
$durlInfo = $this->getDirectUrlByUrl($partFile->url, $bigFileInfo['pwd']);
// 创建临时文件接收切片
$tmpChunkPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'lz_part_' . uniqid() . '.tmp';
$tmpFp = fopen($tmpChunkPath, 'w+b');
$ch = curl_init($durlInfo->durl);
curl_setopt($ch, CURLOPT_FILE, $tmpFp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// 累积进度计算(切换切片时总体进度条保持递增,不会重置)
if (is_callable($callback)) {
$baseBytes = $downloadedTotal;
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function($ch, $dltotal, $dlnow) use ($callback, $fileName, $totalSize, $baseBytes, $partIndex, $parts, $partName) {
if ($dlnow > 0) {
$now = $baseBytes + (int)$dlnow;
$callback($fileName, $totalSize, min($now, $totalSize), $partIndex + 1, count($parts), $partName, (int)$dlnow, (int)$dltotal);
}
});
}
curl_exec($ch);
curl_close($ch);
// 【关键逻辑】识别并裁剪切片尾部 512B 的伪装填充 (Padding)
$chunkSize = filesize($tmpChunkPath);
if ($chunkSize > 512) {
fseek($tmpFp, -512, SEEK_END);
$tail = fread($tmpFp, 512);
if (str_contains($tail, 'padding')) {
ftruncate($tmpFp, $chunkSize - 512); // 截断剔除 512 字节报尾
}
}
// 4MB 缓冲区流式追加写入合并主文件
fseek($tmpFp, 0);
while (!feof($tmpFp)) {
$buf = fread($tmpFp, 4194304);
if ($buf === false || $buf === '') break;
fwrite($outFp, $buf);
}
fclose($tmpFp);
@unlink($tmpChunkPath); // 及时清理临时切片
$downloadedTotal = filesize($filePath);
}
fclose($outFp);
return self::SUCCESS;
}
2. 流式输出与临时中转缓存“秒删销毁”
为保证服务端做代理合并下载时磁盘0 残留,后端通过流式 Output 推送给客户端,传输完成后立刻销毁中转目录:
[PHP] 纯文本查看 复制代码 /**
* 附件流输出,传输完毕立即销毁服务器中转临时文件
*/
function streamFileToClientAndDestroy(string $filePath, ?string $transitDir = null): void {
if (!file_exists($filePath)) jsonResponse(404, '文件不存在或已被销毁');
$fileName = basename($filePath);
$fileSize = filesize($filePath);
while (ob_get_level()) @ob_end_clean();
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . rawurlencode($fileName) . '"');
header('Content-Length: ' . $fileSize);
$handle = fopen($filePath, 'rb');
if ($handle) {
while (!feof($handle) && !connection_aborted()) {
echo fread($handle, 1048576); // 1MB 缓冲区流式吐给客户端
@flush();
}
fclose($handle);
}
// 传输完毕或断开连接后,立刻瞬间销毁磁盘中转文件与临时目录
@unlink($filePath);
if ($transitDir && is_dir($transitDir)) {
cleanupTransitDir($transitDir);
}
exit;
}
3. ESA `acw_sc__v2` 挑战算法纯 PHP 逆向求解
当蓝奏云触发 ESA 防爬校验时,后端直接通过代码解密混淆算法,求解 `acw_sc__v2` Cookie 响应头:
[PHP] 纯文本查看 复制代码 /**
* 纯 PHP 解密蓝奏云 acw_sc__v2 反爬屏障
*/
public static function calcAcwScV2(string $htmlText): string {
if (preg_match("/arg1='([0-9A-Z]+)'/", $htmlText, $matches)) {
$arg1 = $matches[1];
return self::hexXor(self::unsbox($arg1), "3000176000856006061501533003690027800375");
}
return '';
}
💻 后端 API 调用与接口测试截图
部署好 `api.php` 后,你的第三方客户端、小程序或 Python 脚本即可方便调用:
1. 免登录单文件直链解析 API
[Bash shell] 纯文本查看 复制代码 curl "http://你的域名/api.php?action=parse_file&url=https://pan.lanzouo.com/i123456&pwd=1234"
返回 JSON 结构:
[PHP] 纯文本查看 复制代码 {
"code": 0,
"msg": "解析成功 (已识别为切片合并大文件)",
"data": {
"name": "超大软件安装包.zip",
"size": "350.5 MB",
"is_big_file": true
}
}
2. 大文件极速上传与多通道并发传输演示
📦 源码下载说明
本程序纯做后端 API 接口开发,代码无任何商业化残留、无广告推广链接。
全套源码已打成压缩包上传至论坛附件:
- **解压密码**:`52pojie`
- **环境要求**:PHP 7.4 ~ 8.2 (开启 cURL 和 mbstring 扩展即可)
感觉有帮助的大佬道友们,顺手点个赞或者加个热度/吾爱币,感谢支持!有任何疑问或建议欢迎在楼下留言交流!
蓝奏云接口.zip
(58.06 KB, 下载次数: 97)
|