<!DOCTYPE html>
  <html>
    <head>
    <title>PHP字符串解码工具</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pako/2.1.0/pako.min.js"></script>
      <style>
        body {
        font-family: Arial, sans-serif;
        max-width: 800px;
        margin: 0 auto;
        padding: 20px;
        line-height: 1.6;
        }
        .result {
        margin-top: 20px;
        padding: 15px;
        border: 1px solid #ddd;
        border-radius: 5px;
        background-color: #f9f9f9;
        }
        .json-result {
        background-color: #f0f8ff;
        border-color: #add8e6;
        }
        .text-result {
        background-color: #fff8e1;
        border-color: #ffd700;
        }
        .error-result {
        background-color: #ffe6e6;
        border-color: #ff6b6b;
        }
        pre {
        white-space: pre-wrap;
        word-wrap: break-word;
        }
        h2 {
        color: #333;
        }
        button {
        padding: 8px 16px;
        background-color: #4caf50;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        }
        button:hover {
        background-color: #45a049;
        }
      </style>
    </head>
    <body>
    <h1>PHP字符串解码工具</h1>
    <p>该工具用于解码PHP gzcompress编码的字符串。</p>
        <div class="result" id="resultContainer">
      <h2>解码结果将显示在这里</h2>
      </div>
      <script>
        function decodePhpGzcompress(encodedStr) {
        try {
        console.log("开始解码...");
        // 1. 手动解析URL编码
        const bytes = [];
        let i = 0;
        encodedStr = encodedStr.replace(/\+/g, " ");  //去掉空格
        while (i < encodedStr.length) {
        if (encodedStr[i] === "%") {
        const hex = encodedStr.substring(i + 1, i + 3);
        bytes.push(parseInt(hex, 16));
        i += 3;
        } else {
        bytes.push(encodedStr.charCodeAt(i));
        i += 1;
        }
        }
        console.log("解析出的字节:", bytes);
        // 2. 跳过zlib头(前2字节)
        const rawData = new Uint8Array(bytes).subarray(2);
        console.log("去掉zlib头后的数据:", Array.from(rawData));
        // 3. 使用inflateRaw解压缩
        const decompressed = pako.inflateRaw(rawData);
        console.log("解压缩后的字节:", Array.from(decompressed));
        // 4. 正确转换为字符串(使用TextDecoder)
        const textDecoder = new TextDecoder("utf-8", { fatal: false });
        let decodedString = textDecoder.decode(decompressed);
        console.log("转换为字符串:", decodedString);
        // 5. 清理非法JSON字符
        decodedString = cleanJsonString(decodedString);
        console.log("清理后的字符串:", decodedString);
        // 6. JSON解析 - 增强版错误处理
        try {
        // 首先检查是否为空字符串
        if (!decodedString || decodedString.trim() === "") {
        console.log("解码结果为空字符串");
        return {
        success: true,
        type: "text",
        content: "",
        message: "解码成功,结果为空字符串",
        };
        }
        const parsed = JSON.parse(decodedString);
        console.log("最终结果(JSON):", parsed);
        return {
        success: true,
        type: "json",
        content: parsed,
        message: "解码成功,结果为JSON对象",
        };
        } catch (jsonError) {
        console.warn("标准JSON解析失败,返回纯文本...");
        // 如果JSON解析失败,返回原始解码后的文本
        return {
        success: true,
        type: "text",
        content: decodedString,
        message: "解码成功,结果为文本(非JSON格式)",
        originalError: jsonError.message,
        };
        }
        } catch (error) {
        console.error("解码失败:", error);
        return {
        success: false,
        type: "error",
        content: null,
        message: "解码过程发生错误",
        error: error.message,
        };
        }
        }
        // 清理JSON字符串中的非法字符
        function cleanJsonString(str) {
        // 移除非ASCII可打印字符
        return str
        .replace(
        /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\uFFFF]/g,
        function (match) {
        // 保留换行和制表符,其他替换为空
        if (match === "\n" || match === "\t") return match;
        return "";
        }
        )
        .trim(); // 去除首尾空白
        }
        // 使用示例
        const encodedStr =
        "x%9C%ABVJI%2CIT%B22%D4Q%2A%C9%2C%C9IU%B2RJOW%AA%05%00V%1E%07+";
        const result = decodePhpGzcompress(encodedStr);
        console.log("解码结果:", result);
        // 显示结果到页面
        displayResult(result);
      </script>
    </body>
  </html>