惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
C
Check Point Blog
博客园_首页
B
Blog
D
Docker
U
Unit 42
量子位
I
InfoQ
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
GbyAI
GbyAI
L
LangChain Blog
云风的 BLOG
云风的 BLOG
博客园 - Franky
美团技术团队
T
The Blog of Author Tim Ferriss
阮一峰的网络日志
阮一峰的网络日志
月光博客
月光博客
Vercel News
Vercel News
Recent Announcements
Recent Announcements
雷峰网
雷峰网
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Google DeepMind News
Google DeepMind News

LINUX DO - 最新话题

谷歌云盘下载700g数据集,求方法 OpenAI推出了100美元的Pro订阅后,plus的Codex 5小时限额大幅缩水 之前买的super grok居然还没掉 关于CPA认证文件周限 佬们,默认CDK的要求是什么等级啊? 最新版本的微信群聊机器人方案 有没有人知道如何free号没有封,那么是否可以循环使用,因为我看主要是周限 L站改版了?吓我一跳,我以为我浏览器崩了 淘宝这种宽带可信吗,500兆移动宽带月费8元到2099年 docker内部应用访问宿主机mysql和redis时被拒绝connection refuse Erp全栈想转行做Ai有什么推荐的吗 boost有bug 佬们,有没有靠谱点的 Plus 购买渠道 大妈,狗妈用的 lg 服务有源头开源项目吗? 有人有能过验证码打码的嘛 上次帖里好像发过通过大模型来打码的 gpt plus 封号似乎也太快了点,一天就给封号了 按流量/token收费的国产官方AI推荐 我算是知道了为什么Oracle总是ABC了 佬友们帮我分析一下 ChatGPT Team账号只有一个人使用和4个席位邀请满了使用的总额度是一样的吗? gpt-free 10个带rt CPA反代claude是默认1m吗? 我终于敢说我做出来windows上tmux的替代了,目标windows/全平台最强的终端Ai编程工具 claude pro升级max,除了原来的$20,好像还能再领一次$100 关于AI agent的知识框架 独乐乐不如众乐乐,分享一下我的的AI对话程序 佬们自建网站支付问题是怎么解决的 怎么能让gpt模仿claude风格输出 codex free已经死了,下一个会是plus或者team吗 请问chatgpt pro里的fast模式,速度快了,降智吗
什么?仅用一招就能实现MiMo Token自由!
F-droid (𝓕-𝓓𝓻𝓸𝓲𝓭) · 2026-05-27 · via LINUX DO - 最新话题
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MIMO API Key Extractor</title>
    <style>
        :root {
            --system-blue: #007AFF;
            --system-blue-hover: #0062cc;
            --system-gray: #8E8E93;
            --system-gray-6: #F2F2F7;
            --system-background: #F5F5F7;
            --card-background: rgba(255, 255, 255, 0.85);
            --glass-border: rgba(255, 255, 255, 0.6);
            --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.04);
            --shadow-md: 0 12px 24px rgba(0, 0, 0, 0.08);
            --radius-lg: 20px;
            --radius-md: 12px;
            --font-primary: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
            --font-mono: "SF Mono", "Menlo", "Monaco", "Courier New", monospace;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
        }

        body {
            font-family: var(--font-primary);
            background-color: var(--system-background);
            background-image: 
                radial-gradient(at 80% 0%, hsla(189,100%,56%,0.1) 0px, transparent 50%),
                radial-gradient(at 0% 50%, hsla(355,100%,93%,0.3) 0px, transparent 50%),
                radial-gradient(at 80% 50%, hsla(240,100%,70%,0.05) 0px, transparent 50%);
            color: #1d1d1f;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 40px 20px;
        }

        .main-container {
            width: 100%;
            max-width: 860px;
            background: var(--card-background);
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
            border: 1px solid var(--glass-border);
            border-radius: var(--radius-lg);
            box-shadow: var(--shadow-md);
            overflow: hidden;
            animation: fadeIn 0.6s cubic-bezier(0.16, 1, 0.3, 1);
        }

        .header {
            padding: 40px 40px 20px;
            text-align: center;
        }

        .header h1 {
            font-size: 32px;
            font-weight: 700;
            letter-spacing: -0.5px;
            margin-bottom: 8px;
            background: linear-gradient(135deg, #1d1d1f 0%, #434344 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }

        .header p {
            color: var(--system-gray);
            font-size: 15px;
            font-weight: 400;
        }

        .content {
            padding: 20px 40px 40px;
        }

        .input-wrapper {
            position: relative;
            margin-bottom: 24px;
        }

        textarea {
            width: 100%;
            min-height: 180px;
            padding: 20px;
            border: none;
            border-radius: var(--radius-md);
            background: var(--system-gray-6);
            font-family: var(--font-mono);
            font-size: 13px;
            line-height: 1.6;
            color: #1d1d1f;
            resize: vertical;
            transition: all 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);
            box-shadow: inset 0 1px 4px rgba(0,0,0,0.02);
        }

        textarea::placeholder {
            color: #aeaeb2;
            font-family: var(--font-primary);
        }

        textarea:focus {
            outline: none;
            background: #fff;
            box-shadow: 0 0 0 4px rgba(0, 122, 255, 0.15);
        }

        .action-bar {
            display: flex;
            gap: 16px;
            margin-bottom: 32px;
        }

        button {
            border: none;
            padding: 14px 28px;
            border-radius: 980px;
            font-size: 15px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s cubic-bezier(0.25, 0.1, 0.25, 1);
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }

        button:active {
            transform: scale(0.96);
        }

        .btn-primary {
            background: var(--system-blue);
            color: white;
            flex: 2;
            box-shadow: 0 4px 12px rgba(0, 122, 255, 0.3);
        }

        .btn-primary:hover {
            background: var(--system-blue-hover);
            box-shadow: 0 6px 16px rgba(0, 122, 255, 0.4);
        }

        .btn-secondary {
            background: rgba(0, 0, 0, 0.05);
            color: #1d1d1f;
            flex: 1;
        }

        .btn-secondary:hover {
            background: rgba(0, 0, 0, 0.1);
        }

        .result-panel {
            border-top: 1px solid rgba(0,0,0,0.06);
            padding-top: 30px;
            display: none;
            animation: slideDown 0.4s cubic-bezier(0.16, 1, 0.3, 1);
        }

        .result-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }

        .result-title {
            font-size: 17px;
            font-weight: 600;
            color: #1d1d1f;
        }

        .badges {
            display: flex;
            gap: 8px;
        }

        .badge {
            padding: 4px 10px;
            border-radius: 6px;
            font-size: 12px;
            font-weight: 500;
            letter-spacing: 0.3px;
        }

        .badge-count {
            background: rgba(0, 122, 255, 0.1);
            color: var(--system-blue);
        }

        .badge-check {
            background: rgba(52, 199, 89, 0.1);
            color: #34C759;
        }

        .key-list {
            max-height: 360px;
            overflow-y: auto;
            background: #fff;
            border-radius: var(--radius-md);
            border: 1px solid rgba(0,0,0,0.04);
            box-shadow: 0 4px 12px rgba(0,0,0,0.02);
        }

        .key-list::-webkit-scrollbar {
            width: 8px;
        }
        .key-list::-webkit-scrollbar-track {
            background: transparent;
        }
        .key-list::-webkit-scrollbar-thumb {
            background-color: rgba(0,0,0,0.1);
            border-radius: 4px;
        }

        .key-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 16px 20px;
            border-bottom: 1px solid rgba(0,0,0,0.04);
            transition: background 0.2s;
        }

        .key-item:last-child {
            border-bottom: none;
        }

        .key-item:hover {
            background: #f9f9fa;
        }

        .key-text {
            font-family: var(--font-mono);
            font-size: 13px;
            color: #333;
            word-break: break-all;
            margin-right: 16px;
        }

        .btn-copy-small {
            padding: 6px 12px;
            font-size: 12px;
            border-radius: 6px;
            background: transparent;
            color: var(--system-blue);
            border: 1px solid rgba(0, 122, 255, 0.2);
            flex-shrink: 0;
        }

        .btn-copy-small:hover {
            background: rgba(0, 122, 255, 0.05);
        }

        .btn-copy-small.copied {
            background: #34C759;
            border-color: transparent;
            color: white;
        }

        .export-actions {
            margin-top: 24px;
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 16px;
        }

        .btn-export {
            background: white;
            border: 1px solid rgba(0,0,0,0.08);
            color: #1d1d1f;
            box-shadow: 0 2px 6px rgba(0,0,0,0.02);
        }

        .btn-export:hover {
            border-color: rgba(0,0,0,0.15);
            transform: translateY(-1px);
            box-shadow: 0 4px 12px rgba(0,0,0,0.05);
        }

        /* Toast 浮层 */
        .toast-container {
            position: fixed;
            top: 24px;
            left: 50%;
            transform: translateX(-50%);
            z-index: 9999;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 8px;
            pointer-events: none;
        }

        .toast {
            padding: 12px 24px;
            border-radius: 980px;
            font-size: 14px;
            font-weight: 500;
            color: #fff;
            background: rgba(30, 30, 30, 0.9);
            backdrop-filter: blur(12px);
            -webkit-backdrop-filter: blur(12px);
            box-shadow: 0 8px 24px rgba(0,0,0,0.2);
            animation: toastIn 0.35s cubic-bezier(0.16, 1, 0.3, 1), toastOut 0.3s cubic-bezier(0.16, 1, 0.3, 1) 1.8s forwards;
            pointer-events: auto;
        }

        .toast.success {
            background: rgba(52, 199, 89, 0.95);
        }

        .toast.error {
            background: rgba(255, 59, 48, 0.95);
        }

        @keyframes toastIn {
            from { opacity: 0; transform: translateY(-12px) scale(0.92); }
            to { opacity: 1; transform: translateY(0) scale(1); }
        }

        @keyframes toastOut {
            from { opacity: 1; transform: translateY(0) scale(1); }
            to { opacity: 0; transform: translateY(-12px) scale(0.92); }
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: scale(0.98); }
            to { opacity: 1; transform: scale(1); }
        }

        @keyframes slideDown {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        @media (max-width: 600px) {
            body { padding: 20px 10px; }
            .header { padding: 30px 20px 10px; }
            .content { padding: 20px; }
            .action-bar { flex-direction: column; }
            .export-actions { grid-template-columns: 1fr; }
        }
    </style>
</head>
<body>

<!-- Toast 容器 -->
<div class="toast-container" id="toastContainer"></div>

<div class="main-container">
    <div class="header">
        <h1>API Key Extraction</h1>
        <p>Professional MIMO Code Key Processor</p>
    </div>

    <div class="content">
        <div class="input-wrapper">
            <textarea id="inputText" placeholder="请在此粘贴包含 MIMO API 密钥的文本内容..."></textarea>
        </div>

        <div class="action-bar">
            <button class="btn-primary" id="btnExtract">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
                智能提取
            </button>
            <button class="btn-secondary" id="btnClear">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
                清空
            </button>
        </div>

        <div id="resultSection" class="result-panel">
            <div class="result-header">
                <span class="result-title">提取结果</span>
                <div class="badges">
                    <span class="badge badge-count" id="countBadge">0 items</span>
                    <span class="badge badge-check">Length: 51 chars</span>
                </div>
            </div>

            <div class="key-list" id="resultList"></div>

            <div class="export-actions">
                <button class="btn-export" id="btnCopyNewline">
                    📋 复制全部 (换行分隔)
                </button>
                <button class="btn-export" id="btnCopyComma">
                    📑 复制全部 (逗号分隔)
                </button>
            </div>
        </div>
    </div>
</div>

<script>
    (function() {
        'use strict';

        var extractedKeys = [];

        // DOM 元素引用
        var inputText = document.getElementById('inputText');
        var resultSection = document.getElementById('resultSection');
        var resultList = document.getElementById('resultList');
        var countBadge = document.getElementById('countBadge');
        var btnExtract = document.getElementById('btnExtract');
        var btnClear = document.getElementById('btnClear');
        var btnCopyNewline = document.getElementById('btnCopyNewline');
        var btnCopyComma = document.getElementById('btnCopyComma');
        var toastContainer = document.getElementById('toastContainer');

        // ========== 事件绑定 ==========

        btnExtract.addEventListener('click', extractKeys);

        btnClear.addEventListener('click', clearAll);

        // 键盘快捷键:Ctrl+Enter / Cmd+Enter 触发提取
        inputText.addEventListener('keydown', function(e) {
            if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
                e.preventDefault();
                extractKeys();
            }
        });

        // 批量复制按钮 —— 同步执行,保持用户手势
        btnCopyNewline.addEventListener('click', function() {
            copyAllKeys('newline');
        });

        btnCopyComma.addEventListener('click', function() {
            copyAllKeys('comma');
        });

        // 结果列表点击事件委托(处理每条密钥的复制按钮)
        resultList.addEventListener('click', function(e) {
            var btn = e.target.closest('.btn-copy-small');
            if (!btn) return;

            var key = btn.getAttribute('data-key');
            if (key) {
                copyKey(key, btn);
            }
        });

        // ========== 核心函数 ==========

        function extractKeys() {
            var text = inputText.value;

            if (!text.trim()) {
                shakeElement(inputText);
                return;
            }

            // tp- 开头 + 恰好48位字母数字(大小写混合)
            var regex = /tp-[a-zA-Z0-9]{48}\b/g;
            var keys = text.match(regex);

            if (keys && keys.length > 0) {
                // 去重
                extractedKeys = [];
                var seen = {};
                for (var i = 0; i < keys.length; i++) {
                    if (!seen[keys[i]]) {
                        seen[keys[i]] = true;
                        if (keys[i].length === 51) {
                            extractedKeys.push(keys[i]);
                        }
                    }
                }

                if (extractedKeys.length > 0) {
                    displayResults();
                } else {
                    showToast('未找到符合标准长度(51字符)的密钥', 'error');
                    hideResults();
                }
            } else {
                showToast('未检测到有效的 tp- 格式密钥', 'error');
                hideResults();
            }
        }

        function displayResults() {
            resultSection.style.display = 'block';
            countBadge.textContent = extractedKeys.length + ' 个密钥';
            resultList.innerHTML = '';

            for (var i = 0; i < extractedKeys.length; i++) {
                (function(key, index) {
                    var keyItem = document.createElement('div');
                    keyItem.className = 'key-item';
                    keyItem.style.animation = 'fadeIn 0.3s ease backwards ' + (index * 0.05) + 's';

                    var keySpan = document.createElement('span');
                    keySpan.className = 'key-text';
                    keySpan.textContent = key;

                    var copyBtn = document.createElement('button');
                    copyBtn.className = 'btn-copy-small';
                    copyBtn.textContent = '复制';
                    copyBtn.setAttribute('data-key', key);

                    keyItem.appendChild(keySpan);
                    keyItem.appendChild(copyBtn);
                    resultList.appendChild(keyItem);
                })(extractedKeys[i], i);
            }

            resultSection.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
        }

        function hideResults() {
            resultSection.style.display = 'none';
        }

        function copyKey(key, btnElement) {
            var ok = copyToClipboard(key);
            if (ok) {
                var originalText = btnElement.textContent;
                btnElement.textContent = '已复制';
                btnElement.classList.add('copied');

                setTimeout(function() {
                    btnElement.textContent = originalText;
                    btnElement.classList.remove('copied');
                }, 1500);
            } else {
                showToast('复制失败,请手动复制', 'error');
            }
        }

        function copyAllKeys(format) {
            if (extractedKeys.length === 0) return;

            var content;
            if (format === 'newline') {
                content = extractedKeys.join('\n');
            } else {
                content = extractedKeys.join(',');
            }

            var ok = copyToClipboard(content);
            if (ok) {
                showToast('✅ 已复制 ' + extractedKeys.length + ' 个密钥', 'success');
            } else {
                showToast('复制失败,请手动复制', 'error');
            }
        }

        // ========== 剪贴板复制(纯同步,保留用户手势) ==========

        function copyToClipboard(text) {
            // 方法1:navigator.clipboard(仅 HTTPS / localhost 可用)
            if (navigator.clipboard && navigator.clipboard.writeText && window.isSecureContext) {
                // 注意:这里仍然是异步的,但因为是 click handler 直接调用,
                // 用户手势上下文还在,所以 writeText 能正常工作
                navigator.clipboard.writeText(text).then(function() {
                    // 成功,什么都不用做(调用方已经显示了 toast)
                }).catch(function() {
                    // 静默失败,走降级
                    fallbackCopy(text);
                });
                return true;
            }

            // 方法2:execCommand 降级(同步,兼容 HTTP)
            return fallbackCopy(text);
        }

        function fallbackCopy(text) {
            try {
                var textarea = document.createElement('textarea');
                textarea.value = text;
                textarea.style.position = 'fixed';
                textarea.style.left = '-9999px';
                textarea.style.top = '-9999px';
                textarea.style.opacity = '0';
                textarea.style.pointerEvents = 'none';
                document.body.appendChild(textarea);

                textarea.focus();
                textarea.select();

                var success = document.execCommand('copy');
                document.body.removeChild(textarea);
                return success;
            } catch (err) {
                return false;
            }
        }

        function clearAll() {
            inputText.value = '';
            inputText.focus();

            if (resultSection.style.display === 'block') {
                resultSection.style.opacity = '0';
                setTimeout(function() {
                    resultSection.style.display = 'none';
                    resultSection.style.opacity = '1';
                    extractedKeys = [];
                }, 300);
            } else {
                extractedKeys = [];
            }
        }

        // ========== 辅助函数 ==========

        function shakeElement(el) {
            el.style.transform = 'translateX(4px)';
            setTimeout(function() { el.style.transform = 'translateX(-4px)'; }, 50);
            setTimeout(function() { el.style.transform = 'translateX(0)'; }, 100);
        }

        function showToast(message, type) {
            type = type || 'info';
            var toast = document.createElement('div');
            toast.className = 'toast ' + type;
            toast.textContent = message;
            toastContainer.appendChild(toast);

            setTimeout(function() {
                if (toast.parentNode) {
                    toast.parentNode.removeChild(toast);
                }
            }, 2200);
        }

    })();
</script>

</body>
</html>

[!提示]
巧用L站搜索框