【python3】简易双因子Radius认证服务器,带UI界面

2023-05-16


需要将dictionary.rfc2865放在运行的同级目录下

#_*_coding:utf-8_*_
from tkinter import *
from tkinter.ttk import *
from tkinter import scrolledtext
from tkinter import messagebox
import time
import os
import re
import socket
import threading
from os import environ
from os.path import join, exists
#from ico import img
#import base64
from pyrad import packet
import pyrad.dictionary
import pyrad.host
import random
import string

CHALLENGE_LEN = 6
CHALLENGE_TYPE = 6
CHALLENGE = "BAdPassw0d"
FilterId = ""

class RadiusServer(pyrad.host.Host):
    def __init__(self):
        dict = pyrad.dictionary.Dictionary("dictionary.rfc2865") #从freeradius中搞一个通用的字典使用
        pyrad.host.Host.__init__(self, dict=dict)

    def get_challenge(self):
        if CHALLENGE_TYPE == 1:
            return (''.join(random.choice(string.ascii_letters) for _ in range(CHALLENGE_LEN))).upper()
        if CHALLENGE_TYPE == 2:
            return (''.join(random.choice(string.ascii_letters) for _ in range(CHALLENGE_LEN))).lower()
        if CHALLENGE_TYPE == 4:
            return ''.join(random.choice(string.ascii_letters) for _ in range(CHALLENGE_LEN))
        if CHALLENGE_TYPE == 6:
            return ''.join(random.choice(string.digits) for _ in range(CHALLENGE_LEN))
        if CHALLENGE_TYPE == 8:
            return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(CHALLENGE_LEN))

    def check_pap_pass(self, radpkt):
        global CHALLENGE
        if radpkt.PwCrypt(CHALLENGE) == radpkt["User-Password"][0]:
            radpkt.code = packet.AccessAccept
            if(len(FilterId)>0):
                radpkt['Filter-Id'] = FilterId
                radpkt['Class'] = FilterId  #安盟使用的安全组信息
            return("用户名:%-16s 状态:挑战码认证通过" % radpkt["User-Name"][0])
        elif radpkt.PwCrypt("Authpasswd") == radpkt["User-Password"][0]:
            radpkt.code = packet.AccessChallenge
            CHALLENGE = self.get_challenge()
            radpkt['Reply-Message'] = "Enter Token Code"
            radpkt['State'] = ("CHALLENGE=%s" % CHALLENGE).encode()
            return("用户名:%-16s 状态:待挑战认证 挑战码:%s" % (radpkt["User-Name"][0],CHALLENGE))
        elif radpkt.PwCrypt("password") == radpkt["User-Password"][0]:
            radpkt.code = packet.AccessAccept
            if(len(FilterId)>0):
                radpkt['Filter-Id'] = FilterId
            return("用户名:%-16s 状态:认证通过" % radpkt["User-Name"][0])
        # elif radpkt.PwCrypt(PIN+"password") == radpkt["User-Password"][0]:
        #     radpkt.code = packet.AccessAccept
        #     return("用户名:%-16s 状态:PIN认证通过" % radpkt["User-Name"][0])
        else:
            radpkt.code = packet.AccessReject
            return("用户名:%-16s 状态:认证失败" % radpkt["User-Name"][0])

    def get_pkt(self, pkt):
        get_pw = None
        get_name = None
        radpkt = self.CreateAuthPacket(packet=pkt) #解析请求报文
        radpkt.secret = b"sharepasswd"
        #radpkt.secret = bytes(secret, encoding = "utf8")

        for key in radpkt.keys():
            print(key, radpkt[key])
        print("="*60)
        info = ""
        radpkt.code = packet.AccessAccept
        if "User-Password" in radpkt.keys():
            info = self.check_pap_pass(radpkt)
        else:
            info = "用户名:%-16s 状态:CHAP通过   IP:%s" % (radpkt['User-Name'][0],radpkt['NAS-IP-Address'][0])

        for key in radpkt.keys():
            print(key, radpkt[key])
        print("="*60)
        return radpkt.ReplyPacket(),info


class app_GUI():
    def __init__(self,init_window_name):
        self.init_window_name = init_window_name
        self.service = False  #开启service 监听

    #设置窗口
    def set_init_window(self):
        self.set_frame()
        self.load_config()

################################界面相关###################################
    def set_frame(self):
        frmLT = Frame(width=580,height=800)
        frmLT.grid(row=0, column=0, padx=18)
        row = 1

        self.IPlabel = Label(frmLT, text="服务IP:")
        self.IPlabel.grid(row=row, column=2,sticky=E, pady=(12,0))
        self.IPvar = StringVar()
        self.IPEntry= Entry(frmLT,textvariable=self.IPvar)
        self.IPvar.set("0.0.0.0")
        self.IPEntry.grid(row=row, column=3, pady=(12,0))
        row +=1
        self.portlabel = Label(frmLT, text="服务端口:")
        self.portlabel.grid(row=row, column=2,sticky=E, pady=(6,6))
        self.portvar = StringVar()
        self.portEntry= Entry(frmLT,textvariable=self.portvar)
        self.portvar.set(1812)
        self.portEntry.grid(row=row, column=3)
        row +=1
        self.filteridlabel = Label(frmLT, text="安全组:")
        self.filteridlabel.grid(row=row, column=2,sticky=E)
        self.filteridvar = StringVar()
        self.filteridEntry= Entry(frmLT,textvariable=self.filteridvar)
        self.filteridvar.set("")
        self.filteridEntry.grid(row=row, column=3)
        self.filteridEntry.bind('<Return>', self.change_filter_id)
        row +=1
        self.radioVar = IntVar()
        self.chaLenLabel = Label(frmLT, text="挑战码长度")
        self.chaLenLabel.grid(row=row, column=2,sticky=E, pady=(6,6))
        self.chaLenVar = StringVar()
        self.chaLenEntry= Entry(frmLT,textvariable=self.chaLenVar)
        self.chaLenVar.set(6)
        self.chaLenEntry.grid(row=row, column=3)
        self.chaLenEntry.bind('<Return>', self.change_challenge_len)
        row +=1
        self.cha = Label(frmLT, text="挑战码类型")
        self.cha.grid(row=row, column=4,sticky=E)
        row +=1
        self.R1 = Radiobutton(frmLT, text="大写字母", variable=self.radioVar, value=1, command=self.change_challenge_type)
        self.R1.grid(row=row, column=2)
        self.R2 = Radiobutton(frmLT, text="小写字母", variable=self.radioVar, value=2, command=self.change_challenge_type)
        self.R2.grid(row=row, column=3)
        self.R3 = Radiobutton(frmLT, text="纯字母", variable=self.radioVar, value=4, command=self.change_challenge_type)
        self.R3.grid(row=row, column=4)
        self.R4 = Radiobutton(frmLT, text="纯数字", variable=self.radioVar, value=6, command=self.change_challenge_type)
        self.R4.grid(row=row, column=7)
        self.R5 = Radiobutton(frmLT, text="全组合", variable=self.radioVar, value=8, command=self.change_challenge_type)
        self.R5.grid(row=row, column=9)
        self.radioVar.set(6)
        row +=1
        self.logTextLabel = Label(frmLT, text="运行日志")
        self.logTextLabel.grid(row=row, column=0, columnspan=15, pady=(12,4))
        row +=1
        self.logText = scrolledtext.ScrolledText(frmLT,width=80, height=15,borderwidth=0.1)
        self.logText.grid(row=row, column=0, columnspan=15,sticky=NW)


        self.strStartButton = StringVar()
        self.strStartButton.set("开启服务")
        self.startButton = Button(frmLT, textvariable=self.strStartButton,command=self.start_service)
        self.startButton.grid(row=2, column=7,)
        self.strHelpButton = Button(frmLT, text="使用说明",command=self.show_help_info)
        self.strHelpButton.grid(row=3, column=7)
        frmLT.grid_propagate(0)

################################保存配置相关###################################
    def config_filename(self):
        return join(environ["appdata"], 'radius_server.config')

    def load_config(self):
        if not exists(self.config_filename()):
            return
        try:
            with open(self.config_filename()) as fd:
                config = eval(fd.read())
                self.IPvar.set(config["ip"])
                self.portvar.set(config["port"])
                global CHALLENGE_LEN,CHALLENGE_TYPE,FilterId
                self.chaLenVar.set(config['challengeLen'])
                CHALLENGE_LEN = int(config['challengeLen'])
                self.radioVar.set(config['challengeType'])
                CHALLENGE_TYPE = int(config['challengeType'])
                if "filterId" in config:
                    self.filteridvar.set(config['filterId'])
                    FilterId = config['filterId']
        except Exception as e:
            self.write_log_to_Text("[ERROR]  %s" % e)

    def save_config(self):
        ip = self.IPvar.get()
        port=self.portvar.get()
        challengelen = self.chaLenEntry.get()
        challengetype= self.radioVar.get()
        filterId = FilterId
        dev = {"ip":ip, "port":int(port), "challengeLen":challengelen, "challengeType":challengetype, "filterId":filterId}
        with open(self.config_filename(), 'w') as fd:
            fd.write(str(dev))

################################内部调用###################################
    def api_para_check_failed(self):
        ip = self.IPvar.get()
        port=int(self.portvar.get())
        if not re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}",ip.strip()) and "::" not in ip:
            self.write_log_to_Text("[ERROR] 请输入合法IP!")
            return True
        if port<1 or port>65535:
            self.write_log_to_Text("[ERROR] 服务端口非法!")
            return True
        self.IPvar.set(ip.strip())
        return False


    #日志动态打印
    def write_log_to_Text(self,logmsg):
        self.logText.see(END)
        current_time = self.get_current_time()
        logmsg_in = current_time +" " + str(logmsg) + "\n"
        self.logText.insert(END, logmsg_in)
        self.logText.see(END)
        self.logText.update()

    #获取当前时间
    def get_current_time(self):
        current_time = time.strftime('%m-%d %H:%M:%S',time.localtime(time.time()))
        return str(current_time)
################################对外接口调用###################################
    def start_service(self):
        if self.api_para_check_failed():  #参数校验不通过
            return
        self.change_challenge_type()
        self.change_filter_id("start")
        self.save_config()
        if self.service == False:
            self.service_t=threading.Thread(target=self.startup_radius_sevice, args=())
            self.service_t.setDaemon(True)
            self.service_t.start()
        else:
            self.service = False
            self.write_log_to_Text("[INFO] %s:%d停止服务" % (self.ip_port[0],self.ip_port[1]))
            self.strStartButton.set("开启服务")

    def startup_radius_sevice(self):
        try:
            self.ip_port = (self.IPEntry.get(), int(self.portEntry.get()))
            if "::" in self.IPEntry.get():
                self.server = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)  # ipv6 udp协议
            else:
                self.server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # ipv4 udp协议
            self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.server.bind(self.ip_port)
        except Exception as e:
            self.write_log_to_Text("[Error]:%s" % e)
            return
        self.service = True
        self.write_log_to_Text("[INFO] %s:%d开启服务" % (self.ip_port[0],self.ip_port[1]))
        self.strStartButton.set("关闭服务")
        while True:
            if not self.service:
                self.server.close()
                break
            data,client_addr = self.server.recvfrom(1024)
            srv = RadiusServer()
            reply,info = srv.get_pkt(data)
            self.server.sendto(reply, client_addr)
            self.write_log_to_Text("[INFO] %s" % info)
            time.sleep(0.1)

    def change_challenge_len(self,type):
        global CHALLENGE_LEN
        if len(self.chaLenVar.get().strip())==0:
            return
        try:
            a = int(self.chaLenVar.get())
            if a < 1 or a > 64:
                self.write_log_to_Text("[Error] 挑战码长度为1~64")
                return
            if a != CHALLENGE_LEN:
                self.write_log_to_Text("[INFO] 挑战码长度修改为%d" % a)
            CHALLENGE_LEN = a
            self.save_config()
        except:
            self.write_log_to_Text("[Error] 挑战码长度值非法")

    def change_filter_id(self,type):
        global FilterId
        lastv = FilterId
        if lastv == self.filteridvar.get():
            return
        FilterId = self.filteridvar.get()
        if(len(FilterId)==0):
            self.write_log_to_Text("[INFO] 认证回应报文不携带Filter-Id字段")
        else:
            self.write_log_to_Text("[INFO] 安全组名称修改为%s" % FilterId)
        self.save_config()

    def change_challenge_type(self):
        global CHALLENGE_TYPE
        CHALLENGE_TYPE = self.radioVar.get()
        self.save_config()

    def show_help_info(self):
        info="""
服务IP是0.0.0.0  本机所有ipv4地址
服务IP是::           本机所有ipv6地址

共享秘钥为sharepasswd
认证方式PAP
用户名随意
密码是password         认证成功
密码是Authpasswd        需要挑战认证,会随机生成挑战码
密码是其他值                   认证失败

认证方式CHAP
用户名随意
密码随意                           认证成功

ps:开启服务后,修改挑战码长度或安全组名称时,需要按回车键才会生效
        """
        messagebox.showinfo("说明",info)

def app_gui_start(title):
    init_window = Tk()
    init_window.resizable(0,0)
    sw = init_window.winfo_screenwidth()
    sh = init_window.winfo_screenheight()
    ww = 614
    wh = 420
    x = (sw-ww) / 2
    y = (sh-wh) / 2
    init_window.title(title)
    init_window.geometry("%dx%d+%d+%d" %(ww,wh,x,y))
    #tmp = open("tmp.ico","wb+")  
    #tmp.write(base64.b64decode(img))
    #tmp.close()
    #init_window.iconbitmap("tmp.ico")
    #os.remove("tmp.ico") 
    app_PORTAL = app_GUI(init_window)
    app_PORTAL.set_init_window()
    init_window.mainloop()

app_gui_start("Simple Radius Server v22.02.19")

附dictionary.rfc2865字典内容,直接拷贝内容存为文件即可

# -*- text -*-
#
#	Attributes and values defined in RFC 2865.
#	http://www.ietf.org/rfc/rfc2865.txt
#
#	$Id: dictionary.rfc2865,v 1.3.2.1 2005/11/30 22:17:29 aland Exp $
#
ATTRIBUTE	User-Name				1	string
ATTRIBUTE	User-Password				2	string encrypt=1
ATTRIBUTE	CHAP-Password				3	octets
ATTRIBUTE	NAS-IP-Address				4	ipaddr
ATTRIBUTE	NAS-Port				5	integer
ATTRIBUTE	Service-Type				6	integer
ATTRIBUTE	Framed-Protocol				7	integer
ATTRIBUTE	Framed-IP-Address			8	ipaddr
ATTRIBUTE	Framed-IP-Netmask			9	ipaddr
ATTRIBUTE	Framed-Routing				10	integer
ATTRIBUTE	Filter-Id				11	string
ATTRIBUTE	Framed-MTU				12	integer
ATTRIBUTE	Framed-Compression			13	integer
ATTRIBUTE	Login-IP-Host				14	ipaddr
ATTRIBUTE	Login-Service				15	integer
ATTRIBUTE	Login-TCP-Port				16	integer
# Attribute 17 is undefined
ATTRIBUTE	Reply-Message				18	string
ATTRIBUTE	Callback-Number				19	string
ATTRIBUTE	Callback-Id				20	string
# Attribute 21 is undefined
ATTRIBUTE	Framed-Route				22	string
ATTRIBUTE	Framed-IPX-Network			23	ipaddr
ATTRIBUTE	State					24	octets
ATTRIBUTE	Class					25	octets
ATTRIBUTE	Vendor-Specific				26	octets
ATTRIBUTE	Session-Timeout				27	integer
ATTRIBUTE	Idle-Timeout				28	integer
ATTRIBUTE	Termination-Action			29	integer
ATTRIBUTE	Called-Station-Id			30	string
ATTRIBUTE	Calling-Station-Id			31	string
ATTRIBUTE	NAS-Identifier				32	string
ATTRIBUTE	Proxy-State				33	octets
ATTRIBUTE	Login-LAT-Service			34	string
ATTRIBUTE	Login-LAT-Node				35	string
ATTRIBUTE	Login-LAT-Group				36	octets
ATTRIBUTE	Framed-AppleTalk-Link			37	integer
ATTRIBUTE	Framed-AppleTalk-Network		38	integer
ATTRIBUTE	Framed-AppleTalk-Zone			39	string

ATTRIBUTE	CHAP-Challenge				60	octets
ATTRIBUTE	NAS-Port-Type				61	integer
ATTRIBUTE	Port-Limit				62	integer
ATTRIBUTE	Login-LAT-Port				63	integer

#
#	Integer Translations
#

#	Service types

VALUE	Service-Type			Login-User		1
VALUE	Service-Type			Framed-User		2
VALUE	Service-Type			Callback-Login-User	3
VALUE	Service-Type			Callback-Framed-User	4
VALUE	Service-Type			Outbound-User		5
VALUE	Service-Type			Administrative-User	6
VALUE	Service-Type			NAS-Prompt-User		7
VALUE	Service-Type			Authenticate-Only	8
VALUE	Service-Type			Callback-NAS-Prompt	9
VALUE	Service-Type			Call-Check		10
VALUE	Service-Type			Callback-Administrative	11

#	Framed Protocols

VALUE	Framed-Protocol			PPP			1
VALUE	Framed-Protocol			SLIP			2
VALUE	Framed-Protocol			ARAP			3
VALUE	Framed-Protocol			Gandalf-SLML		4
VALUE	Framed-Protocol			Xylogics-IPX-SLIP	5
VALUE	Framed-Protocol			X.75-Synchronous	6

#	Framed Routing Values

VALUE	Framed-Routing			None			0
VALUE	Framed-Routing			Broadcast		1
VALUE	Framed-Routing			Listen			2
VALUE	Framed-Routing			Broadcast-Listen	3

#	Framed Compression Types

VALUE	Framed-Compression		None			0
VALUE	Framed-Compression		Van-Jacobson-TCP-IP	1
VALUE	Framed-Compression		IPX-Header-Compression	2
VALUE	Framed-Compression		Stac-LZS		3

#	Login Services

VALUE	Login-Service			Telnet			0
VALUE	Login-Service			Rlogin			1
VALUE	Login-Service			TCP-Clear		2
VALUE	Login-Service			PortMaster		3
VALUE	Login-Service			LAT			4
VALUE	Login-Service			X25-PAD			5
VALUE	Login-Service			X25-T3POS		6
VALUE	Login-Service			TCP-Clear-Quiet		8

#	Login-TCP-Port		(see /etc/services for more examples)

VALUE	Login-TCP-Port			Telnet			23
VALUE	Login-TCP-Port			Rlogin			513
VALUE	Login-TCP-Port			Rsh			514

#	Termination Options

VALUE	Termination-Action		Default			0
VALUE	Termination-Action		RADIUS-Request		1

#	NAS Port Types

VALUE	NAS-Port-Type			Async			0
VALUE	NAS-Port-Type			Sync			1
VALUE	NAS-Port-Type			ISDN			2
VALUE	NAS-Port-Type			ISDN-V120		3
VALUE	NAS-Port-Type			ISDN-V110		4
VALUE	NAS-Port-Type			Virtual			5
VALUE	NAS-Port-Type			PIAFS			6
VALUE	NAS-Port-Type			HDLC-Clear-Channel	7
VALUE	NAS-Port-Type			X.25			8
VALUE	NAS-Port-Type			X.75			9
VALUE	NAS-Port-Type			G.3-Fax			10
VALUE	NAS-Port-Type			SDSL			11
VALUE	NAS-Port-Type			ADSL-CAP		12
VALUE	NAS-Port-Type			ADSL-DMT		13
VALUE	NAS-Port-Type			IDSL			14
VALUE	NAS-Port-Type			Ethernet		15
VALUE	NAS-Port-Type			xDSL			16
VALUE	NAS-Port-Type			Cable			17
VALUE	NAS-Port-Type			Wireless-Other		18
VALUE	NAS-Port-Type			Wireless-802.11		19

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【python3】简易双因子Radius认证服务器,带UI界面 的相关文章

  • GLIBC内存管理源码分析

    1 glibc公共接口 define SIZE SZ sizeof size t 32位机下位4个字节 xff0c 64位机下位8个字节 define MALLOC ALIGNMENT 16 不管是32位还是64位 xff0c 均为16 d
  • codeforces 1328B K-th Beautiful String 规律 水题

    https vjudge net problem CodeForces 1328B 题目大意 xff1a 一个长度为 n n n 的字符串 xff0c 两个字符为 b b b
  • Weak & Strong Alias(强弱别名)

    语句原型 xff1a void smc timing init int cs attribute weak alias 34 smc timing init 34 总结 xff1a smc timing init是smc timing in
  • 苹果手机备份数据到电脑什么位置 iPhone备份到电脑上的东西在哪里

    随着现在备份软件的简化和普及 xff0c 越来越多的人养成了定期对苹果手机进行备份的习惯 那么很多人就会有一个疑问 xff0c 使用备份软件进行备份后 xff0c 备份的数据存放在电脑的什么位置呢 xff1f 下面就来了解一下苹果手机备份数
  • linux 挂起后无法唤醒屏幕

    span class token comment 安装 span span class token function sudo span span class token function apt get span span class t
  • AtCoder ABC 239题解(A ~ E)

    AtCoder ABC 239 A Horizon 语法 43 数学 s q r t a
  • postgresql insert into插入记录时使用select子查询

    span class token keyword INSERT span span class token keyword INTO span ls pos history span class token punctuation span
  • 怎么跟 HR 谈薪资?

    1 做功课 xff1a 提前了解应聘公司的行业薪酬水平 xff0c 公司岗位薪资范围 2 突专业 xff1a 面试电话接通的那一刻 xff0c 就要通过专业能力来为薪酬谈判做铺垫了 3 超预期 xff1a 面试中要总超出岗位需求展示你的全部
  • 量化策略研究员的成长策略

    量化策略研究员需要必备技能 xff1a 1 扎实的数学建模及严谨的逻辑推导能力 xff0c 充分掌握概率 统计等方法 xff1b 2 熟悉机器学习 深度学习 人工智能 xff0c Matlab Python C 43 43 xff1b 3
  • Mac安装MySQL

    目录 一 安装 二 环境变量 2 1 MySQL服务的启停和状态的查看 三 启动 四 初始化设置 4 1 退出sql界面 五 配置 5 1 检测修改结果 一 安装 第一步 xff1a 打开网址 xff0c https www mysql c
  • Win10下安装Ubuntu20.04双系统

    Ubuntu和Linux的区别 搞清楚Linux和Ubuntu的关系 xff1a 1 严格来说 xff0c Linux并不是操作系统 xff0c 而是一个操作系统的内核 xff0c 严谨一些可以说 xff1a linux 一般指 GNU 套
  • 面试的时候,如何自我介绍?

    就是自我介绍的时候 xff0c 应该先说些什么 xff1f 中间怎么说 xff1f 最后怎么结尾 xff1f 主要说那些内容比较好 xff1f 而且在纸质的个人简历之中也有 自我介绍 xff0c 那么两个 自我介绍 的内容是一样的吗 xff
  • 结果论的学习

    结果论 xff0c 是指主张一个行为的对错完全取决于此一行为所造成的结果 xff0c 所谓对的行为就是行为者在面临各种可能的行为选择时 xff0c 采行其中能达成最佳结果的行为 中文名 结果论 外文名 Consequentialethics
  • 如何修改oracle数据库字符集

    1 以管理员身份进入数据库 sqlplus nolog conn sys as sysdba password xxxxxxxx 2 修改字符集 SHUTDOWN IMMEDIATE STARTUP MOUNT ALTER SYSTEM E
  • 详解Redisson分布式限流的实现原理

    我们目前在工作中遇到一个性能问题 xff0c 我们有个定时任务需要处理大量的数据 xff0c 为了提升吞吐量 xff0c 所以部署了很多台机器 xff0c 但这个任务在运行前需要从别的服务那拉取大量的数据 xff0c 随着数据量的增大 xf
  • 聊一聊过度设计!

    文章目录 什么是过度设计 xff1f 过度设计的坏处如何避免过度设计充分理解问题本身保持简单小步快跑征求其他人的意见 总结 新手程序员在做设计时 xff0c 因为缺乏经验 xff0c 很容易写出欠设计的代码 xff0c 但有一些经验的程序员
  • 中国移动业务支撑系统简介(BOSS、BASS、BOMC、4A及VGOP)

    业务支撑系统 xff08 Business Support Systems xff0c 简称BSS xff09 主要应用于通信行业 xff0c 通过该系统对用户执行相应业务操作 它采用省中心 全国中心两级系统架构 xff0c 两级系统相辅相
  • 推荐系统遇上深度学习(一一一)-双重样本感知的DIFM模型

    上一篇中 xff0c 我们介绍了样本感知的FM模型 xff0c 也就是IFM模型 而本文将介绍其改进版本 xff0c 称为Dual Input aware Factorization Machine xff08 DIFM xff09 xff
  • Java高并发之CyclicBarrier简介

    Java 中的 CyclicBarrier 是一种同步工具 xff0c 它可以让多个线程在一个屏障处等待 xff0c 直到所有线程都到达该屏障处后 xff0c 才能继续执行 CyclicBarrier 可以用于协调多个线程的执行 xff0c
  • Linux xargs命令介绍

    Linux 中的 xargs 命令是一个非常有用的命令行工具 xff0c 可以将一些参数集合传递给其他命令作为参数 xff0c 并利用指定的命令进行处理 它可以帮助我们批量处理文件 xff0c 执行一些需要多个参数的命令 xff0c 并且支

随机推荐

  • 深入理解Spring的事件通知机制

    Spring作为一个优秀的企业级应用开发框架 xff0c 不仅提供了众多的功能模块和工具 xff0c 还提供了一种灵活高效的事件通知机制 xff0c 用于处理组件之间的松耦合通讯 本文将详细介绍Spring的事件通知机制的原理 使用方法以及
  • 人工智能未来是否会取代人类程序员?

    这个话题在近期来引起了很大讨论 xff0c 尤其是当GPT4发布后 xff0c 其展现出来的能力让很多岗位的从业者战战兢兢 xff0c 比如像程序员 xff0c 甚至有大佬跳出说三年 AI一定会取代程序员 人工智能和机器人是否会大规模取代人
  • 为什么说过早优化是万恶之源?

    Donald Knuth xff08 高德纳 xff09 是一位计算机科学界的著名学者和计算机程序设计的先驱之一 他被誉为计算机科学的 圣经 计算机程序设计艺术 的作者 xff0c 提出了著名的 大O符号 来描述算法的时间复杂度和空间复杂度
  • Linux parallel 命令使用手册

    文章目录 引言安装和配置GNU Parallel安装配置 GNU Parallel的基本用法GNU Parallel的高级用法1 在多个计算机上并行执行作业2 从文件中读取命令行参数3 生成详细的日志和报告 GNU Parallel的优缺点
  • 使用ffmpeg缩小视频体积的几种方式

    随着视频制作的普及 xff0c 视频文件的体积也越来越大 xff0c 给存储和传输带来了很大的困扰 为了解决这个问题 xff0c 我们可以使用FFmpeg这个强大的工具来缩小视频的体积 本文将介绍三种常用的方法 xff1a 调整视频的分辨率
  • 从CPU的视角看 多线程代码为什么那么难写!

    当我们提到多线程 并发的时候 xff0c 我们就会回想起各种诡异的bug xff0c 比如各种线程安全问题甚至是应用崩溃 xff0c 而且这些诡异的bug还很难复现 我们不禁发出了灵魂拷问 为什么代码测试环境运行好好的 xff0c 一上线就
  • ThreadPoolExecutor——高效处理并发任务的必备良器

    ThreadPoolExecutor 如何使用线程池状态线程池执行任务的过程阻塞队列拒绝策略线程池的监控和调优最佳实践总结 ThreadPoolExecutor是Java concurrent中用于管理线程池的类 xff0c 它是Execu
  • 使用ffmpeg拼接两张图片

    最近在工作中遇到了一个需求 xff0c 就是需要将两张图片拼接在一起 xff0c 作为一个封面图 如果只是临时拼接一张 xff0c 我们可以只用photoshop之类的图片编辑工具 xff0c 将两张图片拼接在一起 而我们的需要是需要实现自
  • 【python】解决[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1076)

    搜了两种方法都没解决这个问题 先介绍下两种方法 1 在代码首部增加如下代码 span class token keyword import span requests span class token punctuation span pa
  • 100G/40G/25G/10G网络测试解决方案

    一 100G概述 随着CDN等视频直播业务和P2P业务的快速发展 xff0c 带宽的要求越来越高 当前5G业务势头正盛 xff0c 其基于400G的主干网络通信业务也在积极部署之中 但当前在很多的业务场景中 xff0c 100G系统的部署仍
  • 交换机测试解决方案

    一 交换机测试概述 自 Kalpana 公司在 1990 年推出第一台以太网交换机以来 xff0c 交换机在30多年的时间内快速的发展 xff0c 成为当今应用最为广泛的网络设备 xff0c 成为整个互联网的基石 以太网交换机以其 高性能
  • IP网络性能测试工具——Renix Perf

    一 Renix Perf 基于软件的网络及应用服务性能测试工具 双臂测试 单臂测试 通过测试端点产生网络流量对网络性能进行测量 TCP UDP PING 语音 视频 HTTP FTP MAIL 组播 测试端点软件可以免费安装部署 二 部署方
  • 网络测试技术——802.1X_MD5认证(下篇)

    上篇我们讲到802 1X MD5的简介 认证过程 测试组网以及测试环境准备 xff0c 本期我们将为大家带来测试的详细步骤 xff1a 六 测试仪配置 1 占用端口 端口功能 xff08 1 xff09 端口1用来模拟DOT1X和发送流量
  • 网络测试技术——802.1X TLS认证(上篇)

    一 TLS认证简介 1 TLS认证 xff08 1 xff09 认证过程 最安全认证技术 实施最复杂 xff08 2 xff09 TLS双向证书认证 服务器对客户端进行认证 客户端对服务器进行认证 2 TLS认证过程 3 交换机认证模式 x
  • SRv6测试技术简介

    什么是SRv6 xff1f SRv6技术就是采用现有的IPv6转发技术 xff0c 通过扩展IPv6报文的头域 xff0c 实现类似标签转发的处理 SRv6将一些IPv6地址定义成实例化的SID xff08 Segment ID xff09
  • RENIX 软件RAW流发送——网络测试仪实操

    本文主要介绍了RENIX软件如何进行RAW流发送操作 文章通过预约端口 添加RAW流 修改负载 发送流量 查看流统计 数据包捕获六个步骤详细介绍了操作过程 步骤一 xff1a 预约端口 1 先安装RENIX软件 xff0c 正确安装情况下桌
  • RENIX软件OSPF和BFD、ISIS和BFD联动测试——网络测试仪实操

    本文介绍了RENIX软件BFD测试相关操作 xff0c 全文分为五大部分 第一部分为BFD概述 xff1b 第二部分为搭建OSPF和BFD联动测试环境 xff1b 第三部分为OSPF和BFD联动测试配置 xff1b 第四部分为搭建ISIS和
  • 信而泰 X-Snapper测试系统,助力家庭路由器IPv6支持度测试

    随着互联网的蓬勃发展 xff0c 宝贵而有限的IPv4地址资源一直在被分配使用 2019年11月25日 xff0c 负责英国 欧洲 中东和部分中亚地区互联网资源分配的欧洲网络协调中心 xff08 RIPE NCC xff09 宣布 xff0
  • 如何使用测试仪进行400G交换机性能测试

    一 400G以太网概述 400G以太网或400 Gigabit Ethernet 400GbE 由 IEEE P802 3bs Task Force 于 2017 年开发 xff0c 它使用与100 Gigabit Ethernet 大致相
  • 【python3】简易双因子Radius认证服务器,带UI界面

    需要将dictionary rfc2865放在运行的同级目录下 coding utf 8 from tkinter import from tkinter ttk import from tkinter import scrolledtex