您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Solves ALL basic math CAPTCHAs (+, -, *, /) in any format
// ==UserScript== // @name Universal Math CAPTCHA Solver // @namespace http://tampermonkey.net/ // @version 3.0 // @description Solves ALL basic math CAPTCHAs (+, -, *, /) in any format // @author ChrisN40 // @match *://*/* // @grant none // ==/UserScript== (function() { 'use strict'; const config = { checkInterval: 1000, maxAttempts: 3, retryDelay: 1000, mathPatterns: [ // Standard equation formats /(?:solve|calculate|what is|answer)\s*(?:the )?(?:following )?(?:math )?(?:problem|function|question)?[:]?\s*([\d+\-*\/=. ]+)/i, /([\d]+\s*[\+\-\*\/]\s*[\d]+)/, // Word problem formats /first number is (\d+)[^\d]+(\d+)[^\d]+([\+\-\*\/])/i, /sum of (\d+) and (\d+)/i, /add (\d+) (?:and|to) (\d+)/i, /subtract (\d+) (?:from|and) (\d+)/i, /product of (\d+) and (\d+)/i, /multiply (\d+) (?:and|by) (\d+)/i, /divide (\d+) (?:by|and) (\d+)/i, /(\d+) plus (\d+)/i, /(\d+) minus (\d+)/i, /(\d+) times (\d+)/i, /(\d+) multiplied by (\d+)/i, /(\d+) divided by (\d+)/i, // Special cases /how much is (\d+) ([\+\-\*\/]) (\d+)/i ] }; class UniversalMathSolver { constructor() { this.attempts = new WeakMap(); this.init(); } init() { console.log('Universal Math Solver initialized'); this.setupMutationObserver(); this.checkMathCaptchas(); setInterval(() => this.checkMathCaptchas(), config.checkInterval); } setupMutationObserver() { const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1 && this.isMathCaptcha(node.textContent)) { this.processMathElement(node); } }); }); }); observer.observe(document.body, { childList: true, subtree: true, characterData: true }); } checkMathCaptchas() { const textElements = document.querySelectorAll('div, p, span, label, td, li, b, strong, h1, h2, h3, h4, h5, h6'); textElements.forEach(element => { if (this.shouldProcessElement(element)) { this.processMathElement(element); } }); } shouldProcessElement(element) { if (!this.attempts.has(element)) { this.attempts.set(element, 0); } return this.attempts.get(element) < config.maxAttempts && this.isMathCaptcha(element.textContent); } isMathCaptcha(text) { if (!text) return false; return config.mathPatterns.some(pattern => pattern.test(text)); } processMathElement(element) { const attempts = this.attempts.get(element); this.attempts.set(element, attempts + 1); try { const mathProblem = this.extractMathProblem(element.textContent); if (mathProblem) { const solution = this.solveMathProblem(mathProblem); if (solution !== null) { this.fillSolution(solution, element); } } } catch (error) { console.error('Math CAPTCHA solve error:', error); if (attempts < config.maxAttempts - 1) { setTimeout(() => this.processMathElement(element), config.retryDelay); } } } extractMathProblem(text) { for (const pattern of config.mathPatterns) { const match = text.match(pattern); if (match) { // Handle word problems if (match[1] && match[2] && match[3]) { const num1 = parseFloat(match[1]); const num2 = parseFloat(match[2]); const operator = this.normalizeOperator(match[3]); // Handle subtraction word order ("subtract A from B" = B - A) if (match[0].includes('subtract') && operator === '-') { return `${num2}${operator}${num1}`; } return `${num1}${operator}${num2}`; } // Handle standard equations else if (match[1]) { return match[1].replace(/\s/g, ''); } } } return null; } normalizeOperator(op) { const opMap = { 'plus': '+', 'add': '+', 'sum': '+', 'minus': '-', 'subtract': '-', 'times': '*', 'multiplied': '*', 'product': '*', 'divide': '/', 'divided': '/' }; return opMap[op.toLowerCase()] || op; } solveMathProblem(problem) { try { // Clean and validate the expression const cleanExpr = problem.replace(/[^\d+\-*\/.]/g, ''); if (!/^[\d+\-*\/.]+$/.test(cleanExpr)) return null; // Split into tokens (numbers and operators) const tokens = cleanExpr.split(/([\+\-\*\/])/).filter(x => x); // Convert to numbers and operators const elements = []; for (const token of tokens) { if (['+', '-', '*', '/'].includes(token)) { elements.push({ type: 'operator', value: token }); } else { elements.push({ type: 'number', value: parseFloat(token) }); } } // First pass: multiplication and division for (let i = 0; i < elements.length; i++) { const el = elements[i]; if (el.type === 'operator' && (el.value === '*' || el.value === '/')) { const left = elements[i-1].value; const right = elements[i+1].value; let result; if (el.value === '*') { result = left * right; } else { if (right === 0) return '∞'; // Division by zero result = left / right; } // Replace the three elements (left, op, right) with result elements.splice(i-1, 3, { type: 'number', value: result }); i -= 2; // Adjust index after replacement } } // Second pass: addition and subtraction let result = elements[0].value; for (let i = 1; i < elements.length; i += 2) { const operator = elements[i].value; const number = elements[i+1].value; if (operator === '+') { result += number; } else { result -= number; } } // Round to 2 decimal places if needed return result % 1 === 0 ? result : parseFloat(result.toFixed(2)); } catch (e) { console.error('Math solving failed:', e); return null; } } fillSolution(solution, referenceElement) { const input = this.findInputField(referenceElement); if (!input) return false; // Try different methods to set the value const methods = [ () => { input.value = solution; return input.value == solution; }, () => { input.focus(); input.value = solution; this.triggerEvents(input); return input.value == solution; }, () => { const setter = Object.getOwnPropertyDescriptor( HTMLInputElement.prototype, 'value').set; setter.call(input, solution); this.triggerEvents(input); return input.value == solution; } ]; for (const method of methods) { try { if (method()) { console.log(`Solved: ${solution}`); return true; } } catch (e) { console.debug('Method failed:', e); } } return false; } findInputField(referenceElement) { const selectors = [ 'input[type="text"]', 'input[type="number"]', 'input:not([type])', 'textarea', '#answer', '#solution', '#captcha', '#mathAnswer' ]; // Check in parent containers let container = referenceElement; while (container) { for (const selector of selectors) { const input = container.querySelector(selector); if (input) return input; } container = container.parentElement; } // Check nearby elements const allInputs = document.querySelectorAll('input, textarea'); const refRect = referenceElement.getBoundingClientRect(); let closestInput = null; let minDistance = Infinity; allInputs.forEach(input => { const inputRect = input.getBoundingClientRect(); const distance = Math.sqrt( Math.pow(inputRect.left - refRect.left, 2) + Math.pow(inputRect.top - refRect.top, 2) ); if (distance < minDistance) { minDistance = distance; closestInput = input; } }); return closestInput; } triggerEvents(input) { ['focus', 'keydown', 'keypress', 'keyup', 'input', 'change', 'blur'].forEach(event => { input.dispatchEvent(new Event(event, { bubbles: true, cancelable: true })); }); } } // Start the solver new UniversalMathSolver(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址