当前位置: 首页 > news >正文

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

网际校验和算法


网际校验和算法

摘 要

本文旨在研究和实现网际校验和(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()

相关文章:

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

网际校验和算法 摘 要 本文旨在研究和实现网际校验和&#xff08;Internet Checksum&#xff09;算法。通过阅读《RFC 1071》文档理解该算法的工作原理&#xff0c;并使用编程语言实现网际校验和的计算过程。本项目将对不同类型的网络报文&#xff08;包括ICMP、TCP、UDP等&a…...

hot100_240. 搜索二维矩阵 II

hot100_240. 搜索二维矩阵 II 直接遍历列减行增 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,1…...

78_Redis网络模型

1.Redis网络模型概述 1.1 Redis网络模型介绍 Redis 7.x的网络模型基于epoll的Reactor模式实现,这是一个高效的事件驱动模型。在Redis中,所有的网络事件(如连接、读写等)都由一个事件循环(Event Loop)来处理。这个事件循环负责监听套接字上的事件,并根据事件类型调用相…...

python范围

用户图形界面-工资计算器 from tkinter import *def f():w int(e1.get()) int(e2.get()) - int(e3.get())wage.insert(0,w)root Tk() root.title("工资计算器") Label(root, text"每月基本工资&#xff1a;").pack() e1 Entry(root) e1.pack() Label(…...

vulnhub靶场【Raven系列】之2 ,对于mysql udf提权的复习

前言 靶机&#xff1a;Raven-2&#xff0c;IP地址为192.168.10.9 攻击&#xff1a;kali&#xff0c;IP地址为192.168.10.2 都采用虚拟机&#xff0c;网卡为桥接模式 文章所用靶机来自vulnhub&#xff0c;可通过官网下载&#xff0c;或者通过链接:https://pan.quark.cn/s/a65…...

基于vite+vue3+mapbox-gl从零搭建一个项目

下面是基于 Vite、Vue 3 和 Mapbox GL 从零搭建一个项目的完整步骤&#xff0c;包括环境搭建、依赖安装、配置和代码示例。 1. 初始化项目 首先&#xff0c;使用 Vite 快速创建一个 Vue 3 项目&#xff1a; npm create vuelatest vue3-mapboxgl --template vue cd vue3-mapbo…...

向harbor中上传镜像(向harbor上传image)

向 Harbor 中上传镜像通常分为以下几个步骤&#xff1a; 1、登录 Harbor 2、构建镜像 3、标记镜像 4、推送镜像到 Harbor 仓库 1、登录 Harbor 首先&#xff0c;确保你已经能够访问 Harbor&#xff0c;并且已经注册了账户。如果还没有 Harbor 账户&#xff0c;你需要先注册一…...

【线性代数】行列式的性质

行列式性质定理讲义 一、行列式的基本性质 性质 1&#xff1a;行列互换 对于任意一个 n n n \times n nn 的方阵 A A A&#xff0c;其行列式 ∣ A ∣ |A| ∣A∣ 满足&#xff1a; ∣ A ∣ ∣ A T ∣ |A| |A^T| ∣A∣∣AT∣ 其中&#xff0c; A T A^T AT 是 A A A 的…...

智能家居企业如何通过设计师渠道打造第二曲线?

随着智能家居行业的迅速发展和消费者需求的不断升级&#xff0c;企业的营销策略也在不断变化。传统的B2C营销模式逐渐让位于更加精细化、定制化的B2B2C模式&#xff0c;其中设计师渠道的开发与合作&#xff0c;成为智能家居企业布局市场、提升品牌影响力的关键。 智能家居推广的…...

Unity3d 实时天气系统基于UniStorm插件和xx天气API实现(含源码)

前言 实时天气在Unity3d三维数字沙盘中的作用非常重要&#xff0c;它能够增强虚拟环境的真实感和互动性&#xff0c;实时天气数据的应用可以提供更为精准和直观的天气信息支持&#xff0c;如果真实的数据加上特效、声音和模型反馈会提高产品档次&#xff0c;提高真实感。 目前…...

年后找工作需要注意的事项

大家好&#xff01;我是 [数擎 AI]&#xff0c;一位热爱探索新技术的前端开发者&#xff0c;在这里分享前端和 Web3D、AI 技术的干货与实战经验。如果你对技术有热情&#xff0c;欢迎关注我的文章&#xff0c;我们一起成长、进步&#xff01; 开发领域&#xff1a;前端开发 | A…...

模拟器多开窗口单IP与代理IP关系

模拟器多开窗口同IP背后出现的问题 在游戏世界中&#xff0c;模拟器多开窗口是玩家们提升体验的常见做法。通过在同一设备上开启多个模拟器窗口&#xff0c;玩家可以同时运营多个游戏账号&#xff0c;增加游戏的趣味性和效率。 一旦检测到一个IP地址下登录了过多的账号&#x…...

Android ScrollView嵌套X5WebView大片空白问题

scrollview嵌套后webview的高度不可控。留有大片空白。 注&#xff1a;官方不建议scrollview嵌套webview 最好让webview自身滚动 解决方案&#xff1a; act_news_detail_wv.setWebViewClient(new WebViewClient() {Overridepublic void onPageFinished(WebView webView, Str…...

Java Web开发进阶——WebSocket与实时通信

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议&#xff0c;广泛应用于需要实时数据交换的应用程序中。它能够实现服务器与客户端之间的双向通信&#xff0c;避免了传统 HTTP 请求/响应的延迟。结合 Spring Boot&#xff0c;开发实时通信应用变得更加高效与简便。 1. …...

zerotier搭建虚拟局域网,自建planet

基于该开源项目 自建planet节点&#xff0c;更快速&#xff0c;更安全 本教程依据docker-zerotier-planet 项目文档书写&#xff0c;并以linux(centos 7)和windows作为示例&#xff0c;需要其他系统配置方法&#xff0c;可移步项目文档 一. 前置资源 具有外网ip的服务器 后面…...

SQL面试题1:连续登陆问题

引言 场景介绍&#xff1a; 许多互联网平台为了提高用户的参与度和忠诚度&#xff0c;会推出各种连续登录奖励机制。例如&#xff0c;游戏平台会给连续登录的玩家发放游戏道具、金币等奖励&#xff1b;学习类 APP 会为连续登录学习的用户提供积分&#xff0c;积分可兑换课程或…...

2Spark Core

2Spark Core 1.RDD 详解1) 为什么要有 RDD?2) RDD 是什么?3) RDD 主要属性 2.RDD-API1) RDD 的创建方式2) RDD 的算子分类3) Transformation 转换算子4) Action 动作算子 3. RDD 的持久化/缓存4. RDD 容错机制 Checkpoint5. RDD 依赖关系1) 宽窄依赖2) 为什么要设计宽窄依赖 …...

linux之进程信号(初识信号,信号的产生)

目录 引入一、初识信号(信号预备知识)1.生活中的信号2.Linux中的信号3.信号进程得出的初步结论 二、信号的产生1.通过终端输入产生信号拓展: 硬件中断2.调用系统函数向进程发信号3.硬件异常产生信号4.软件条件产生信号拓展: 核心转储技术总结一下&#xff1a; 引入 一、初识信…...

基于nginx实现正向代理(linux版本)

介绍 在企业开发环境中&#xff0c;局域网内的设备通常需要通过正向代理服务器访问互联网。正向代理服务器充当中介&#xff0c;帮助客户端请求外部资源并返回结果。局域网内也就是俗称的内网&#xff0c;局域网外的互联网就是外网&#xff0c;在一些特殊场景内&#xff0c;例…...

【蓝牙】win11 笔记本电脑连接 hc-06

文章目录 前言步骤 前言 使用电脑通过蓝牙添加串口 步骤 设置 -> 蓝牙和其他设备 点击 显示更多设备 更多蓝牙设置 COM 端口 -> 添加 有可能出现卡顿&#xff0c;等待一会 传出 -> 浏览 点击添加 hc-06&#xff0c;如果没有则点击 再次搜索 确定 添加成…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...