爬虫案例-使用Session登录指定网站(JS逆向AES-CBC加密+MD5加密)

news2025/2/12 3:58:32

总体概览:使用Session登录该网站,其中包括对password参数进行js逆向破解

                (涉及加密:md5加密+AES-CBC加密)

难度:两颗星

目标网址:aHR0cHM6Ly93d3cuZnhiYW9nYW8uY29tLw==

下面文章将分为四个部分:

        1、定位主体加密函数,进行断点

        2、分析整体加密流程

        3、对JS代码进行扣取、补充、重写

        4、使用Session进行登录

运行效果展示:

JS逆向运行截图:

Session登陆成功截图:

正文开始: 

第一步、定位主体加密函数,进行断点

首先进入网站,点击登陆后进行抓包,很明显可以看出这里的密码(data参数)被进行了加密。

        由于data参数比较常见不太好搜索,因此我们对url的接口byPhoneNumber进行搜索

        搜索一共只有三个结果,比较少就都点进去看看,发现第一个很明显就是加密的主体函数并且 l 为加密的数据,直接对 l 参数进行断点后再次点击登陆,确定这个就是我们所需要的函数

第二步、分析整体加密流程

var o = e.password
, s = e.mobile
, a = A.dnGetter()
, l = D().ne("".concat(a).concat(o), _()("".concat(s.slice(3)).concat(a)));

直接看代码的话初步得出以下结论:

o为密码,s为账号,a疑似一个时间戳(这个后面再去验证),l 为加密后的一串数据

其中 l 为核心,下面对 l 进行分析:

1、其中可以看出括号内前半截是a与o的一个简单的拼接

2、后半截的话是先对密码部分截取第三位数之后的数据并与a进行拼接,并通过 _() 函数进行处理,发现 _() 是对拼接后的数据进行了md5的加密

3、在括号内的数据处理完成后调用D函数下的ne方法再进行一次处理

 

  得到这些信息后开始扣取JS代码并补充缺少的函数

第三步、对JS代码进行扣取、补充、重写

步骤1:对a参数进行补充

首先将主体的加密函数复制下来写到自己定义的一个方法里,文中可以看出需要传入e参数(账号密码信息),下面是主体函数的代码:

var get_password = function (e){
        var o = e.password
      , s = e.mobile
      , a = A.dnGetter()
      , l = D().ne("".concat(a).concat(o), _()("".concat(s.slice(3)).concat(a)));
        return l
}
var e = {
    "mobile": "17688888888",
    "password": "Wu123123123"
}
console.log(get_password(e))

很明显这里缺少了 A.dnGetter() 函数,找到这个函数点击进入发现它是一个名为 ot 的函数,写入JS代码中,并将原来的 A.dnGetter() 改写为 ot() 

 

 点击运行,发现缺少参数c,在此设置断点,运行了几次之后发现c为固定值false,因此我们直接令他为false,同时我们发现这句话还缺少了 window.D 参数 ,运行发现 这个也是固定值,补充完后运行一下结果没毛病。

 

 

window = global
window.D = 1
var ot = function() {
    return false || "number" !== typeof window.D ? +String(Date.now()).substr(0, 10) : +String(Date.now()).substr(0, 10) + window.D
}

 接下来就是我们的重头戏了!!

步骤2:对D.ne函数进行补充

首先是进入D函数下的ne方法,进入发现这里是一个很明显的AES-CBC加密,将D改为一个对象,将ne方法放入D中,并将原本的D().ne() 改写为 D.ne     (这里有两种写法,我个人更喜欢写成D.ne一点看着会简单一些,如果想要 D().ne()的写法的话也可以,都放在下面了)

 

 写法1:

 写法2:

 再次运行发现缺少了对象,由于这里的格式与AES加密一模一样,因此在这里我将o替换成了JavaScript中的 crypto-js 库,这是一个经常用于加解密的库,调用前需要安装 jsdom

安装及使用方法可以看我上一篇文章所讲的:AES加密和解密详解_浩·的博客-CSDN博客

let CryptoJS = require('crypto-js');		// 调用crypto-js 模块
let D = {
        ne: function(e, t) {
        return CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(e), CryptoJS.enc.Utf8.parse(t.substr(0, 32)), {
            iv: CryptoJS.enc.Utf8.parse(t.substr(-16)),
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }).ciphertext.toString().toUpperCase()
    }
}

 步骤3:对 _() 函数进行补充与改写

前面分析过了在这下面的部分其实是将_()后面的数据进行了md5加密,会改写JS代码的或者使用python替代的可以直接跳过这一步不看。下面这部分主要还是练习一下对JS的逆向能力。对md5加密函数进行还原操作。

这里有一个小坑,将鼠标移到 _() 上后发现调用的是a函数,需要将a先展开再进入a中。

可以看见这里传入了我们前面所讲的后半截数据,因此可以将原本的

_()(后半截数据)  改写为 _(后半截数据) 

同时为了美观,我们将 _  函数改名为exports,具体改写后的代码如下:

exports = function(e, n) {
    if (void 0 === e || null === e)
        throw new Error("Illegal argument " + e);
    var r = t.wordsToBytes(i(e, n));
    return n && n.asBytes ? r : n && n.asString ? a.bytesToString(r) : t.bytesToHex(r)
}
var get_password = function (e){
        var o = e.password
      , s = e.mobile
      , a = ot()
      , l = D.ne("".concat(a).concat(o), exports(("".concat(s.slice(3)).concat(a))));
        return l
}

再次运行,发现对象 t 及其附带的函数wordsToBytes、bytesToHex都未被定义,给t下断点,进入t中。刚好发现我们想要的两个函数都在里面,直接带走。新建一个对象t,并放入这两个函数。

 

let t = {
    wordsToBytes: function(e) {
        for (var t = [], n = 0; n < 32 * e.length; n += 8)
            t.push(e[n >>> 5] >>> 24 - n % 32 & 255);
        return t
    },
    bytesToHex: function(e) {
        for (var t = [], n = 0; n < e.length; n++)
            t.push((e[n] >>> 4).toString(16)),
            t.push((15 & e[n]).toString(16));
        return t.join("")
    }
}

 再次运行再 t 的旁边还缺少了个 i  

下面对 i 进行补充,进入 i 并打下断点,将i先全扣下来再运行

这里报错 r 未被定义,这个比较明显,因为r就在上面,可以看见 r 为一个对象,包含了两个方法

 

 

 

可以看见 r 调用的utf8就在这里,同时utf8的两个方法还用到了下面的bin,因此在这我们直接扣过去 并新建一个 r 对象保存。由于单个单词 t 容易造成重复,我们这里对 对象t改了一下名字,最后再 i 函数中调用

 

 再次运行,缺少了t.bytesToWords,回到刚刚的地方继续重复操作,定位过去发现这里是刚刚扣 t 对象的地方,我们只需要将新的给补充进去

 

 

 然后重复,运行、下断点、进入函数,发现v函数是再上面被定义的,

我们进入定义它的地方 i.ff 函数中,顺路吧剩下的四个一起扣下来

 

 继续重复刚刚的操作扣 t.endian([l, s, f, d]) ,发现这里还调用了上面两个函数,一起带走。

要注意一下这里名字变了,扣过去的时候要改回来,并且把下面的 n.rotl 也改成 t.rotl

 

 

 改完之后发现这里有个bug,如果要将n改为t的话这就与上面的for 循环中的t变量冲突了,因此我们将for循环的变量改为其他的。 于是这里改为图二。

 再次点击运行,发现已经大功告成啦!!!!!

 

到这里逆向部分就已经完成了,下面进行登录操作

第四步、使用Session进行登录

查看登录发送的包,发现这里有一个时间戳,根据逆向时候知道的这个时间戳需要用来加密,因此我们需要将这个时间戳与JS的时间戳保持一直。所以我们需要在python上生成时间戳,然后发送给JS,对此我们还要将JS的时间戳改为一个传入的参数,即传入a(时间戳参数)

// 主函数改写后:
var get_pas_word = function(e,a){
    var o = e.password
      , s = e.mobile
      // , a = ot()
    var l = D.ne("".concat(a).concat(o), aaa(("".concat(s.slice(3)).concat(a))));
    return l
}
var e_dic = {
    "mobile": "17836797789",
    "password": "123wu123123"
}
a = 1686207919
console.log(get_pas_word(e_dic,a))

全部代码:Session登录+JS逆向代码

JS加密代码:

window = global

var ot = function() {
    return false || "number" !== typeof window.D ? +String(Date.now()).substr(0, 10) : +String(Date.now()).substr(0, 10) + window.D
}

let CryptoJS = require('crypto-js');		// 调用crypto-js 模块
let D = {
        ne: function(e, t) {
        return CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(e), CryptoJS.enc.Utf8.parse(t.substr(0, 32)), {
            iv: CryptoJS.enc.Utf8.parse(t.substr(-16)),
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }).ciphertext.toString().toUpperCase()
    }
}

let r_obj = {
    utf8: {
        stringToBytes: function(e) {
            return r_obj.bin.stringToBytes(unescape(encodeURIComponent(e)))
        },
        bytesToString: function(e) {
            return decodeURIComponent(escape(r_obj.bin.bytesToString(e)))
        }
    },
    bin: {
        stringToBytes: function(e) {
            for (var t = [], n = 0; n < e.length; n++)
                t.push(255 & e.charCodeAt(n));
            return t
        },
        bytesToString: function(e) {
            for (var t = [], n = 0; n < e.length; n++)
                t.push(String.fromCharCode(e[n]));
            return t.join("")
        }
    }
}

i = function(e, n) {
    var r = r_obj.utf8
                e.constructor == String ? e = n && "binary" === n.encoding ? a.stringToBytes(e) : r.stringToBytes(e) : o(e) ? e = Array.prototype.slice.call(e, 0) : Array.isArray(e) || e.constructor === Uint8Array || (e = e.toString());
                for (var c = t.bytesToWords(e), u = 8 * e.length, l = 1732584193, s = -271733879, f = -1732584194, d = 271733878, p = 0; p < c.length; p++)
                    c[p] = 16711935 & (c[p] << 8 | c[p] >>> 24) | 4278255360 & (c[p] << 24 | c[p] >>> 8);
                c[u >>> 5] |= 128 << u % 32,
                c[14 + (u + 64 >>> 9 << 4)] = u;

                i._ff = function(e, t, n, r, o, a, i) {
                    var c = e + (t & n | ~t & r) + (o >>> 0) + i;
                    return (c << a | c >>> 32 - a) + t
                }
                ,
                i._gg = function(e, t, n, r, o, a, i) {
                    var c = e + (t & r | n & ~r) + (o >>> 0) + i;
                    return (c << a | c >>> 32 - a) + t
                }
                ,
                i._hh = function(e, t, n, r, o, a, i) {
                    var c = e + (t ^ n ^ r) + (o >>> 0) + i;
                    return (c << a | c >>> 32 - a) + t
                }
                ,
                i._ii = function(e, t, n, r, o, a, i) {
                    var c = e + (n ^ (t | ~r)) + (o >>> 0) + i;
                    return (c << a | c >>> 32 - a) + t
                }
                var v = i._ff
                  , m = i._gg
                  , h = i._hh
                  , y = i._ii;



                for (p = 0; p < c.length; p += 16) {
                    var g = l
                      , b = s
                      , x = f
                      , w = d;
                    l = v(l, s, f, d, c[p + 0], 7, -680876936),
                    d = v(d, l, s, f, c[p + 1], 12, -389564586),
                    f = v(f, d, l, s, c[p + 2], 17, 606105819),
                    s = v(s, f, d, l, c[p + 3], 22, -1044525330),
                    l = v(l, s, f, d, c[p + 4], 7, -176418897),
                    d = v(d, l, s, f, c[p + 5], 12, 1200080426),
                    f = v(f, d, l, s, c[p + 6], 17, -1473231341),
                    s = v(s, f, d, l, c[p + 7], 22, -45705983),
                    l = v(l, s, f, d, c[p + 8], 7, 1770035416),
                    d = v(d, l, s, f, c[p + 9], 12, -1958414417),
                    f = v(f, d, l, s, c[p + 10], 17, -42063),
                    s = v(s, f, d, l, c[p + 11], 22, -1990404162),
                    l = v(l, s, f, d, c[p + 12], 7, 1804603682),
                    d = v(d, l, s, f, c[p + 13], 12, -40341101),
                    f = v(f, d, l, s, c[p + 14], 17, -1502002290),
                    l = m(l, s = v(s, f, d, l, c[p + 15], 22, 1236535329), f, d, c[p + 1], 5, -165796510),
                    d = m(d, l, s, f, c[p + 6], 9, -1069501632),
                    f = m(f, d, l, s, c[p + 11], 14, 643717713),
                    s = m(s, f, d, l, c[p + 0], 20, -373897302),
                    l = m(l, s, f, d, c[p + 5], 5, -701558691),
                    d = m(d, l, s, f, c[p + 10], 9, 38016083),
                    f = m(f, d, l, s, c[p + 15], 14, -660478335),
                    s = m(s, f, d, l, c[p + 4], 20, -405537848),
                    l = m(l, s, f, d, c[p + 9], 5, 568446438),
                    d = m(d, l, s, f, c[p + 14], 9, -1019803690),
                    f = m(f, d, l, s, c[p + 3], 14, -187363961),
                    s = m(s, f, d, l, c[p + 8], 20, 1163531501),
                    l = m(l, s, f, d, c[p + 13], 5, -1444681467),
                    d = m(d, l, s, f, c[p + 2], 9, -51403784),
                    f = m(f, d, l, s, c[p + 7], 14, 1735328473),
                    l = h(l, s = m(s, f, d, l, c[p + 12], 20, -1926607734), f, d, c[p + 5], 4, -378558),
                    d = h(d, l, s, f, c[p + 8], 11, -2022574463),
                    f = h(f, d, l, s, c[p + 11], 16, 1839030562),
                    s = h(s, f, d, l, c[p + 14], 23, -35309556),
                    l = h(l, s, f, d, c[p + 1], 4, -1530992060),
                    d = h(d, l, s, f, c[p + 4], 11, 1272893353),
                    f = h(f, d, l, s, c[p + 7], 16, -155497632),
                    s = h(s, f, d, l, c[p + 10], 23, -1094730640),
                    l = h(l, s, f, d, c[p + 13], 4, 681279174),
                    d = h(d, l, s, f, c[p + 0], 11, -358537222),
                    f = h(f, d, l, s, c[p + 3], 16, -722521979),
                    s = h(s, f, d, l, c[p + 6], 23, 76029189),
                    l = h(l, s, f, d, c[p + 9], 4, -640364487),
                    d = h(d, l, s, f, c[p + 12], 11, -421815835),
                    f = h(f, d, l, s, c[p + 15], 16, 530742520),
                    l = y(l, s = h(s, f, d, l, c[p + 2], 23, -995338651), f, d, c[p + 0], 6, -198630844),
                    d = y(d, l, s, f, c[p + 7], 10, 1126891415),
                    f = y(f, d, l, s, c[p + 14], 15, -1416354905),
                    s = y(s, f, d, l, c[p + 5], 21, -57434055),
                    l = y(l, s, f, d, c[p + 12], 6, 1700485571),
                    d = y(d, l, s, f, c[p + 3], 10, -1894986606),
                    f = y(f, d, l, s, c[p + 10], 15, -1051523),
                    s = y(s, f, d, l, c[p + 1], 21, -2054922799),
                    l = y(l, s, f, d, c[p + 8], 6, 1873313359),
                    d = y(d, l, s, f, c[p + 15], 10, -30611744),
                    f = y(f, d, l, s, c[p + 6], 15, -1560198380),
                    s = y(s, f, d, l, c[p + 13], 21, 1309151649),
                    l = y(l, s, f, d, c[p + 4], 6, -145523070),
                    d = y(d, l, s, f, c[p + 11], 10, -1120210379),
                    f = y(f, d, l, s, c[p + 2], 15, 718787259),
                    s = y(s, f, d, l, c[p + 9], 21, -343485551),
                    l = l + g >>> 0,
                    s = s + b >>> 0,
                    f = f + x >>> 0,
                    d = d + w >>> 0
                }
                return t.endian([l, s, f, d])
            }

t = {
    wordsToBytes: function(e) {
        for (var t = [], n = 0; n < 32 * e.length; n += 8)
            t.push(e[n >>> 5] >>> 24 - n % 32 & 255);
        return t
    },
    bytesToWords: function(e) {
        for (var t = [], n = 0, r = 0; n < e.length; n++,
        r += 8)
            t[r >>> 5] |= e[n] << 24 - r % 32;
        return t
    },
    bytesToHex: function(e) {
        for (var t = [], n = 0; n < e.length; n++)
            t.push((e[n] >>> 4).toString(16)),
            t.push((15 & e[n]).toString(16));
        return t.join("")
    },
    rotl: function(e, t) {
        return e << t | e >>> 32 - t
    },
    rotr: function(e, t) {
        return e << 32 - t | e >>> t
    },

    endian: function(e) {
        if (e.constructor == Number)
            return 16711935 & t.rotl(e, 8) | 4278255360 & t.rotl(e, 24);
        for (var x = 0; x < e.length; x++)
            e[x] = t.endian(e[x]);
        return e
    }
}

aaa = function (e,n){
    // if (void 0 === e || null === e)
    //     throw new Error("Illegal argument " + e);
    var r = t.wordsToBytes(i(e, n));
    return n && n.asBytes ? r : n && n.asString ? a.bytesToString(r) : t.bytesToHex(r)
}

var get_pas_word = function(e,a){
    var o = e.password
      , s = e.mobile
      // , a = ot()
    var l = D.ne("".concat(a).concat(o), aaa(("".concat(s.slice(3)).concat(a))));
    return l
}
var e_dic = {
    "mobile": "17836797789",
    "password": "123wu123123"
}
a = 1686207919
console.log(get_pas_word(e_dic,a))

最终python登录代码:

# -*- coding: UTF-8 -*-
'''
@Project :wbh_pj 
@File :111.py
@Author :hao
@Date :2023/6/8 15:11 
'''
import time
import execjs
import requests

headers = {
    'authority': 'api.fxbaogao.com',
    'accept': '*/*',
    'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7',
    'content-type': 'application/json; charset=UTF-8',
    'origin': 'https://www.fxbaogao.com',
    'referer': 'https://www.fxbaogao.com/',
    'sec-ch-ua': '"Google Chrome";v="113", "Chromium";v="113", "Not-A.Brand";v="24"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'same-site',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
    'user-id': '0',
    'user-token': 'QQ',
}

def get_pas_word(e_dic,now_time):
    filename_js = '123.js'
    with open(filename_js, encoding='utf-8', mode='r') as f:
        pw_js = f.read()
        f.close()
    js1 = execjs.compile(pw_js)
    print('********* 正在生成 -- pas_word *********')
    pas_word = js1.call('get_pas_word', e_dic,now_time)         # 获取token
    print(pas_word)
    return pas_word

def login():
    now_time = int(time.time())      # 获取时间戳
    e_dic = {
        "mobile": "17688888888",
        "password": "123wu123123"
    }
    pas_word = get_pas_word(e_dic,now_time)

    json_data = {
        'mobile': '17688688515',
        'data': pas_word,
        'time': now_time,
    }
    session = requests.session()
    # response = requests.post('https://api.fxbaogao.com/mofoun/user/login/byPhoneNumber', headers=headers,
    #                          json=json_data)
    response1 = session.post('https://api.fxbaogao.com/mofoun/user/login/byPhoneNumber', headers=headers,json=json_data)
    print(response1.text)

if __name__ == '__main__':
    login()

JS逆向部分总结:

        1、在登录的时候对password参数与时间戳拼接;

        2、对账号参数切及时间戳的拼接;

        3、将部分关键数据转数组后先进行MD5加密处理;

        4、最终将前面数据全部拼接对数据使用AES下的CBC加密

        5、得到password的参数之后使用request模块的Session进行登录操作

AES加密解密:AES加密和解密详解_aesdecrypt_浩·的博客-CSDN博客

知名外卖平台项目:JS逆向---获取某知名外卖平台数据(_token)_浩·的博客-CSDN博客

更多爬虫项目请看:浩 的个人爬虫项目

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/640006.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在后大流行时代利用Airbnb实现逆周期增长

回望近十年共享经济的发展历程&#xff0c;谁也不曾想到&#xff0c;最被看好的共享经济代表Uber竟在连年亏损后忍痛IPO&#xff0c;上市首日即破发&#xff0c;而主打「互联网房地产」模式的独角兽WeWork则上市失败&#xff0c;迅速失血&#xff0c;一度走到破产边缘。作为“共…

模型剪枝:Network Slimming剪枝实战

本文来自公众号“AI大道理” ​ Network Slimming剪枝是比较广泛的一种模型剪枝方法&#xff0c;作者来自清华大学、英特尔中国实验室、复旦大学和科内尔大学。 1、Network Slimming剪枝理论 Network Slimming剪枝是结构性剪枝&#xff0c;是通道剪枝&#xff0c;是静态剪枝…

mac安装hive_20230609

竟然是今年第一篇 hhhh 过两天把上半年的东西梳理好的话 陆续放上来吧&#xff5e; 公司本地测试环境的hive版本不支持不等式关联操作&#xff0c;而现在用hive也比较多&#xff0c;所以在本地装了一个hive&#xff0c;主要写一下大致步骤和过程中遇到的问题&#xff5e;&#…

win10任务栏卡死解决

现象&#xff1a; win10 更新后&#xff0c;开机任务栏卡死&#xff0c;点开始反应&#xff0c;设置页面无法打开。 原因&#xff1a; 原因是Win10更新的任务栏资讯和兴趣&#xff0c;而资讯和兴趣是Edge浏览器的&#xff0c;该服务器是在国外&#xff0c;国内的网络加载不出来…

【lvs集群】HAProxy搭建Web集群

HAProxy搭建Web集群 一、 HAProxy简介1.1HAProxy主要特性1.2HAProxy负载均衡策略非常多&#xff0c;常见的有如下8种1.3LVS、Nginx、HAproxy的区别1.4常见的Web集群调度器 二、Haproxy搭建 Web 群集haproxy服务器部署节点服务器部署 三、定义监控页面与定义日志3.1定义监控页面…

stm32f103最小系统板详细介绍

一.什么是单片机最小系统 常见的单片机最小系统为单片机能独立运行程序及控制外围电路的最简单电路&#xff0c;主要由单片机、晶振电路、复位电路三部分构成。Stm32f103c8t6也不例外&#xff0c;构成最小的运行电路也需要以上三部分。 Stm32f103最小系统板原理图如下&#xf…

初始Sentinel(Sentinel的简单介绍及项目整合)

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;在一家满意的公司实习。本篇文章将详细介绍Sentinel的概念&#xff0c;优点&#xff0c;与Hystrix的对比以及微服务中整合Sentinel&#xff0c;后续文章将详细介绍Sentinel的细节部分。 如果文章…

分享几个关于AI的网站

分享几个关于AI的网站 AI文本 ChatGPT&#xff1a;https://chat.openai.com/ NotionAI&#xff1a;https://www.notion.so/product/ai A.I. Data Sidekick&#xff1a;AI工具编写 SQL、文档等的速度提高10倍https://www.airops.com/ Writesonic&#xff1a;人工智能写作辅助工…

CSS基础学习--7 fonts字体

一、CSS 字体 CSS字体属性定义字体系列&#xff0c;加粗&#xff0c;大小&#xff0c;文字样式。 二、字体系列 font-family 属性设置文本的字体系列 font-family 属性应该设置几个字体名称作为一种"后备"机制&#xff0c;如果浏览器不支持第一种字体&#xff0c;…

Haproxy的应用

Taproxy 一、Haproxy的原理Haproxy的主要特性Haproxy八种负载均衡策略LVS、Nginx、Haproxy的区别 二、搭建web群集 一、Haproxy的原理 Haproxy是可提供高可用性&#xff0c;负载均衡以及基于TCP和HTTP应用的代理&#xff0c;是免费、快速并且可靠的一种解决方案。Haproxy非常适…

电脑提示vcruntime140_1.dll丢失怎么修复?

本修复教程操作系统&#xff1a;Windows系统 vcruntime140_1.dll是电脑文件中的dll文件&#xff08;动态链接库文件&#xff09;。如果计算机中丢失了某个dll文件&#xff0c;可能会导致某些软件和游戏等程序无法正常启动运行&#xff0c;并且导致电脑系统弹窗报错。 在我们打…

FPGA基础知识-模块和端口

目录 学习目标 学习内容 端口 端口列表 端口声明 端口链接规则 学习时间 总结 学习目标&#xff1a; 1.说明Verilog 模块定义中的各个组成部分&#xff0c;例如模块名、端口列表、参数、变址声明、数据流描述语句、行为语句、调用&#xff08;实例引用》其他模块以及任务…

Java网络开发(Filter过滤器)—— tomcat的过滤器 编码控制 + 网页权限控制

目录 引出1.过滤器简介2.用过滤器实现全局编码控制&#xff08;1&#xff09;导包import javax.servlet.*;&#xff08;2&#xff09;如果是tomcat8.5&#xff0c;要把3个方法都实现&#xff08;3&#xff09;代码如下&#xff0c;要点&#xff1a;放行&#xff0c;chain.doFil…

Bug小能手系列(python)_7: BertTokenizer报错 Connection reset by peer

ConnectionResetError: [Errno 104] Connection reset by peer 0. 错误介绍1. 解决思路1.1 添加代码 force_downloadTrue1.2 删除缓存1.3 科学上网1.4 线下下载 2. 解决方法2.1 清除缓存2.2 线下下载模型&#xff08;强烈建议&#xff09; 3. 总结 0. 错误介绍 当使用transfor…

4.将图神经网络应用于大规模图数据(Cluster-GCN)

到目前为止&#xff0c;我们已经为节点分类任务单独以全批方式训练了图神经网络。特别是&#xff0c;这意味着每个节点的隐藏表示都是并行计算的&#xff0c;并且可以在下一层中重复使用。 然而&#xff0c;一旦我们想在更大的图上操作&#xff0c;由于内存消耗爆炸&#xff0c…

【Python 生成器与迭代器】零基础也能轻松掌握的学习路线与参考资料

一、Python生成器与迭代器概述 Python是一种高级编程语言&#xff0c;其中非常重要的概念就是生成器和迭代器。Python生成器和迭代器联合使用&#xff0c;能够实现高效的迭代操作&#xff0c;避免增加额外的内存消耗&#xff0c;同时提高代码的可读性。Python中常见的生成器和…

单机多节点 elasticsearch 集群安全认证

es 版本&#xff1a;7.6.2 部署环境&#xff1a;CentOS Linux release 7.6.1810 (Core) 一&#xff1a;生成 ca 证书 cd 到 es 的安装目录&#xff0c;并执行下面的命令来生成 ca 证书&#xff1a; ./bin/elasticsearch-certutil ca Elasticsearch碰到第一个直接回车&#xf…

面试专题:Mysql

1.说说自己对于 MySQL 常见的两种存储引擎&#xff1a;MyISAM与InnoDB的理解 关于二者的对比与总结: 1.count运算上的区别&#xff1a;因为MyISAM缓存有表meta-data&#xff08;行数等&#xff09;&#xff0c;因此在做COUNT(*)时对于一个结构很好的查询是不需要消耗多少资源的…

[CKA]考试之K8s 版本升级

由于最新的CKA考试改版&#xff0c;不允许存储书签&#xff0c;本博客致力怎么一步步从官网把答案找到&#xff0c;如何修改把题做对&#xff0c;下面开始我们的 CKA之旅 题目为&#xff1a; Task 现有的Kubernetes 集群正在运行版本1.22.0。仅将master节点上的所有 Kuberne…

【Python】集合 set ② ( 集合常用操作 | 集合中添加元素 | 集合中移除元素 | 集合中随机取出元素 )

文章目录 一、集合中添加元素二、集合中移除元素三、集合中随机取出元素 在 Python 中 , 集合 set 是无序的 , 因此 集合 数据容器 不支持 使用 下标索引 访问 集合元素 ; 一、集合中添加元素 调用 集合#add(新元素) 函数 , 可以将新元素添加到 集合 数据容器中 ; 集合添加元素…