Linux C/C++ 入侵检测系统(IDS绕过技巧)

news2024/11/17 20:45:54

入侵检测系统(IDS)是一种网络安全设备,其主要功能是对网络传输进行即时监视,并在入侵检测系统(IDS)是一种网络安全设备,其主要功能是对网络传输进行即时监视,并在发现可疑传输时发出警报或者采取主动反应措施。相较于其他网络安全设备,IDS的主要特性在于其积极主动的安全防护技术。它不会跨越多个物理网段,通常只监听一个端口,不需要转发任何流量,只需在网络上被动、无声地收集所关心的报文。

在具体实现上,IDS首先提取收集到的流量统计特征值,并利用内置的入侵知识库对这些流量特征进行智能分析比较匹配。如果某个报文流量与预设阀值的匹配度较高,则该报文将被认为可能是攻击行为,此时,IDS将根据相应的配置进行报警或进行有限度的反击。

IDS实现原理及作用

IDS实现原理:

  - 网络流量分析:IDS监视网络上的数据流量,分析数据包的内容、来源、目标等信息,以寻找异常迹象。
  - 特征检测:IDS使用特定的规则或特征签名来检测已知的攻击模式或恶意行为。这些规则可以基于数字签名、统计学、行为分析等技术实现。
  - 异常检测:IDS还可以通过建模正常的系统和网络活动情况,然后检测出与正常行为明显不同的异常情况。

IDS作用:

 - 攻击检测:IDS可以检测到诸如网络扫描、拒绝服务攻击、恶意软件传播等各种类型的攻击行为。
 - 恶意行为分析:IDS能够发现系统内的恶意活动,如非法访问、异常登录行为等。
 - 事后审计:IDS记录异常事件和攻击行为,便于事后审计和安全调查。

总的来说,IDS的作用是帮助组织监控和保护其网络和系统,及时发现潜在的安全问题,并采取相应的措施来应对。IDS通常与其他安全解决方案如防火墙、入侵预防系统(IPS)等配合使用,形成全面的安全防护体系。

IDS 和iptables 配合使用

iptables 是一个 Linux 系统中用于配置和管理防火墙规则的工具,而入侵检测系统(IDS)则用于监测网络攻击行为并做出相应反应。在使用 iptables 时,可以与 IDS 配合使用,以提高系统的安全性和防护能力。
以下是一些使用 iptables 配合 IDS:

  • 启用 iptables 日志:iptables 可以记录防火墙的日志信息,包括拒绝的连接、异常流量等。将这些日志信息发送给 IDS,可以帮助 IDS 检测和分析攻击行为。在 iptables 规则中,使用 LOG 目标记录日志信息,然后通过 syslog
    或其他方式将日志发送给 IDS。
  • 定义自定义的 iptables 规则:使用 iptables 可以定义自定义的规则,以针对特定的攻击行为或异常流量进行过滤和阻断。可以将这些规则与 IDS 集成,以便在检测到攻击时自动应用相应的规则。
  • 与 IDS 进行联动:iptables 和 IDS 可以进行联动,以实现自动化的防御和响应。例如,当 IDS 检测到攻击行为时,可以触发
    iptables 规则的自动应用,以快速阻断攻击流量或隔离攻击者。同样,当 iptables 规则触发时,也可以通知 IDS
    进行进一步的分析和处理。
  • 管理和维护:在使用 iptables 和 IDS
    的过程中,需要定期管理和维护这些工具。例如,更新规则库、检查日志文件、修复配置错误等。确保定期进行安全审计和漏洞扫描,以确保系统的安全性。

总之,iptables 和 IDS 是 Linux 系统安全性的重要组成部分。通过合理的配置和管理这些工具,可以增强系统的防护能力,并提高对攻击行为的响应速度。

检测网络中的异常行为及代码实现

  • 入侵检测系统(IDS)可以通过在TCP三次握手时注入服务器来检测网络中的异常行为。具体来说,当客户端向服务器发起TCP连接请求时,IDS可以在中间插入自己的IP地址和端口号,与服务器进行通信。这样,IDS就可以截获并分析TCP连接过程中的所有数据包,以检测是否存在恶意攻击或异常行为。

    在TCP三次握手的过程中,客户端首先发送一个SYN包给服务器,表示请求建立连接。服务器收到SYN包后,会回复一个SYN-ACK包,表示同意建立连接。最后,客户端再回复一个ACK包,表示确认建立连接。在这个过程中,IDS可以截获并分析这些数据包,以检测是否存在恶意攻击或异常行为。

iptables -A OUTPUT -p tcp --sport 80 --tcp-flags RST RST -j DROP

这个命令的作用是在iptables防火墙规则中添加一条规则,用于阻止所有从本地主机(源IP地址)发出的TCP连接请求,这些请求的目标端口是80,并且具有RST标志。当满足这些条件时,该规则将丢弃这些连接请求。

...

#define DATA "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 21\r\n\r\nyou have been hacked!"

...
pcap_t* open_pcap_socket(char* device, const char* bpfstr)
{
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t* pd;
    uint32_t  srcip, netmask;
    struct bpf_program  bpf;

    // 如果没有指定网络接口(设备),请获取第一个
    if (!*device && !(device = pcap_lookupdev(errbuf)))
    {
        printf("pcap_lookupdev(): %s\n", errbuf);
        return NULL;
    }
    
    // 打开设备进行实时捕获,而不是读取数据包捕获文件
    if ((pd = pcap_open_live(device, BUFSIZ, 1, 0, errbuf)) == NULL)
    {
        printf("pcap_open_live(): %s\n", errbuf);
        return NULL;
    }

    // 获取网络设备源IP地址和网络掩码
    if (pcap_lookupnet(device, &srcip, &netmask, errbuf) < 0)
    {
        printf("pcap_lookupnet: %s\n", errbuf);
        return NULL;
    }

    if (pcap_compile(pd, &bpf, (char*)bpfstr, 0, netmask))
    {
        printf("pcap_compile(): %s\n", pcap_geterr(pd));
        return NULL;
    }

    // 将数据包筛选器分配给给定的libpcap套接字
    if (pcap_setfilter(pd, &bpf) < 0)
    {
        printf("pcap_setfilter(): %s\n", pcap_geterr(pd));
        return NULL;
    }

    return pd;
}

void capture_loop(pcap_t* pd, int packets, pcap_handler func)
{
    int linktype;
 
    // 确定数据链路层类型。
    if ((linktype = pcap_datalink(pd)) < 0)
    {
        printf("pcap_datalink(): %s\n", pcap_geterr(pd));
        return;
    }
 
    //设置数据链路层标头大小
    switch (linktype)
    {
    case DLT_NULL:
        linkhdrlen = 4;
        break;
 
    case DLT_EN10MB:
        linkhdrlen = 14;
        break;
 
    case DLT_SLIP:
    case DLT_PPP:
        linkhdrlen = 24;
        break;
 
    default:
        printf("Unsupported datalink (%d)\n", linktype);
        return;
    }
 
    // 开始捕获数据包
    if (pcap_loop(pd, packets, func, 0) < 0)
        printf("pcap_loop failed: %s\n", pcap_geterr(pd));
}
...
void parse_packet(u_char *user, struct pcap_pkthdr *packethdr, 
                  u_char *packetptr)
{
...
    // 跳过数据链路层标头并获取IP标头字段
    packetptr += linkhdrlen;
    iphdr = (struct ip*)packetptr;
    strcpy(srcip, inet_ntoa(iphdr->ip_src));
    strcpy(dstip, inet_ntoa(iphdr->ip_dst));
    sprintf(iphdrInfo, "ID:%d TOS:0x%x, TTL:%d IpLen:%d DgLen:%d",
            ntohs(iphdr->ip_id), iphdr->ip_tos, iphdr->ip_ttl,
            4*iphdr->ip_hl, ntohs(iphdr->ip_len));
 

    packetptr += 4*iphdr->ip_hl;
    if (iphdr->ip_p == IPPROTO_TCP )
    {
        tcphdr = (struct tcphdr*)packetptr;
            
        addr_in.sin_family = AF_INET;
        addr_in.sin_port = tcphdr->source;
        addr_in.sin_addr.s_addr = iphdr->ip_src.s_addr;
        
        if (debug_output)
        {
            printf("[*] TCP  %s:%d -> %s:%d\t", srcip, ntohs(tcphdr->source), dstip, ntohs(tcphdr->dest));
            printf( "%c%c%c%c%c%c Seq: 0x%x Ack: 0x%x Win: 0x%x TcpLen: %d\n",
                (tcphdr->urg ? 'U' : '*'), (tcphdr->ack ? 'A' : '*'),
                (tcphdr->psh ? 'P' : '*'), (tcphdr->rst ? 'R' : '*'),
                (tcphdr->syn ? 'S' : '*'), (tcphdr->fin ? 'F' : '*'),
                ntohl(tcphdr->seq), ntohl(tcphdr->ack_seq), ntohs(tcphdr->window), 4*tcphdr->doff
            );
        }
        
        sender_port = ntohs(tcphdr->source);
        seq_number = rand();

        memset(synack_packet, 0, sizeof(synack_packet));
        memset(pshack_packet, 0, sizeof(pshack_packet));
        memset(finack_packet, 0, sizeof(finack_packet));
        memset(ack_packet, 0, sizeof(ack_packet));
        
        // 正在准备SYN-ACK数据包
        ipHdr = (struct iphdr *) synack_packet;
        tcpHdr = (struct tcphdr *) (synack_packet + sizeof(struct iphdr));

        ipHdr->ihl = 5;
        ipHdr->version = 4;
        ipHdr->tos = 0;
        ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
        ipHdr->id = htons(rand());
        ipHdr->frag_off = 0x00; 
        ipHdr->ttl = 0xFF;
        ipHdr->protocol = IPPROTO_TCP;
        ipHdr->check = 0;
        ipHdr->saddr = iphdr->ip_dst.s_addr;
        ipHdr->daddr = iphdr->ip_src.s_addr;

        ipHdr->check = csum((unsigned short *) synack_packet, ipHdr->tot_len); 

        tcpHdr->source = tcphdr->dest; 
        tcpHdr->dest = tcphdr->source;
        tcpHdr->seq = htonl(seq_number);
        seq_number += 1; // 递增序列号
        tcpHdr->ack_seq = htonl(ntohl(tcphdr->seq) + 1);
        tcpHdr->doff = 5;
        tcpHdr->res1 = 0;
        tcpHdr->cwr = 0; 
        tcpHdr->ece = 0;
        tcpHdr->urg = 0;
        tcpHdr->ack = 1; 
        tcpHdr->psh = 0;
        tcpHdr->rst = 0;
        tcpHdr->syn = 1;
        tcpHdr->fin = 0; 
        tcpHdr->window = htons(15500);
        tcpHdr->check = 0; 
        tcpHdr->urg_ptr = 0;
        tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr);
            
        // 准备DATA数据包
        memcpy(pshack_packet, synack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr));
        ipHdr = (struct iphdr *) pshack_packet;
        tcpHdr = (struct tcphdr *) (pshack_packet + sizeof(struct iphdr));
        data = (char *) (pshack_packet + sizeof(struct iphdr) + sizeof(struct tcphdr));
        strcpy(data, DATA);
        ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr) + strlen(data);
        tcpHdr->seq = htonl(seq_number);
        seq_number += strlen(data);// Increment seq number
        tcpHdr->syn = 0;
        tcpHdr->psh = 1;
        tcpHdr->check = 0x0;
        tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr) + strlen(data), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr);
            
        // 准备FIN数据包
        memcpy(finack_packet, pshack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr) + strlen(data));
        ipHdr = (struct iphdr *) finack_packet;
        tcpHdr = (struct tcphdr *) (finack_packet + sizeof(struct iphdr));
        tcpHdr->seq = htonl(seq_number);
        seq_number += 1; // Increment seq number
        ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
        tcpHdr->fin = 1;
        tcpHdr->psh = 0;
        tcpHdr->check = 0x0;
        tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr);
        
        // 正在准备ACK数据包
        memcpy(ack_packet, synack_packet, sizeof(struct iphdr) + sizeof(struct tcphdr));
        ipHdr = (struct iphdr *) ack_packet;
        tcpHdr = (struct tcphdr *) (ack_packet + sizeof(struct iphdr));
        tcpHdr->seq = tcphdr->ack_seq;
        tcpHdr->ack_seq = htonl(ntohl(tcphdr->seq) + 1);
        if (strlen((char*) tcphdr + 4*tcphdr->doff) > 0)
            tcpHdr->ack_seq = htonl(ntohl(tcpHdr->ack_seq) - 1 + strlen((char*) tcphdr + 4*tcphdr->doff));
        ipHdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
        tcpHdr->ack = 1; 
        tcpHdr->psh = 0;
        tcpHdr->rst = 0;
        tcpHdr->syn = 0;
        tcpHdr->fin = 0; 
        tcpHdr->check = 0x0;
        tcpHdr->check = tcp_checksum(tcpHdr, sizeof(struct tcphdr), iphdr->ip_dst.s_addr, iphdr->ip_src.s_addr);
        
        if (tcphdr->syn && !tcphdr->ack )
        {
...
            ipHdr = (struct iphdr *) pshack_packet;            
            if((bytes = sendto(sock, pshack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0)
                perror("Error on sendto()");
            else {
                printf("\t[+] [%s:%d] Sending HTTP response data\n", srcip, ntohs(tcphdr->source));
            }
            ipHdr = (struct iphdr *) finack_packet;            
            if((bytes = sendto(sock, finack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0)
                perror("Error on sendto()");
            else {
                printf("\t[+] [%s:%d] Closing connection. Sending FIN-ACK\n", srcip, ntohs(tcphdr->source));
            }
        }
        else if (tcphdr->ack && (tcphdr->psh || tcphdr->fin) && send_ack)
        {            
            ipHdr = (struct iphdr *) ack_packet;
            if((bytes = sendto(sock, ack_packet, ipHdr->tot_len, 0, (struct sockaddr *) &addr_in, sizeof(addr_in))) < 0)
                perror("Error on sendto()");
            else
                printf("[+] ACKing to [%s:%d]\n", srcip, ntohs(tcphdr->source));
        }
    }
    ...
}


int main(int argc, char **argv)
{
...
    
    sprintf(help, "usage: %s -i <interface> -p <port: 1..65535> [-d] [-a]\n\t-d\tenable debug output\n\t-a\tsend ACK packet to every incoming data packet\n\n", argv[0]);
    
    if((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
        perror("Error while creating socket");
        exit(-1);
    }

    if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one)) < 0) {
        perror("Error while setting socket options");
        exit(-1);
    }
    
    while ((c = getopt (argc, argv, "hadi:p:")) != -1)
    {
        switch (c)
        {
        case 'i':
            strcpy(interface, optarg);
            break;
        case 'p':
            strcpy(port, optarg);
            break;
        case 'd':
            debug_output = 1;
            break;
        case 'a':
            send_ack = 1;
            break;
        case 'h':
        default:
            printf("%s", help);
            exit(0);
            break;
        }
    }
    
    if (atoi(port) < 1 || atoi(port) > 65535 || interface[0] == 0x0)
    {
        printf("%s", help);
        exit(0);
    }
    
    strcat(bpfstr, "tcp and dst port ");
    strcat(bpfstr, port);
    
    if ((pd = open_pcap_socket(interface, bpfstr)))
    {
        capture_loop(pd, 0, (pcap_handler)parse_packet);
    }
...
}

运行效果:
If you need the complete source code, please add the WeChat number (c17865354792)

抓包效果:

IDS(入侵检测系统)绕过技巧

IDS(入侵检测系统)绕过技巧是指利用各种方法来规避或欺骗入侵检测系统的技术手段。IDS是一种网络安全设备,用于监测和检测网络中的入侵行为。它可以根据定义的规则识别可能的攻击行为并提供相应的警报。然而,攻击者可能会尝试绕过IDS以隐藏其攻击活动并规避被检测的风险。

以下是一些可能的IDS绕过技巧的原理和作用:

  1. 基于流量特征的绕过:攻击者可以利用特定协议或传输方式的特征来规避IDS的检测。例如,攻击者可以使用分片或隧道技术来分割或隐藏攻击流量,使其不容易被IDS检测到。

  2. 加密和隐蔽通信:攻击者可以使用加密通信方式或隐蔽通道来隐藏其攻击流量。这可以防止IDS对传输的内容进行检测和分析。

  3. 基于缺陷的攻击:攻击者可以利用IDS本身的漏洞或缺陷来绕过其检测机制。例如,攻击者可能发现IDS的规则规则不完善或配置错误,从而在不被检测到的情况下执行攻击。

  4. 欺骗:攻击者可能试图欺骗IDS来规避被检测。例如,攻击者可以发送特制的数据包以模拟合法流量,从而使IDS无法发现其中的恶意行为。

这些绕过技巧的目的是使攻击者的行为隐蔽,使其能够成功地进行攻击而不被检测或阻止。对抗这些绕过技巧的关键在于不断更新和改进IDS的检测规则和技术,以及加强网络安全防御的整体能力。

总结

入侵检测系统(IDS)是一种用于检测和识别网络攻击的网络安全工具。IDS可以监视网络流量,检测各种攻击行为,并发出警报或采取相应的防御措施。

Welcome to follow WeChat official account【程序猿编码

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

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

相关文章

【tgowt】更新thirdparty

更新完毕后是这样的 之前有过构建但是不能用在owt-p2p项目中,会有崩溃? 【tgowt】cmake转ninja vs构建现在好像都更新到108了 submodule比较麻烦 只修改这里的还不行:一旦git submodule init 后,再改这里的似乎晚了?如果能成功clone就有生成 还必须要改这里的 折腾好几次才…

NL2SQL学习

在学习NL2SQL之前先要进行三W提问&#xff1a; 即what 是什么 &#xff1b; why 为什么使用&#xff1b; how 如何使用 NL2SQL是什么&#xff1f; NL2SQL&#xff08;NLP Natural Language To SQL&#xff09;是自然语言处理的新兴研究热点&#xff0c;顾名思义&#xff0…

【STM32】

STM32 1 CMSIS1.1 概述1.2 CMSIS 应用程序文件描述 2 库2.1 简介2.2 标准外设库&#xff08;standrd Peripheral Libraries&#xff09;2.3 HAL 库2.3.1 目录结构2.3.2 HAL库API函数和变量的命名规则2.3.3 HAL库对寄存器位操作的相关宏定义2.3.4 HAL库回调函数2.3.5 HAL使用注意…

drawio连接线的样式设置

drawio是一款强大的图表绘制软件&#xff0c;支持在线云端版本以及windows, macOS, linux安装版。 如果想在线直接使用&#xff0c;则直接输入网址draw.io或者使用drawon(桌案), drawon.cn内部完整的集成了drawio的所有功能&#xff0c;并实现了云端存储&#xff0c;以及在线共…

给CAD中添加自定义菜单CUIX

本文以AutoCAD2020为例&#xff0c;介绍如何添加自定义菜单。 打开AutoCAD2020&#xff0c;在命令行执行CUI并回车&#xff0c;出现菜单 进入菜单编辑界面 点击传输&#xff0c;然后新建 在菜单上右键&#xff0c;添加自定义菜单 点击保存&#xff0c;即可存为cuix文件。之后…

湖南大学-数据库系统-2018期中考试解析

答案是自己做的&#xff0c;仅供参考。 一、单选题&#xff08;每小题2分&#xff0c;共30分&#xff09; 1、下列关于数据库系统正确的描述是&#xff08; A &#xff09;。 A、数据库系统减少了数据的冗余 B、数据库系统避免了一切冗余 C、数据库系统中数据的一致性是指数据…

leetCode 493 翻转对

给定一个数组 nums &#xff0c;如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。你需要返回给定数组中的重要翻转对的数量。 未完待续~

“辛巴猫舍”内网渗透、提权、撞库学习笔记

前言&#xff1a; 在拿到靶机时&#xff0c;我们最先需要做的是信息收集&#xff0c;包括不限于&#xff1a;C段扫描&#xff0c;端口探测&#xff0c;指纹识别&#xff0c;版本探测等。其次就是 漏洞挖掘、漏洞利用、提权、维持权限、日志清理、留下后门。 以上就是渗透的基本…

企业微信开发教程一:添加企微应用流程图解以及常见问题图文说明

最近在前辈的基础上新添加了一个企微应用&#xff0c;过程中遇到了一些卡点&#xff0c;这里一一通过图片标注与注释的方式记录一下&#xff0c;希望能给后来人提供一些清晰明了的帮助&#xff0c;话不多说&#xff0c;大家直接看图吧。 &#xff08;文中包括一些本项目独有的配…

SPSS二元Logistic回归

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件请点击此链接下…

畅通工程之局部最小花费问题 (C++)

目录 题目&#xff1a; 思路&#xff1a; 代码&#xff1a; 结果 题目&#xff1a; 思路&#xff1a; 详细思路都在代码注释里 。 代码&#xff1a; #include<iostream>//无向图邻接矩阵 #include<map> #include<algorithm> #define mvnum 1005 using …

【论文阅读VLDB13】Online, Asynchronous Schema Change in F1

Online, Asynchronous Schema Change in F1 ABSTRACT 在一个globally 分布式数据库&#xff0c;with shared data, stateless servers, and no global membership.进行一个schema演变。证明许多常见的模式更改可能会导致异常和数据库损坏&#xff0c;通过将破坏引起的模式更改…

第十三章《搞懂算法:神经网络是怎么回事》笔记

目前神经网络技术受到追捧&#xff0c;一方面是由于数据传感设备、数据通信技术和数据存储技术 的成熟与完善&#xff0c;使得低成本采集和存储海量数据得以成为现实;另一方面则是由于计算能力的大幅提升&#xff0c;如图形处理器(Graphics Processing Unit&#xff0c;GPU)在神…

人工智能基础_机器学习023_理解套索回归_认识L1正则---人工智能工作笔记0063

然后上一节我们说了L1,L2正则是为了提高,模型的泛化能力, 提高泛化能力,实际上就是把模型的公式的w,权重值,变小对吧. 然后我们这里首先看第一个L1正则,是怎么做到把w权重变小的 可以看到最上面是线性回归的损失函数,然后 L1可以看到,这个正则,就是在损失函数的基础上给损失…

3D模型人物换装系统

3D模型人物换装系统 介绍遇到的问题问题修复具体实现换装1.准备所有模型部位和模型骨骼部位准备材质准备模型根骨骼准备创建文件夹将上述模型拖成预制体创建一个动画状态机给他们附上待机动画 2.脚本驱动Mesh合并代码 UCombineSkinnedMgr.cs创建Mesh以及实例化对象的代码 UChar…

CSS特效第一弹:右上角tag标志纯代码前端实现(非图片)

&#x1f60e;效果&#xff1a; &#x1f937;‍♂️思路&#xff1a; 分为2个部分&#xff1a; 1.文字方块右下角折角 文字方块用绝对定位z-index让文字方块悬浮在右上角的位置 2.右下角折角通过before伪元素border属性实现(三角形实现方法&#xff09; &#x1f44d;核心代…

人工智能基础_机器学习024_梯度下降进阶_L1正则可视化图形---人工智能工作笔记0064

然后我们就来用代码实现一下L1正则的可视化,我们来看看 首先导入 import numpy as np 数学计算 import matplotlib.pyplot as plt 画图用的 然后我们把L1正则的公式写出来 可以看到L1的正则 其实就是w1和w2的绝对值相加对吧 然后这里我们写一个公式: f(x,y) = |x|+|y| …

12. 定时器按键消抖

12. 定时器按键消抖 定时器按键消抖简介定时器消抖配置步骤程序编写bsp_keyfilter.hbsp_keyfilter.cmain 定时器按键消抖简介 使用延时函数消抖会浪费 CPU 性能&#xff0c;因为延时函数就是空跑。如果按键是使用中断的方式实现的&#xff0c;就更不能在中断服务函数中使用延时…

【基础算法模板梳理】再也不想学算法了!(待更新)

目录 1、【二分】 &#xff08;1&#xff09;rmid —— 大于等于某数的最小值 &#xff08;2&#xff09;lmid —— 小于等于某数的最大值 2、【前缀和】 &#xff08;1&#xff09;一维前缀和 &#xff08;2&#xff09;二维前缀和 3、【差分】 &#xff08;1&#x…

嵌入式中常见的显示屏接口有哪些?

显示屏接口一般有I2C、SPI、UART、RGB、LVDS、MIPI、EDP和DP等。下面简要总结一下。 01 中小屏接口I2C、SPI、UAR 一般3.5寸以下的小尺寸LCD屏&#xff0c;显示数据量比较少&#xff0c;普遍采用低速串口&#xff0c;如I2C、SPI、UART。 I2C&#xff1a; I2C总线是半双工&…