Greasy Fork 支持简体中文。

NEU AAO Captcha filler

自动填充东北大学教务处验证码

// ==UserScript==
// @namespace         https://github.com/eleflea
// @name              NEU AAO Captcha filler
// @name:en           NEU AAO Captcha filler
// @name:zh           东北大学教务处验证码填充
// @name:zh-CN        东北大学教务处验证码填充
// @description       自动填充东北大学教务处验证码
// @description:en    Automatically fill the Northeastern University's aao website captcha
// @description:zh    自动填充东北大学教务处验证码
// @description:zh-CN 自动填充东北大学教务处验证码
// @include           *://aao.qianhao.aiursoft.com/*
// @include           *://202.118.31.197/*
// @include           *://aao.neu.edu.cn/*
// @include           *://zhjw.neu.edu.cn/*
// @supportURL        https://github.com/eleflea/neu_filler/
// @version           0.2.3
// @author            eleflea
// @grant             none
// ==/UserScript==

"use strict";

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

var aaoCaptcha = function aaoCaptcha(imgElement) {
    var token = {
        "*": "101111100011111010111",
        "+": "111101111000011111011",
        "1": "1011110000000011111111111111",
        "2": "1011100011101000101101111111",
        "3": "1011101011011010010001111111",
        "4": "1111011101101100000001111111",
        "5": "0000110010111001001101111111",
        "6": "1110001101011011100101111111",
        "7": "0111111011110001001110111111"
    };
    var box = [[7, 2, 17, 16], [19, 2, 27, 16], [33, 2, 43, 16]];

    function digit(box, threshold) {
        var min = 30;
        var num = 0;
        for (var i = 1; i < 8; i++) {
            var score = grayImg.compare.apply(grayImg, _toConsumableArray(box).concat([token[i.toString()]]));
            if (score < threshold) {
                return i;
            }
            if (score < min) {
                min = score;
                num = i;
            }
        }
        return num;
    }

    function operator(box, threshold) {
        var scorePlus = grayImg.compare.apply(grayImg, _toConsumableArray(box).concat([token["+"]]));
        var scoreMul = grayImg.compare.apply(grayImg, _toConsumableArray(box).concat([token["*"]]));
        if (scoreMul > scorePlus) {
            return 0;
        }
        return 1;
    }

    function identify(threshold) {
        var num1 = digit(box[0], threshold);
        var num2 = digit(box[2], threshold);
        var op = operator(box[1], threshold);
        return op ? num1 * num2 : num1 + num2;
    }

    function removeNoise() {
        for (var y = 1; y < height - 1; y++) {
            for (var x = 1; x < height - 1; x++) {
                if (!grayImg.at(x, y) && grayImg.at(x - 1, y) && grayImg.at(x, y - 1) && grayImg.at(x + 1, y) && grayImg.at(x, y + 1)) {
                    grayImg.set(x, y, 1);
                }
            }
        }
    }

    // get imgData
    var canvasElement = document.createElement('canvas');
    var height = imgElement.height;
    var width = imgElement.width;
    canvasElement.height = height;
    canvasElement.width = width;
    var ctx = canvasElement.getContext('2d');
    ctx.drawImage(imgElement, 0, 0);
    var imgData = ctx.getImageData(0, 0, imgElement.width, imgElement.height).data;
    // check imgData, alpha must be 255
    if (imgData[3] == 0) {
        return;
    }

    // convert to gray level with 140 threshold
    var grayImgData = [];
    for (var i = 0; i < 4 * height * width; i += 4) {
        var lum = 0.299 * imgData[i] + 0.587 * imgData[i + 1] + 0.114 * imgData[i + 2];
        grayImgData.push(lum > 140 ? 1 : 0);
    }

    // grayImg obj
    var grayImg = {
        width: width,
        height: height,
        grayImgData: grayImgData,
        at: function at(x, y) {
            return this.grayImgData[x + this.width * y];
        },
        set: function set(x, y, color) {
            this.grayImgData[x + this.width * y] = color;
        },
        compare: function compare(x1, y1, x2, y2, template) {
            var score = 0;
            var count = 0;
            for (var x = x1; x < x2; x += 3) {
                for (var y = y1; y < y2; y += 2) {
                    score += this.at(x, y) != template[count];
                    count++;
                }
            }
            return score;
        }

        // remove noise and identify
    };removeNoise();
    var result = identify(2);

    // set input element with the result
    document.getElementsByName('Agnomen')[0].value = result.toString();
};

// test existence first
var imgElement = document.querySelector('img[width="55"][height="20"]');
if (imgElement !== null) {
    // wait for captcha loaded
    aaoCaptcha(imgElement);
    imgElement.addEventListener("load", function () {
        aaoCaptcha(imgElement);
    });
}