SkillRack Math Captcha Solver

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

目前为 2024-10-26 提交的版本。查看 最新版本

  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/codeprogramgroup.xhtml
  9. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  10. // @require https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. "use strict";
  16.  
  17. // Define the IDs of the captcha image, input field, and proceed button
  18. const CAPTCHA_IMAGE = "j_id_78";
  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 specified 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 ? usernameElement.textContent.match(/(\d{12}@\w{3})/) : null; // Match the username pattern
  48. return match ? match[0] : ""; // Return the matched username or empty string
  49. }
  50.  
  51. /**
  52. * Solves the captcha by extracting numbers and performing the calculation.
  53. * @param {string} text - The OCR result from the captcha image.
  54. * @param {string} username - The username to be removed from the OCR text.
  55. * @returns {number|null} - The result of the addition or null if not found.
  56. */
  57. function solveCaptcha(text, username) {
  58. // Remove the username from the OCR text and trim whitespace
  59. const cleanedText = text.replace(new RegExp(username, "gi"), "").trim();
  60. // Match the addition pattern in the cleaned text
  61. const match = cleanedText.match(/(\d+)\s*\+\s*(\d+)/);
  62. // Return the sum of the two numbers if a match is found
  63. return match ? parseInt(match[1], 10) + parseInt(match[2], 10) : null;
  64. }
  65.  
  66. /**
  67. * Handles the captcha-solving process.
  68. * This function orchestrates the overall captcha solving by coordinating image processing and user interactions.
  69. */
  70. async function handleCaptcha() {
  71. // Get the captcha elements from the DOM
  72. const captchaImage = document.getElementById(CAPTCHA_IMAGE);
  73. const captchaInput = document.getElementById(CAPTCHA_INPUT);
  74. const proceedBtn = document.getElementById(PROCEED_BTN);
  75.  
  76. // Log an error and exit if any elements are not found
  77. if (!captchaImage || !captchaInput || !proceedBtn) {
  78. alert("Captcha or input elements not found."); // Notify user
  79. return; // Stop execution
  80. }
  81.  
  82. // Get the username from the UI
  83. const username = getUsername();
  84. // Invert the colors of the captcha image for better OCR processing
  85. const invertedImg = invertColors(captchaImage);
  86.  
  87. try {
  88. // Process the inverted image using Tesseract.js for OCR
  89. const { data: { text } } = await Tesseract.recognize(invertedImg, "eng", {
  90. whitelist: "1234567890+=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@ ", // Allowed characters
  91. psm: 6, // Page segmentation mode
  92. });
  93.  
  94. // Solve the Captcha using the OCR text and username
  95. const result = solveCaptcha(text, username);
  96. // Notify if the captcha could not be solved
  97. if (result === null) {
  98. alert("Unable to solve Captcha. Please try again.");
  99. return; // Stop execution
  100. }
  101. // Fill the captcha input with the calculated result
  102. captchaInput.value = result;
  103. // Click the submit button to proceed
  104. proceedBtn.click();
  105. } catch (error) {
  106. // Log any errors encountered during the OCR process
  107. console.error("Error processing captcha:", error);
  108. alert("An error occurred while processing the captcha. Please try again."); // Notify user
  109. }
  110. }
  111.  
  112. // Wait for the window to fully load before handling the captcha
  113. window.addEventListener("load", handleCaptcha);
  114. })();