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

网际校验和算法


网际校验和算法

摘 要

本文旨在研究和实现网际校验和(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, scrolledtextdef checksum_calculating(data):"""计算给定数据的校验和(使用Internet Checksum算法)。参数:data (bytes): 要计算校验和的字节数据。返回:int: 计算得到的校验和。"""# 如果数据长度为奇数,补一个0字节if len(data) % 2 != 0:data += b'\x00'checksum = 0for 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 & 0xffffreturn checksumdef 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, payloaddef 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, payloaddef 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_datadef 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 * 4tcp_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_checksumdef 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_checksumdef 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 Nonedef 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:  # IPv4protocol, 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:  # ICMPicmp_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:  # TCPsrc_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_lengthchecksum_data = pseudo_header + tcp_header_for_checksum + tcp_dataif 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:  # UDPsrc_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_lengthchecksum_data = pseudo_header + udp_header_for_checksum + udp_dataif 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("提示", "未选择任何文件。")returntry: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:continuedata_line = Nonefor line in lines:if line.startswith('|'):data_line = linebreakif not data_line:continuepacket_bytes = hexstr_to_bytes(data_line)if packet_bytes is None:output.append(f"无法解析的数据行: {data_line[:50]}...")continuepacket_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.rhkb.cn/news/3502.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python毕业设计选题:基于django+vue的智能租房系统的设计与实现

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 租客注册 添加租客界面 租客管理 房屋类型管理 房屋信息管理 系统管理 摘要 本文首…

联发科MTK6762/MT6762安卓核心板_4G智能模块应用

MT6762安卓核心板是一款工业级高性能、可运行 android9.0 操作系统的 4G智能模块。MT6762平台打造具备 AI 体验、先进双摄像头拍摄效果且具备丰富连接功能的智能手机主板。 MT6762安卓核心板 是一款髙性能低功耗的 4G 全网通安卓智能模块。此模块支持 2G/3G/4G 移动&#xff0c…

彩色图像面积计算一般方法及MATLAB实现

一、引言 在数字图像处理中&#xff0c;经常需要获取感兴趣区域的面积属性&#xff0c;下面给出图像处理的一般步骤。 1.读入的彩色图像 2.将彩色图像转化为灰度图像 3.灰度图像转化为二值图像 4.区域标记 5.对每个区域的面积进行计算和显示 二、程序代码 %面积计算 cle…

重拾Python学习,先从把python删除开始。。。

自己折腾就是不行啊&#xff0c;屡战屡败&#xff0c;最近终于找到前辈教我 第一步 删除Python 先把前阵子折腾的WSL和VScode删掉。还是得用spyder&#xff0c;跟matlab最像&#xff0c;也最容易入手。 从VScode上搞python&#xff0c;最后安装到appdata上&#xff0c;安装插…

Redis系列之底层数据结构字典Dict

Redis系列之底层数据结构字典Dict Dict数据结构 Dict是Redis数据结构中使用最为频繁的复合型数据结构&#xff0c;本质上是一个哈希表 查看redis6.0版本的源码&#xff0c;链接&#xff1a;https://github.com/redis/redis/blob/6.0/src/dict.h 哈希表的结构定义&#xff1…

《贪心算法:原理剖析与典型例题精解》

必刷的贪心算法典型例题&#xff01; 算法竞赛&#xff08;蓝桥杯&#xff09;贪心算法1——数塔问题-CSDN博客 算法竞赛&#xff08;蓝桥杯&#xff09;贪心算法2——需要安排几位师傅加工零件-CSDN博客 算法&#xff08;蓝桥杯&#xff09;贪心算法3——二维数组排序与贪心算…

基于 Python 的深度学习的车俩特征分析系统,附源码

博主介绍&#xff1a;✌stormjun、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

VSCode 的部署

一、VSCode部署 (1)、简介 vsCode 全称 Visual Studio Code&#xff0c;是微软出的一款轻量级代码编辑器&#xff0c;免费、开源而且功能强大。它支持几乎所有主流的程序语言的语法高亮、智能代码补全、自定义热键、括号匹配、代码片段、代码对比Diff、版本管理GIT等特性&…

【开源免费】基于SpringBoot+Vue.JS欢迪迈手机商城(JAVA毕业设计)

本文项目编号 T 141 &#xff0c;文末自助获取源码 \color{red}{T141&#xff0c;文末自助获取源码} T141&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

Transformer创新模型!Transformer+BO-SVR多变量回归预测,添加气泡图、散点密度图(Matlab)

Transformer创新模型&#xff01;TransformerBO-SVR多变量回归预测&#xff0c;添加气泡图、散点密度图&#xff08;Matlab&#xff09; 目录 Transformer创新模型&#xff01;TransformerBO-SVR多变量回归预测&#xff0c;添加气泡图、散点密度图&#xff08;Matlab&#xff0…

Nmap之企业漏洞扫描(Enterprise Vulnerability Scanning for Nmap)

简介 Namp是一个开源的网络连接端扫描软件&#xff0c;主要用于网络发现和安全审核。‌它可以帮助用户识别网络上的设备、分析它们的服务、检测操作系统类型&#xff0c;甚至发现潜在的安全漏洞。Nmap由Fyodor开发&#xff0c;最初是为了满足网络管理员的需求&#xff0c;但随…

windows下安装并使用node.js

一、下载Node.js 选择对应你系统的Node.js版本下载 Node.js官网下载地址 Node.js中文网下载地址??? 这里我选择的是Windows64位系统的Node.js20.18.0&#xff08;LTS长期支持版本&#xff09;版本的.msi安装包程序 官网下载&#xff1a; 中文网下载&#xff1a; 二、安…

Ability Kit-程序框架服务(类似Android Activity)

文章目录 Ability Kit&#xff08;程序框架服务&#xff09;简介Stage模型开发概述Stage模型应用组件应用/组件级配置UIAbility组件概述概述声明配置 生命周期概述生命周期状态说明Create状态WindowStageCreate**和**WindowStageDestroy状态WindowStageWillDestroy状态Foregrou…

Redis超详细入门教程(基础篇)

目录 一、什么是Redis 二、安装Redis 1、Windows系统安装 2、Linux系统安装 三、Redis通用命令 四、Redis基本命令 五、五种数据结构类型 5.1、String类型 5.2、List集合类型 5.3、Set集合类型 5.4、Hash集合类型 5.5、Zset有序集合类型 六、总结 一、什么是Redi…

黑马Java面试教程_P1_导学与准备篇

系列博客目录 文章目录 系列博客目录导学Why?举例 准备篇企业是如何筛选简历的(筛选简历的规则)HR如何筛选简历部门负责人筛选简历 简历注意事项简历整体结构个人技能该如何描述项目该如何描述 应届生该如何找到合适的练手项目项目来源找到项目后&#xff0c;如何深入学习项目…

在Linux上如何让ollama在GPU上运行模型

之前一直在 Mac 上使用 ollama 所以没注意&#xff0c;最近在 Ubuntu 上运行发现一直在 CPU 上跑。我一开始以为是超显存了&#xff0c;因为 Mac 上如果超内存的话&#xff0c;那么就只用 CPU&#xff0c;但是我发现 Llama3.2 3B 只占用 3GB&#xff0c;这远没有超。看了一下命…

算法(蓝桥杯)贪心算法7——过河的最短时间问题解析

一、题目描述 在漆黑的夜里&#xff0c;N位旅行者来到了一座狭窄且没有护栏的桥边。他们只带了一只手电筒&#xff0c;且桥窄得只够让两个人同时过。如果各自单独过桥&#xff0c;N人所需的时间已知&#xff1b;若两人同时过桥&#xff0c;则所需时间是走得较慢的那个人单独行动…

LDD3学习7--硬件接口I/O端口(以short为例)

1 理论 1.1 基本概念 目前对外设的操作&#xff0c;都是通过寄存器。寄存器的概念&#xff0c;其实就是接口&#xff0c;访问硬件接口&#xff0c;有I/O端口通信和内存映射I/O (Memory-Mapped I/O)&#xff0c;I/O端口通信是比较老的那种&#xff0c;都是老的串口并口设备&am…

前端【3】--CSS布局,CSS实现横向布局,盒子模型

盒子分类 1、块级盒子 2、内联级盒子 3、内联块级盒子 4、弹性盒子 5、盒子内部分区 方法一&#xff1a;使用 float 普通盒子实现横向布局 方法二&#xff1a;使用 display: inline-block 内联块级元素实现横向布局 方法三&#xff1a;使用弹性盒子 flexbox&#xff0…

初学stm32 --- flash模仿eeprom

目录 STM32内部FLASH简介 内部FLASH构成&#xff08;F1&#xff09; FLASH读写过程&#xff08;F1&#xff09; 闪存的读取 闪存的写入 内部FLASH构成&#xff08;F4 / F7 / H7&#xff09; FLASH读写过程&#xff08;F4 / F7 / H7&#xff09; 闪存的读取 闪存的写入 …