《计算机网络》课后探研题书面报告_网际校验和算法

news2025/1/15 13:50:10

网际校验和算法


网际校验和算法

摘 要

本文旨在研究和实现网际校验和(Internet Checksum)算法。通过阅读《RFC 1071》文档理解该算法的工作原理,并使用编程语言实现网际校验和的计算过程。本项目将对不同类型的网络报文(包括ICMP、TCP、UDP等)进行差错检验,对捕获的报文进行校验和计算并验证其正确性。项目包括报文数据的读取、校验和的计算以及结果的输出展示等功能。本报告详细描述了算法的实现过程、测试方法和实验结果,并对网际校验和算法在网络通信中的应用进行了分析。通过本次探研,加深了对网络协议差错检测机制的理解,提高了协议分析与实现的能力。

关键字:网际校验和、差错检测、网络协议、报文验证

一、算法概述

网际校验和算法是一种简单且高效的错误检测机制,广泛应用于网络协议中,如IP、TCP、UDP等。其核心思想是在数据传输前生成一个校验和,并通过对数据进行分段求和及取反操作来实现错误检测。接收端通过相同的算法重新计算校验和,如果结果为全0,则说明数据传输过程中未发生错误。

1 算法原理

网际校验和算法由两个核心组件构成:校验和的生成与验证。在数据传输过程中,发送方负责生成校验和,而接收方则执行校验和的验证工作。下面是校验和的详细生成流程:

数据分块:在算法开始时,首先将数据流划分为16位(2字节)为单位的字块。如果数据总长度不是16位的整数倍,则需要在末尾填充0来补足。

把校验和字段置为0:在计算校验和之前,需要先将校验和字段的值置为0。这是因为校验和字段本身也会参与计算,但计算时应当使用0值。

逐块求和:对每个16位字块进行加和,若产生进位(即求和结果超过16位,产生大于65535的结果),则将进位加回到结果的最低位。这个进位的处理是算法的关键,使得加法操作能避免丢失信息。

按位取反:将上述求和结果按位取反(即对所有位进行反转),得到最终的校验和。取反操作是为了增强错误检测的能力,避免某些类型的错误模式(如全0或全1错误)无法被检测到。

校验和的验证则在接收端进行。在接收端,重新进行相同的求和和取反操作(不进行第②步)。如果最终结果是全0,则认为数据未发生错误;如果结果不是全0,则说明数据在传输过程中出现了错误。

该算法的设计使其能够快速且有效地检测常见的数据传输错误,如单比特错误、字节错误等。但它也有局限性,对于一些特定类型的错误(例如数据的字块顺序被改变)可能不敏感,因此它并不是一种完美的错误检测算法,但在多数应用场景下,已能满足需求。

2 算法特点

网际校验和算法在计算机网络中扮演着重要角色,其设计目标是通过简单的操作实现数据传输中的错误检测。由于其独特的特点和广泛的应用价值,该算法在多种网络协议中被广泛采用。以下将从多个方面介绍网际校验和算法的主要特点:

(1)简单高效:计算过程中仅需基本的加法和按位取反操作,执行效率较高,适合硬件加速实现,适用于实时性要求较高的应用场景。

(2)检错能力适中:能有效检测大多数单比特错误和字块错误,但对某些复杂的错误模式(如字节重排)敏感度较低。

(3)广泛应用:被广泛用于IP、TCP、UDP等网络协议中,尤其在需要高效和实时处理的环境中,已成为标准校验方法之一。

(4)实现灵活:由于其简单性,校验和的计算可以根据数据长度和类型的不同进行调整,灵活性较高。

3 算法应用

网际校验和算法因其独特的技术特征,在实际应用中具有广泛的实用价值。该算法凭借计算简便、检错能力适度等优势,已被广泛集成至各类网络协议和应用系统中,为数据传输的完整性与可靠性提供了有效保障。以下将详细介绍该算法在不同领域中的典型应用:

(1)网络通信协议:

  1. IP层(IPv4首部校验和):用于检测IP数据包的头部是否在传输过程中被篡改或损坏。
  2. 传输层(TCP、UDP报文段校验和):用于校验TCP和UDP报文段中的数据完整性,确保数据在传输过程中未被修改。

(2)数据完整性验证:

  1. 文件传输与存储完整性检测:校验和可用于验证文件传输过程中的数据完整性,确保文件未在传输中发生损坏。
  2. 网络设备数据包处理:网络设备通过校验和算法确保接收和转发的数据包完整性。

(3)嵌入式系统:

在嵌入式系统中,尤其是通信模块,使用该算法进行数据校验,确保通信过程中的数据不被篡改或丢失。

(4)网络安全与监控:

网络入侵检测与数据包分析工具:在安全系统中,算法可用于检测网络数据包中的错误或恶意篡改,从而保障网络的安全性。

二、编程实现

1 程序编写

下文将详细介绍如何通过编程实现网际校验和算法。本章节将从编程环境搭建开始,逐步说明代码实现的具体步骤、关键函数的设计思路以及数据处理的方法。通过这个实践过程,我们不仅能够深入理解网际校验和算法的工作原理,也能掌握如何将理论算法转化为可执行的程序代码。程序采用Python语言实现,代码结构清晰,便于理解和后续的维护与扩展。

1.1 编程环境

编程环境的正确配置是确保程序开发和运行顺利进行的重要前提。我选择了Windows 11作为开发平台,搭配功能强大的PyCharm作为集成开发环境,使用广受欢迎的Python编程语言,并将处理来自Wireshark工具导出的“.txt”格式数据文件。这些工具的选择既考虑了开发效率,也兼顾了程序的可移植性和扩展性。

  1. 操作系统:Windows 11
  2. 开发工具:PyCharm
  3. 编程语言:Python
  4. 数据文档格式:从Wireshark工具软件导出的原始数据包,为“.txt”格式。

图1 数据文档格式图

图1 数据文档格式图

1.2 校验流程

本次编码不仅完成了对IP数据报首部的校验,还实现了ICMP、TCP、UDP报文的校验功能。鉴于整个实现流程较为复杂,此处仅展示IP数据报首部的关键校验流程。具体的IP数据报首部校验流程如下图所示(非标准流程图):

图2 IP数据报首部校验流程图

图2 IP数据报首部校验流程图

1.3 核心代码

鉴于IP报文首部校验和的计算与验证机制涉及多个分散的代码模块,此处仅展示其核心实现部分。完整的实现细节请参阅源代码。

(1)校验和计算函数`checksum_calculating`:实现标准的网际校验和算法,用于计算IP头部校验和。在函数中,校验和的计算流程如下:①从输入数据中检查长度,若为奇数则进行字节补齐;②对数据按16位为单位进行累加计算;③将进位加至最低位;④对最终结果取反得到校验和。具体代码如下图所示:

图3 校验和计算函数

图3 校验和计算函数

(2)校验和验证函数`process_packet_to_string`:实现接收数据包的校验和验证。在函数中,校验和的验证流程如下:①从接收的IP首部中提取原始校验和;②构造用于校验和计算的IP首部数据;③调用`checksum_calculating`函数计算当前校验和;④将计算得到的校验和与原始校验和进行比对。部分代码如下图所示:

图4 校验和验证函数(部分)

图4 校验和验证函数(部分)

2 程序测试

为验证程序的正确性,下面我将对我编写的用于网际校验和验证的程序进行测试。

2.1 测试文件

本次测试的数据文件均来自于计网实验5,从中选取典型的ICMP、UDP、TCP报文各一个。测试文件分别为“ICMP.txt”、“TCP.txt”、“UDP.txt”。这些文件包含了真实网络环境中的典型数据包,能够很好地验证算法在实际应用场景中的表现。测试文件内容格式如前文所述。

图5 测试文件

图5 测试文件

2.2 测试结果

(1)ICMP

下图是ICMP报文的具体内容,可以看到它的IP首部校验和为“f2 24”(图中蓝色高亮部分)。

图6 ICMP报文

图6 ICMP报文

下图是程序读取该报文后的测试结果,程序运行结果正确,与预期一致。

图7 ICMP报文测试结果

图7 ICMP报文测试结果

(2)TCP

下图是TCP报文的具体内容,可以看到它的IP首部校验和为“cd 6c”(图中蓝色高亮部分)。

图8 TCP报文

图8 TCP报文

下图是程序读取该报文后的测试结果,程序运行结果正确,与预期一致。

图9 TCP报文测试结果

图9 TCP报文测试结果

(3)UDP 

下图是UDP报文的具体内容,可以看到它的IP首部校验和为“c0 d3”(图中蓝色高亮部分)。

图10 UDP报文

图10 UDP报文

下图是程序读取该报文后的测试结果,程序运行结果正确,与预期一致。

图11 UDP报文测试结果

图11 UDP报文测试结果

结 论

本次探研通过深入分析网际校验和算法的原理并进行实践实现,取得了以下主要成果:

(1)完成了网际校验和算法的理论研究和代码实现。通过研读《RFC 1071》文档,深入理解了该算法的工作原理,包括数据分块、校验和计算和验证等核心过程。研究表明该算法具有实现简单、计算效率高等特点,这也解释了其在网络协议中的广泛应用。

(2)成功开发了一个能够处理多种网络协议报文的校验程序。该程序不仅实现了IP数据报首部的校验,还扩展支持了ICMP、TCP、UDP等多种协议报文的校验功能。通过实际测试,程序能够正确计算和验证各类报文的校验和,验证结果与实际数据包中的校验和完全匹配。

(3)通过实践验证了网际校验和算法在差错检测方面的有效性。虽然该算法在某些特定错误模式(如字节重排)的检测上存在局限性,但其简单高效的特点使其非常适合网络通信中的实时差错检测需求。

(4)本次探研的实践过程加深了对网络协议差错检测机制的理解,提高了协议分析与实现的能力。通过编程实现和测试验证,不仅掌握了算法的技术细节,也认识到了在实际网络环境中确保数据传输可靠性的重要性。

总的来说,本次探研不仅完成了对网际校验和算法的理论学习和实践实现,还通过具体的程序开发和测试验证了该算法的实用价值。这些工作为进一步理解和应用网络协议中的差错检测机制奠定了基础。

参考文献

  1. Braden R, Borman D A, Partridge C. RFC 1071 Computing the Internet Checksum[S]. Fremont: RFC Editor, 1988.
  2. 李毅,张帆,张润宇.IPv4头部校验和的反码算法[J].武汉理工大学学报,2003,(04):64-68.
  3. 刘派.IP首部校验算法[J].电脑知识与技术,2010,6(19):5194-5196.
  4. 乔世成,张智丰,廉洁.IP首部校验和算法研究[J].内蒙古民族大学学报(自然科学版),2016,31(05):400-402.DOI:10.14045/j.cnki.15-1220.2016.05.010.
  5. 孔庆春.当前应用于计算机通信中的差错检测与控制技术[J].信息与电脑(理论版),2017,(18):146-148.

参考代码

import struct
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext


def checksum_calculating(data):
    """
    计算给定数据的校验和(使用Internet Checksum算法)。

    参数:
        data (bytes): 要计算校验和的字节数据。

    返回:
        int: 计算得到的校验和。
    """
    # 如果数据长度为奇数,补一个0字节
    if len(data) % 2 != 0:
        data += b'\x00'

    checksum = 0
    for i in range(0, len(data), 2):
        word = struct.unpack('!H', data[i:i + 2])[0]
        checksum += word
        # 处理进位
        while checksum >> 16:
            checksum = (checksum & 0xffff) + (checksum >> 16)

    checksum = ~checksum & 0xffff
    return checksum


def parse_ethernet_frame(data):
    """
    解析以太网帧头,提取EtherType。

    参数:
        data (bytes): 以太网帧的字节数据。

    返回:
        tuple: (ethertype (int), payload (bytes))。

    异常:
        ValueError: 数据长度不足以解析以太网帧头。
    """
    if len(data) < 14:
        raise ValueError("数据长度不足以解析以太网帧头")

    # 查找EtherType为0x0800(IPv4)的位置
    for i in range(len(data) - 2):
        if data[i] == 0x08 and data[i + 1] == 0x00:
            eth_header = data[:i + 2]
            payload = data[i + 2:]
            return 0x0800, payload

    # 如果未找到,使用标准解析方法
    eth_header = data[:14]
    eth_fields = struct.unpack('!6s6sH', eth_header)
    ethertype = eth_fields[2]
    payload = data[14:]
    return ethertype, payload


def parse_ip_packet(data):
    """
    解析IP数据包,提取协议类型和IP头部。

    参数:
        data (bytes): IP数据包的字节数据。

    返回:
        tuple: (protocol (int), ip_header (bytes), payload (bytes))。

    异常:
        ValueError: 数据长度不足以解析IP头部或完整的IP头部。
    """
    if len(data) < 20:
        raise ValueError("数据长度不足以解析IP头部")

    version_ihl = data[0]
    ihl = (version_ihl & 0x0F) * 4  # 头部长度
    if len(data) < ihl:
        raise ValueError("数据长度不足以解析完整的IP头部")

    ip_header = data[:ihl]
    protocol = data[9]
    payload = data[ihl:]
    return protocol, ip_header, payload


def parse_icmp_packet(data):
    """
    解析ICMP数据包。

    参数:
        data (bytes): ICMP数据包的字节数据。

    返回:
        tuple: (icmp_type (int), icmp_code (int), icmp_data (bytes),
                received_checksum (int), checksum_data (bytes))。

    异常:
        ValueError: 数据长度不足以解析ICMP头部。
    """
    if len(data) < 4:
        raise ValueError("数据长度不足以解析ICMP头部")

    icmp_header = data[:4]
    icmp_fields = struct.unpack('!BBH', icmp_header)
    icmp_type = icmp_fields[0]
    icmp_code = icmp_fields[1]
    received_checksum = icmp_fields[2]
    icmp_data = data[4:]

    # 创建用于计算校验和的数据(校验和字段置0)
    checksum_data = data[:2] + b'\x00\x00' + data[4:]
    return icmp_type, icmp_code, icmp_data, received_checksum, checksum_data


def parse_tcp_packet(data):
    """
    解析TCP数据包。

    参数:
        data (bytes): TCP数据包的字节数据。

    返回:
        tuple: (src_port (int), dest_port (int), seq_num (int), ack_num (int),
                tcp_header_for_checksum (bytes), tcp_data (bytes),
                received_checksum (int))。

    异常:
        ValueError: 数据长度不足以解析TCP头部。
    """
    if len(data) < 20:
        raise ValueError("数据长度不足以解析TCP头部")

    tcp_header = data[:20]
    tcp_fields = struct.unpack('!HHLLHHHH', tcp_header)
    src_port = tcp_fields[0]
    dest_port = tcp_fields[1]
    seq_num = tcp_fields[2]
    ack_num = tcp_fields[3]
    offset_reserved_flags = tcp_fields[4]
    window = tcp_fields[5]
    received_checksum = tcp_fields[6]
    urgent_pointer = tcp_fields[7]

    # 提取数据偏移、保留和标志位
    data_offset = (offset_reserved_flags >> 12) & 0xF  # 数据偏移(高4位)
    reserved = (offset_reserved_flags >> 6) & 0x3F  # 保留位(中间6位)
    flags = offset_reserved_flags & 0x3F  # 标志位(低6位)
    data_offset = data_offset * 4

    tcp_data = data[data_offset:]

    # 校验和计算时,将校验和字段置零,但保留整个20字节头部
    tcp_header_for_checksum = tcp_header[:16] + b'\x00\x00' + tcp_header[18:20]

    return src_port, dest_port, seq_num, ack_num, tcp_header_for_checksum, tcp_data, received_checksum


def parse_udp_packet(data):
    """
    解析UDP数据包。

    参数:
        data (bytes): UDP数据包的字节数据。

    返回:
        tuple: (src_port (int), dest_port (int), length (int),
                udp_header_for_checksum (bytes), udp_data (bytes),
                received_checksum (int))。

    异常:
        ValueError: 数据长度不足以解析UDP头部。
    """
    if len(data) < 8:
        raise ValueError("数据长度不足以解析UDP头部")

    udp_header = data[:8]
    udp_fields = struct.unpack('!HHHH', udp_header)
    src_port = udp_fields[0]
    dest_port = udp_fields[1]
    length = udp_fields[2]
    received_checksum = udp_fields[3]
    udp_data = data[8:]

    # 将校验和字段置零用于计算
    udp_header_for_checksum = udp_header[:6] + b'\x00\x00'
    return src_port, dest_port, length, udp_header_for_checksum, udp_data, received_checksum


def hexstr_to_bytes(line):
    """
    将十六进制字符串转换为字节数据。

    参数:
        line (str): 包含十六进制数的字符串,每个字节由两个十六进制字符表示,
                    字节之间用'|'分隔。

    返回:
        bytes or None: 转换后的字节数据,如果转换失败则返回None。
    """
    try:
        parts = line.strip().split('|')
        # 去除空白部分
        parts = [p.strip() for p in parts if p.strip()]

        if len(parts) > 1:
            parts = parts[1:]  # 去掉偏移量字段

        # 确保每个部分有两个字符,不足则前置补零
        hex_pairs = [p.zfill(2) for p in parts]
        hex_cleaned = ''.join(hex_pairs)
        return bytes.fromhex(hex_cleaned)
    except Exception:
        return None


def process_packet_to_string(packet_bytes):
    """
    处理数据包并将解析结果格式化为字符串。

    参数:
        packet_bytes (bytes): 要处理的数据包字节数据。

    返回:
        str: 格式化后的解析结果。
    """
    result = []
    result.append(f"原始报文数据 ({len(packet_bytes)} 字节): {packet_bytes.hex()}")

    try:
        # 解析以太网帧
        ethertype, payload = parse_ethernet_frame(packet_bytes)
        result.append(f"以太网类型: 0x{ethertype:04x}")

        if ethertype == 0x0800:  # IPv4
            protocol, ip_header, ip_payload = parse_ip_packet(payload)
            result.append(f"IP协议版本: {ip_header[0] >> 4}")
            result.append(f"IP首部长度: {(ip_header[0] & 0x0F) * 4} 字节")
            result.append(f"IP协议: {protocol}")

            # IP校验和
            received_ip_checksum = struct.unpack('!H', ip_header[10:12])[0]
            ip_header_for_checksum = ip_header[:10] + b'\x00\x00' + ip_header[12:]
            calculated_ip_checksum = checksum_calculating(ip_header_for_checksum)
            result.append(f"接收的IP校验和: 0x{received_ip_checksum:04x}")
            result.append(f"计算的IP校验和: 0x{calculated_ip_checksum:04x}")
            if received_ip_checksum == calculated_ip_checksum:
                result.append("IP校验和正确")
            else:
                result.append("IP校验和错误")

            if protocol == 1:  # ICMP
                icmp_type, icmp_code, icmp_data, received_checksum, checksum_data = parse_icmp_packet(ip_payload)
                calculated_checksum = checksum_calculating(checksum_data)
                result.append(f"ICMP类型: {icmp_type}, 代码: {icmp_code}")
                result.append(f"ICMP接收的校验和: 0x{received_checksum:04x}")
                result.append(f"ICMP计算的校验和: 0x{calculated_checksum:04x}")
                if received_checksum == calculated_checksum:
                    result.append("ICMP校验和正确")
                else:
                    result.append("ICMP校验和错误")

            elif protocol == 6:  # TCP
                src_port, dest_port, seq_num, ack_num, tcp_header_for_checksum, tcp_data, received_checksum = parse_tcp_packet(
                    ip_payload)

                source_ip = ip_header[12:16]  # 源IP地址
                destination_ip = ip_header[16:20]  # 目的IP地址

                reserved_zero = b'\x00'
                protocol_byte = struct.pack('!B', protocol)
                segment_length = len(tcp_header_for_checksum) + len(tcp_data)
                tcp_length = struct.pack('!H', segment_length)

                # 构造伪头部用于校验和计算
                pseudo_header = source_ip + destination_ip + reserved_zero + protocol_byte + tcp_length
                checksum_data = pseudo_header + tcp_header_for_checksum + tcp_data

                if len(checksum_data) % 2 != 0:
                    checksum_data += b'\x00'

                calculated_checksum = checksum_calculating(checksum_data)

                result.append(f"TCP源端口: {src_port}, 目的端口: {dest_port}")
                result.append(f"TCP接收的校验和: 0x{received_checksum:04x}")
                result.append(f"TCP计算的校验和: 0x{calculated_checksum:04x}")
                if received_checksum == calculated_checksum:
                    result.append("TCP校验和正确")
                else:
                    result.append("TCP校验和错误")

            elif protocol == 17:  # UDP
                src_port, dest_port, length, udp_header_for_checksum, udp_data, received_checksum = parse_udp_packet(
                    ip_payload)

                source_ip = ip_header[12:16]  # 源IP地址
                destination_ip = ip_header[16:20]  # 目的IP地址

                reserved_zero = b'\x00'
                protocol_byte = struct.pack('!B', protocol)
                udp_length = struct.pack('!H', length)

                # 构造伪头部用于校验和计算
                pseudo_header = source_ip + destination_ip + reserved_zero + protocol_byte + udp_length
                checksum_data = pseudo_header + udp_header_for_checksum + udp_data

                if len(checksum_data) % 2 != 0:
                    checksum_data += b'\x00'

                calculated_checksum = checksum_calculating(checksum_data)

                result.append(f"UDP源端口: {src_port}, 目的端口: {dest_port}")
                result.append(f"UDP接收的校验和: 0x{received_checksum:04x}")
                result.append(f"UDP计算的校验和: 0x{calculated_checksum:04x}")
                if received_checksum == calculated_checksum:
                    result.append("UDP校验和正确")
                else:
                    result.append("UDP校验和错误")

            else:
                result.append(f"未支持的IP协议类型: {protocol}")

        else:
            result.append(f"未支持的以太网类型: 0x{ethertype:04x}")

    except ValueError as ve:
        result.append("解析报文时出错: " + str(ve))

    return '\n'.join(result)


def main_gui():
    """
    主函数,创建图形界面,选择文件,解析报文,计算校验和并显示结果。
    """
    root = tk.Tk()
    root.title("网际校验和分析工具")
    root.geometry("800x600")

    # 创建可滚动文本区域显示结果
    text_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=100, height=40)
    text_area.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)

    def select_file():
        """
        处理文件选择和报文解析。
        """
        file_path = filedialog.askopenfilename(
            title="选择测试文件",
            filetypes=(("文本文件", "*.txt"), ("所有文件", "*.*"))
        )

        if not file_path:
            messagebox.showinfo("提示", "未选择任何文件。")
            return

        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read().strip()

            packets = content.split('\n\n')
            output = []

            for packet in packets:
                lines = packet.strip().split('\n')
                if len(lines) < 2:
                    continue

                data_line = None
                for line in lines:
                    if line.startswith('|'):
                        data_line = line
                        break

                if not data_line:
                    continue

                packet_bytes = hexstr_to_bytes(data_line)
                if packet_bytes is None:
                    output.append(f"无法解析的数据行: {data_line[:50]}...")
                    continue

                packet_result = process_packet_to_string(packet_bytes)
                output.append(packet_result)

            # 显示解析结果
            text_area.delete(1.0, tk.END)
            text_area.insert(tk.END, '\n\n'.join(output))

        except Exception as e:
            messagebox.showerror("错误", f"发生错误: {e}")

    # 创建选择文件并分析的按钮
    select_button = tk.Button(root, text="选择测试文件并分析", command=select_file)
    select_button.pack(pady=10)

    root.mainloop()


if __name__ == "__main__":
    main_gui()

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

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

相关文章

业务幂等性技术架构体系之接口幂等深入剖析

在实际应用中&#xff0c;由于网络不稳定、系统延迟等原因&#xff0c;客户端可能会重复发送相同的请求。如果这些重复请求都被服务器处理并执行&#xff0c;就可能导致意想不到的问题&#xff0c;比如重复扣款、多次下单或者数据不一致等。 这就是为什么我们需要接口幂等性。…

sql模糊关联匹配

需求目标&#xff1a; 建立临时表 drop table grafana_bi.zbj_gift_2024;USE grafana_bi; CREATE TABLE zbj_gift_2024 (id INT AUTO_INCREMENT PRIMARY KEY,userName VARCHAR(255),giftName VARCHAR(255),giftNum INT,points INT,teacher VARCHAR(255),sendDate DATETIME,…

《蜜蜂路线》

题目背景 无 题目描述 一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你&#xff1a;蜜蜂从蜂房 mm 开始爬到蜂房 nn&#xff0c;m<nm<n&#xff0c;有多少种爬行路线&#xff1f;&#xff08;备注&#xff1a;题面有误&am…

LeetCode100之搜索二维矩阵(46)--Java

1.问题描述 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回…

JS爬虫实战演练

在这个小红书私信通里面进行一个js的爬虫 文字发送 async function sendChatMessage(content) {const url https://pro.xiaohongshu.com/api/edith/ads/pro/chat/chatline/msg;const params new URLSearchParams({porch_user_id: 677e116404ee000000000001});const messageD…

自动连接校园网wifi脚本实践(自动网页认证)

目录 起因执行步骤分析校园网登录逻辑如何判断当前是否处于未登录状态&#xff1f; 书写代码打包设置开机自动启动 起因 我们一般通过远程控制的方式访问实验室电脑&#xff0c;但是最近实验室老是断电&#xff0c;但重启后也不会自动连接校园网账户认证&#xff0c;远程工具&…

WPS计算机二级•表格函数计算

听说这里是目录哦 函数基础知识 相对绝对混合引用&#x1f32a;️相对引用绝对引用混合引用 常用求和函数 SUM函数&#x1f326;️语法说明 函数快速求 平均数最值⚡平均数最值 实用统计函数 实现高效统计&#x1f300;COUNTCOUNTIF 实用文本函数 高效整理数据&#x1f308;RIG…

自动化测试工具Ranorex Studio(八十九)-解决方案浏览器

解决方案浏览器 除了为项目添加条目外&#xff0c;’Solution Explorer’允许你编辑解决方案的其他辅助选项。 例如&#xff0c;增加文件夹从而将项目中的录制模块和代码模块分离开来。 图&#xff1a;在solution browser中为项目添加文件夹 另外&#xff0c;你可以删除不用的…

2025 年 UI 大屏设计新风向

在科技日新月异的 2025 年&#xff0c;UI 大屏设计领域正经历着深刻的变革。随着技术的不断进步和用户需求的日益多样化&#xff0c;新的设计风向逐渐显现。了解并掌握这些趋势&#xff0c;对于设计师打造出更具吸引力和实用性的 UI 大屏作品至关重要。 一、沉浸式体验设计 如…

绘制三角形、正六边形、五角星、六角星

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>绘制图形</title><style>body {displ…

LLM实现视频切片合成 前沿知识调研

1.相关产品 产品链接腾讯智影https://zenvideo.qq.com/可灵https://klingai.kuaishou.com/即梦https://jimeng.jianying.com/ai-tool/home/Runwayhttps://aitools.dedao.cn/ai/runwayml-com/Descripthttps://www.descript.com/?utm_sourceai-bot.cn/Opus Cliphttps://www.opu…

Node.js - HTTP

1. HTTP请求 HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本传输协议&#xff09;是客户端和服务器之间通信的基础协议。HTTP 请求是由客户端&#xff08;通常是浏览器、手机应用或其他网络工具&#xff09;发送给服务器的消息&#xff0c;用来请求资源或执行…

鸿蒙中自定义slider实现字体大小变化

ui&#xff1a; import { display, mediaquery, router } from kit.ArkUI import CommonConstants from ./CommonConstants; import PreferencesUtil from ./PreferencesUtil; import StyleConstants from ./StyleConstants;// 字体大小 Entry Component struct FontSize {Sta…

Springboot + vue 小区物业管理系统

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;&#x1f525;&…

uni-app编写微信小程序使用uni-popup搭配uni-popup-dialog组件在ios自动弹出键盘。

uni-popup-dialog 对话框 将 uni-popup 的type属性改为 dialog&#xff0c;并引入对应组件即可使用对话框 &#xff0c;该组件不支持单独使用 示例 <button click"open">打开弹窗</button> <uni-popup ref"popup" type"dialog"…

RabbitMQ中有哪几种交换机类型?

大家好&#xff0c;我是锋哥。今天分享关于【RabbitMQ中有哪几种交换机类型&#xff1f;】面试题。希望对大家有帮助&#xff1b; RabbitMQ中有哪几种交换机类型&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在RabbitMQ中&#xff0c;交换机&#xf…

Uniapp中实现加载更多、下拉刷新、返回顶部功能

一、加载更多&#xff1a; 在到达底部时&#xff0c;将新请求过来的数据追加到原来的数组即可&#xff1a; import {onReachBottom } from "dcloudio/uni-app";const pets ref([]); // 显示数据function network() {uni.request({url: "https://api.thecatap…

Kotlin 循环语句详解

文章目录 循环类别for-in 循环区间整数区间示例1&#xff1a;正向遍历示例2&#xff1a;反向遍历 示例1&#xff1a;遍历数组示例2&#xff1a;遍历区间示例3&#xff1a;遍历字符串示例4&#xff1a;带索引遍历 while 循环示例&#xff1a;计算阶乘 do-while 循环示例&#xf…

【零基础租赁实惠GPU推荐及大语言模型部署教程01】

租赁GPU推荐及大语言模型部署简易教程 1 官网地址2 注册账号及登录3 租用GPU3.1 充值&#xff08;不限制充值最低金额&#xff0c;1元亦可&#xff09;3.2 容器实例&#xff08;实际就是你租用的GPU电脑&#xff09;3.3 选择镜像&#xff08;选择基础环境&#xff1a;框架版本和…

Centos 宝塔安装

yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh 安装成功界面 宝塔说明文档 https://www.bt.cn/admin/servers#wcu 或者可以注册宝塔账号 1 快速部署 安装docker 之后 2 需要在usr/bin下下载do…