猿人学2023第一题:利用协议获取全部5页全部数字之和

题目地址:aHR0cHM6Ly9tYXRjaDIwMjMueXVhbnJlbnh1ZS5jbi90b3BpYy8x

一、页面调试

        1)在控制台搜索接口名称可以很容易定位到发送请求的地方,代码可读性比较好,可以直接在相关函数内打上断点;

        2)点击页码触发请求逻辑,在右侧面板可以看到相关的变量。

        请求总共需要传3个参数“now、page、token”,其中,now(当前时间戳)和page(当前页码)比较简单,主要是提取token的生成方法;

        从代码中可以知道 token 的计算公式为:MD5(AES(now + page)),意即:将时间戳和页码的字符串进行拼接,再对拼接后的字符串进行AES加密,接着对AES加密后的字符串内容进行MD5计算。

        起初,我直接使用网上公共的AES加密方法来实现代码,但发现请求会报错“token无效”,这时才恍然网站的AES加密是不同的。

二、代码实现

        代码的关键点主要是提取AES加密方法,这里有两个方案:

        方案一

        在正式发送请求之前,可以在断点调试过程中,将AES加密的方法右键存为全局变量,以便在后续的函数中使用。这种方式有点讨巧,不用去花太多时间在去提取代码。

// 变量声明:请求成功的次数
let count = 0;
// 变量声明:所有请求到的数据
let dataList = [];
// 函数声明:发送请求获取页面数据
let getPageData = function (pageNum) {
    let timestamp = Date['now']()
        , iv = '666yuanrenxue66'
        , h = temp1['AES']['encrypt'](timestamp + String(pageNum), iv, {
        'mode': temp1['mode']['ECB'],
        'padding': temp1['pad']['Pkcs7']
    })
        , i = '/api/match2023/1'
        , j = {
        'page': String(pageNum),
        'token': temp1['MD5'](h['toString']())['toString'](),
        'now': timestamp
    };
    $['ajax']({
        'url': i,
        'dataType': 'json',
        'async': !![],
        'data': j,
        'type': 'POST',
        'beforeSend': function(k) {},
        'success': function(k) {
            k = (k['data'] || []).map(v => v.value);
            dataList = [...dataList, ...k];
            count++;
            if (count >= 5) {
                let sum = dataList.reduce((a, b) => (a + b), 0);
                console.log('sum:', sum)
            }
        },
        'complete': function() {},
        'error': function() {
        }
    });
}
// 开始运行:循环依次发送各个页面的数据请求
for (let i = 1; i <= 5; i++) {
    setTimeout(() => {
        getPageData(i)
    }, i * 200)
}

         方案二

        提取加密相关代码。好在代码都集中在 /corejs/match1.js 文件中。经过分析,其实修改的内容并不多,只需将第34~75行之间的Ajax请求做些许调整。

        1)去除了初始化时对call函数的调用;

        2)修改Ajax请求成功后的回调函数。

        修改后的代码执行完成后,会在全局生成一个名为call的函数,这个函数就是用来请求页面数据的。

// 微调 corejs/match1.js 内容:重新定义全局call方法
// ...前方省略
0x2: [function(a, b, c) {
    call = function(d, cb) {
        // ...略
        $['ajax']({
            'url': i,
            'dataType': 'json',
            'async': !![],
            'data': j,
            'type': 'POST',
            'beforeSend': function(k) {},
            'success': function(k) {
                k = k['data'];
                cb && cb(k);
            },
            'complete': function() {},
            'error': function() {
            }
        });
    }
}
// ...后方省略

// 变量声明:请求成功的次数
let count = 0;
// 变量声明:所有请求到的数据
let dataList = [];
// 函数声明:请求成功后的回调函数
let callback = function (data) {
    data = (data || []).map(v => v.value);
    dataList = [...dataList, ...data];
    count++;
    if (count >= 5) {
        let sum = dataList.reduce((a, b) => (a + b), 0);
        console.log('sum:', sum)
    }
}
// 开始运行:循环依次发送各个页面的数据请求
for (let i = 1; i <= 5; i++) {
    setTimeout(() => {
        call(i, callback)
    }, i * 200)
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半吊子伯爵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值