SkillRack Math Captcha Solver

Solves Math Captcha on the SkillRack website using Tesseract.js.

当前为 2024-11-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name SkillRack Math Captcha Solver
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4
  5. // @description Solves Math Captcha on the SkillRack website using Tesseract.js.
  6. // @author Bit-Blazer
  7. // @license GNU GPLv3
  8. // @match https://www.skillrack.com/faces/candidate/codeprogram.xhtml
  9. // @match https://www.skillrack.com/faces/candidate/tutorprogram.xhtml
  10. // @icon https://envs.sh/GiG.png
  11. // @require https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js
  12. // @grant none
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. "use strict";
  17.  
  18. // Define the IDs of the captcha image, input field, and proceed button
  19. const CAPTCHA_INPUT = "capval";
  20. const PROCEED_BTN = "proceedbtn";
  21.  
  22. /**
  23. * Inverts the colors of the Captcha Image for better OCR results.
  24. * This is useful for enhancing the text recognition capability of Tesseract.js.
  25. * @param {HTMLImageElement} image - The image to be inverted.
  26. * @returns {string} - Base64 encoded data URL of the inverted image.
  27. */
  28. function invertColors(image) {
  29. const canvas = document.createElement("canvas");
  30. const ctx = canvas.getContext("2d");
  31. canvas.width = image.width;
  32. canvas.height = image.height;
  33. ctx.drawImage(image, 0, 0);
  34. ctx.globalCompositeOperation = "difference"; // Invert colors
  35. ctx.fillStyle = "white"; // Set background to white
  36. ctx.fillRect(0, 0, canvas.width, canvas.height); // Fill the canvas
  37. return canvas.toDataURL(); // Return the inverted image as a data URL
  38. }
  39.  
  40. /**
  41. * Extracts the username from the span element.
  42. * This function looks for the username pattern in the badge label.
  43. * @returns {string} - The extracted username or an empty string if not found.
  44. */
  45. function getUsername() {
  46. const usernameElement = document.querySelector(".ui-badge-label"); // Select the username element
  47. const match = usernameElement
  48. ? usernameElement.textContent.match(/(\d{12}@\w{3})/)
  49. : null; // Match the username pattern
  50. return match ? match[0] : ""; // Return the matched username or empty string
  51. }
  52.  
  53. /**
  54. * Solves the captcha by extracting numbers and performing the calculation.
  55. * @param {string} text - The OCR result from the captcha image.
  56. * @param {string} username - The username to be removed from the OCR text.
  57. * @returns {number|null} - The result of the addition or null if not found.
  58. */
  59. function solveCaptcha(text, username) {
  60. // Remove the username from the OCR text and trim whitespace
  61. const cleanedText = text.replace(new RegExp(username, "gi"), "").trim();
  62. // Match the addition pattern in the cleaned text
  63. const match = cleanedText.match(/(\d+)\s*\+\s*(\d+)/);
  64. // Return the sum of the two numbers if a match is found
  65. return match ? parseInt(match[1], 10) + parseInt(match[2], 10) : null;
  66. }
  67.  
  68. /**
  69. * Handles the captcha-solving process.
  70. * This function orchestrates the overall captcha solving by coordinating image processing and user interactions.
  71. */
  72. async function handleCaptcha() {
  73. // Get the captcha elements from the DOM
  74. const captchaImage = document.querySelector("img[src*='data:image']");
  75. const captchaInput = document.getElementById(CAPTCHA_INPUT);
  76. const proceedBtn = document.getElementById(PROCEED_BTN);
  77.  
  78. // Log an error and exit if any elements are not found
  79. if (!captchaImage || !captchaInput || !proceedBtn) {
  80. console.log("Captcha or input elements not found.");
  81. return; // Stop execution
  82. }
  83.  
  84. // Get the username from the UI
  85. const username = getUsername();
  86. // Invert the colors of the captcha image for better OCR processing
  87. const invertedImg = invertColors(captchaImage);
  88.  
  89. try {
  90. // Process the inverted image using Tesseract.js for OCR
  91. const {
  92. data: { text },
  93. } = await Tesseract.recognize(invertedImg, "eng", {
  94. whitelist:
  95. "1234567890+=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@ ", // Allowed characters
  96. psm: 6, // Page segmentation mode
  97. });
  98.  
  99. // Solve the Captcha using the OCR text and username
  100. const result = solveCaptcha(text, username);
  101. // Notify if the captcha could not be solved
  102. if (result === null) {
  103. console.log("Unable to solve Captcha. Please try again.");
  104. return; // Stop execution
  105. }
  106. // Fill the captcha input with the calculated result
  107. captchaInput.value = result;
  108. // Click the submit button to proceed
  109. proceedBtn.click();
  110. } catch (error) {
  111. // Log any errors encountered during the OCR process
  112. console.error("Error processing captcha:", error);
  113. alert(
  114. "An error occurred while processing the captcha. Please try again."
  115. ); // Notify user
  116. }
  117. }
  118.  
  119. // Wait for the window to fully load before handling the captcha
  120. window.addEventListener("load", handleCaptcha);
  121. })();