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

量子密码的轻量级通信协议笔记

代码笔记

本文档提供了项目代码的详细说明,包括代码结构、关键算法实现和重要的代码片段。

代码结构

.
├── Makefile                # 构建系统配置
├── coap_client.c           # CoAP客户端实现
├── coap_server.c           # CoAP服务端实现
├── coap.c                  # CoAP协议基础功能实现
├── coap.h                  # CoAP协议相关定义和函数声明
├── rainbow.c               # Rainbow签名算法实现
├── rainbow.h               # Rainbow签名相关定义和函数声明
├── protocol_optimize.c     # 协议优化算法实现
├── protocol_optimize.h     # 协议优化相关定义和函数声明
├── protocol_test.c         # 协议优化性能测试
├── performance_analyzer.c  # 性能分析工具
├── visualize_performance.py # 性能数据可视化脚本
└── run_tests.sh            # 测试脚本

代码规范

项目采用C语言实现,遵循以下规范:

  1. 命名规范:

    • 函数名: 使用小写字母和下划线,如 rainbow_sign()
    • 变量名: 使用小写字母和下划线,如 message_id
    • 常量和宏: 使用大写字母和下划线,如 KYBER_PUBLICKEYBYTES
    • 结构体: 使用驼峰命名法,如 PerformanceMetrics
  2. 代码缩进:

    • 使用4个空格缩进
    • 大括号放在同一行
  3. 注释规范:

    • 函数前使用多行注释说明功能
    • 复杂逻辑处使用单行注释
    • 所有公共API都有文档注释
  4. 错误处理:

    • 所有函数返回值都进行检查
    • 使用返回值指示错误状态
    • 内存分配都检查是否成功

CoAP协议实现 (coap.c/h)

CoAP消息格式

typedef struct {uint8_t version;         // CoAP版本号(固定为1)uint8_t type;            // 消息类型(CON, NON, ACK, RST)uint8_t token_len;       // 令牌长度(0-8字节)uint8_t code;            // 响应码uint16_t message_id;     // 消息IDuint8_t token[8];        // 令牌Option *options;         // 选项链表uint8_t *payload;        // 有效负载size_t payload_len;      // 有效负载长度
} CoAPMessage;

消息类型

#define COAP_MESSAGE_CON 0   // 需要确认的消息
#define COAP_MESSAGE_NON 1   // 不需要确认的消息
#define COAP_MESSAGE_ACK 2   // 确认消息
#define COAP_MESSAGE_RST 3   // 重置消息

核心函数

消息创建和释放
// 创建新的CoAP消息
CoAPMessage *coap_message_create();// 释放CoAP消息资源
void coap_message_free(CoAPMessage *message);
消息编码和解码
// 将CoAP消息编码为二进制格式
int coap_message_encode(const CoAPMessage *message, uint8_t *buffer, size_t buffer_len);// 从二进制数据解码CoAP消息
int coap_message_decode(CoAPMessage *message, const uint8_t *buffer, size_t buffer_len);
分块传输实现

实现了简化版的CoAP分块传输机制,使用Block2选项:

// 添加Block2选项
int coap_add_block2_option(CoAPMessage *message, uint32_t num, uint8_t more, uint16_t size);// 解析Block2选项
int coap_parse_block2_option(const CoAPMessage *message, uint32_t *num, uint8_t *more, uint16_t *size);

Rainbow签名实现 (rainbow.h/c)

关键数据结构

// Rainbow密钥对结构
typedef struct {unsigned char public_key[RAINBOW_PUBLIC_KEY_BYTES];unsigned char private_key[RAINBOW_PRIVATE_KEY_BYTES];
} RainbowKeyPair;

主要函数

密钥生成
void rainbow_keygen(RainbowKeyPair *keypair) {printf("rainbow_keygen 开始\n");// 使用 rand() 生成私钥for (int i = 0; i < RAINBOW_PRIVATE_KEY_BYTES; i++) {keypair->private_key[i] = rand() % 256;}// 使用 SHA256 哈希私钥生成公钥,确保单向性unsigned char hash[SHA256_DIGEST_LENGTH];SHA256(keypair->private_key, RAINBOW_PRIVATE_KEY_BYTES, hash);for (int i = 0; i < RAINBOW_PUBLIC_KEY_BYTES; i++) {keypair->public_key[i] = hash[i % SHA256_DIGEST_LENGTH];}printf("rainbow_keygen 完成,私钥前16字节: ");for (int i = 0; i < 16; i++) printf("%02x", keypair->private_key[i]);printf("\n公钥前16字节: ");for (int i = 0; i < 16; i++) printf("%02x", keypair->public_key[i]);printf("\n");
}
签名和验证
// 签名实现
void rainbow_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *private_key) {// 计算消息哈希unsigned char hash[SHA256_DIGEST_LENGTH];SHA256(message, message_len, hash);// 生成签名 = 哈希 XOR 私钥for (int i = 0; i < RAINBOW_SIGNATURE_BYTES; i++) {signature[i] = hash[i % SHA256_DIGEST_LENGTH] ^ private_key[i % RAINBOW_PRIVATE_KEY_BYTES];}
}// 简化的验证实现(实际使用中替换为真正的验证逻辑)
int rainbow_verify(const unsigned char *message, size_t message_len, const unsigned char *signature, const unsigned char *public_key) {// 注意:这是一个简化实现,总是返回验证成功return 1;
}

协议优化实现 (protocol_optimize.c/h)

1. 报文压缩 (RLE算法)

// 应用游程长度编码(RLE)压缩
size_t apply_compression(unsigned char *input, size_t input_len, unsigned char *output, size_t output_max_len) {// 如果输入数据较小,直接使用未压缩模式if (input_len < 512) {output[0] = 0xC1;  // 未压缩标记memcpy(output + 1, input, input_len);return input_len + 1;}size_t out_pos = 1; // 保留第一个字节作为压缩模式标记size_t in_pos = 0;while (in_pos < input_len) {// 查找连续相同的字节序列unsigned char current = input[in_pos];size_t run_length = 1;while (in_pos + run_length < input_len && input[in_pos + run_length] == current && run_length < 255) {run_length++;}// 如果序列长度超过3,使用RLE编码if (run_length >= 3) {// 写入RLE标记、重复字节和重复次数output[out_pos++] = 0xFF; // RLE标记output[out_pos++] = current; // 重复字节output[out_pos++] = run_length; // 重复次数} else {// 对于短序列,直接复制for (size_t j = 0; j < run_length; j++) {output[out_pos++] = current;}}// 移动到下一个未处理的字节in_pos += run_length;}// 设置压缩模式标记output[0] = 0xC0;return out_pos;
}
解压缩实现
// 对应的解压缩算法
size_t decompress_data(unsigned char *input, size_t input_len, unsigned char *output, size_t output_max_len) {// 检查压缩标记if (input[0] == 0xC1) {// 未压缩数据,直接复制size_t copy_len = input_len - 1;if (copy_len > output_max_len) {copy_len = output_max_len;}memcpy(output, input + 1, copy_len);return copy_len;} else if (input[0] != 0xC0) {// 无效的压缩标记return 0;}// 解压缩RLE编码的数据size_t in_pos = 1;  // 跳过压缩标记size_t out_pos = 0;while (in_pos < input_len && out_pos < output_max_len) {// 检查是否是RLE编码标记if (input[in_pos] == 0xFF && in_pos + 2 < input_len) {// 读取重复字节和次数unsigned char value = input[in_pos + 1];unsigned char count = input[in_pos + 2];// 展开重复序列for (unsigned char i = 0; i < count; i++) {output[out_pos++] = value;}// 移动到下一个编码in_pos += 3;} else {// 直接复制单个字节output[out_pos++] = input[in_pos++];}}return out_pos;
}

2. 会话密钥复用

数据结构
// 会话密钥缓存结构
typedef struct {unsigned char key[64]; // 足够大以存储各种密钥size_t key_len;unsigned char associated_data[256]; // 关联数据(如IP地址、端口等)size_t ad_len;time_t creation_time;int valid;
} SessionKeyCache;#define MAX_SESSION_KEYS 10
static SessionKeyCache session_keys[MAX_SESSION_KEYS];
static int session_key_count = 0;
密钥保存与检索
// 保存会话密钥供后续使用
void save_session_key(const unsigned char *key, size_t key_len, const unsigned char *associated_data, size_t ad_len) {int index = -1;// 如果已存在相同关联数据的条目,则更新它if (associated_data && ad_len > 0) {for (int i = 0; i < session_key_count; i++) {if (session_keys[i].ad_len == ad_len && memcmp(session_keys[i].associated_data, associated_data, ad_len) == 0) {index = i;break;}}}// 如果未找到现有条目,创建一个新的或替换最老的if (index == -1) {if (session_key_count < MAX_SESSION_KEYS) {index = session_key_count++;} else {// 替换最老的会话密钥time_t oldest_time = time(NULL);int oldest_idx = 0;for (int i = 0; i < MAX_SESSION_KEYS; i++) {if (session_keys[i].creation_time < oldest_time) {oldest_time = session_keys[i].creation_time;oldest_idx = i;}}index = oldest_idx;}}// 更新会话密钥条目memcpy(session_keys[index].key, key, key_len);session_keys[index].key_len = key_len;if (associated_data && ad_len > 0) {memcpy(session_keys[index].associated_data, associated_data, ad_len);session_keys[index].ad_len = ad_len;}session_keys[index].creation_time = time(NULL);session_keys[index].valid = 1;
}// 检索之前保存的会话密钥
int retrieve_session_key(unsigned char *key, size_t key_len,const unsigned char *associated_data, size_t ad_len) {for (int i = 0; i < session_key_count; i++) {if (session_keys[i].valid && session_keys[i].ad_len == ad_len && memcmp(session_keys[i].associated_data, associated_data, ad_len) == 0) {// 检查密钥是否过期 (24小时)time_t now = time(NULL);if (now - session_keys[i].creation_time > 24 * 60 * 60) {session_keys[i].valid = 0;return 0;}// 复制密钥size_t copy_len = key_len < session_keys[i].key_len ? key_len : session_keys[i].key_len;memcpy(key, session_keys[i].key, copy_len);return 1; // 成功找到并复制密钥}}return 0; // 未找到匹配的密钥
}

3. 协议头压缩

// 应用协议头压缩
size_t apply_header_reduction(unsigned char *buffer, size_t buffer_len) {// 添加协议头压缩标记 0xA5unsigned char header_flag = 0xA5;// 检查是否是CoAP首包并需要压缩if (buffer_len >= 8 && ((buffer[0] >> 4) & 0x0F) <= 3) {// 提取和保留重要字段unsigned char type_ver = buffer[0];unsigned char code = buffer[1];unsigned short message_id = (buffer[2] << 8) | buffer[3];// 创建压缩头部unsigned char new_header[5];new_header[0] = header_flag;new_header[1] = type_ver;new_header[2] = code;new_header[3] = (message_id >> 8) & 0xFF;new_header[4] = message_id & 0xFF;// 计算选项部分起始位置size_t options_start = 4;size_t payload_marker_pos = 0;// 找到有效载荷标记0xFF的位置for (size_t i = options_start; i < buffer_len; i++) {if (buffer[i] == 0xFF) {payload_marker_pos = i;break;}}// 如果找到有效载荷标记if (payload_marker_pos > 0) {// 计算需要移动的数据大小size_t options_size = payload_marker_pos - options_start;size_t payload_size = buffer_len - payload_marker_pos - 1;// 复制压缩头部memmove(buffer, new_header, 5);// 复制选项部分(如果有)if (options_size > 0) {memmove(buffer + 5, buffer + options_start, options_size);}// 添加有效载荷标记buffer[5 + options_size] = 0xFF;// 复制有效载荷数据(如果有)if (payload_size > 0) {memmove(buffer + 5 + options_size + 1, buffer + payload_marker_pos + 1, payload_size);}// 返回新的缓冲区长度return 5 + options_size + 1 + payload_size;}}// 如果不能压缩,返回原始长度return buffer_len;
}

性能测试 (protocol_test.c)

测试数据生成

// 生成测试数据
TestData generate_test_data(size_t size) {TestData data;data.data = (unsigned char *)malloc(size);data.data_len = size;if (data.data) {// 填充一些模拟数据for (size_t i = 0; i < size; i++) {// 生成一些模式用于测试压缩效果if (i % 100 < 20) {data.data[i] = 0x00;  // 一些零字节} else if (i % 100 < 40) {data.data[i] = 0xFF;  // 一些FF字节} else if (i % 100 < 60) {data.data[i] = i & 0xFF;  // 递增模式} else if (i % 100 < 80) {data.data[i] = 'A' + (i % 26);  // 文本模式} else {data.data[i] = rand() & 0xFF;  // 随机数据}}}return data;
}

性能计时器

// 启动计时器
void start_timer(struct timespec *timer) {if (!timer) return;clock_gettime(CLOCK_MONOTONIC, timer);
}// 停止计时器并返回经过的毫秒数
double stop_timer(struct timespec *timer) {if (!timer) return 0.0;struct timespec end;clock_gettime(CLOCK_MONOTONIC, &end);double milliseconds = (end.tv_sec - timer->tv_sec) * 1000.0;milliseconds += (end.tv_nsec - timer->tv_nsec) / 1000000.0;return milliseconds;
}

客户端和服务端实现

客户端通信流程

// 简化的客户端通信逻辑
int main() {// 1. 初始化(创建套接字、绑定端口等)int sock = socket(AF_INET, SOCK_DGRAM, 0);// 2. 生成密钥对(Kyber和Rainbow)crypto_kem_keypair(client_pk, client_sk);rainbow_keygen(&rainbow_keypair);// 3. 发送公钥到服务端CoAPMessage *request = coap_message_create();// ... 设置请求参数coap_send_request(sock, request, server_addr);// 4. 接收服务端的公钥和密文CoAPMessage *response = coap_receive_response(sock);// 5. 解密共享密钥crypto_kem_dec(shared_secret, server_ciphertext, client_sk);// 6. 验证服务端签名rainbow_verify(server_message, message_len, server_signature, server_rainbow_pk);// 7. 使用共享密钥进行后续通信// ...return 0;
}

服务端通信流程

// 简化的服务端通信逻辑
int main() {// 1. 初始化(创建套接字、绑定端口等)int sock = socket(AF_INET, SOCK_DGRAM, 0);bind(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));// 2. 生成密钥对(Kyber和Rainbow)crypto_kem_keypair(server_pk, server_sk);rainbow_keygen(&rainbow_keypair);// 3. 等待客户端连接并接收公钥CoAPMessage *request = coap_receive_request(sock);// 4. 使用客户端公钥加密共享密钥crypto_kem_enc(ciphertext, shared_secret, client_pk);// 5. 对消息进行签名rainbow_sign(signature, message, message_len, rainbow_keypair.private_key);// 6. 发送服务端公钥、密文和签名CoAPMessage *response = coap_message_create();// ... 设置响应参数coap_send_response(sock, response, client_addr);// 7. 使用共享密钥进行后续通信// ...return 0;
}

优化算法复杂度分析

1. 报文压缩算法 (RLE)

  • 时间复杂度: O(n),其中n是输入数据的长度
  • 空间复杂度: O(n),最坏情况下压缩后数据与原始数据大小相当
  • 最佳场景: 数据中包含大量连续重复字节

2. 会话密钥复用

  • 时间复杂度:
    • 保存: O(k),其中k是最大存储的密钥数量
    • 检索: O(k),需要线性搜索所有密钥
  • 空间复杂度: O(k),存储k个密钥及其元数据
  • 优化点: 可以使用哈希表提高检索效率至O(1)

3. 协议头压缩

  • 时间复杂度: O(n),其中n是消息长度
  • 空间复杂度: O(1),使用固定额外空间
  • 节省空间: 通常在小数据包中节省1-5字节

安全考虑

密钥管理

  • 当前实现中,密钥直接存储在内存中,生产环境应考虑:
    • 安全的密钥存储(如TPM, HSM)
    • 密钥分发机制
    • 密钥轮换策略

简化实现的限制

  • Rainbow签名实现是简化版本,不提供真正的安全保证
  • 会话密钥目前只有简单的时间失效机制
  • 没有防止重放攻击的机制

增强安全性的建议

  1. 替换Rainbow为标准化的后量子签名算法
  2. 添加随机数和时间戳防止重放攻击
  3. 实现完整的TLS/DTLS安全层
  4. 加入密钥衍生函数(KDF)和安全的随机数生成器

调试技巧

输出调试信息

在关键函数中添加如下代码以启用调试输出:

#ifdef DEBUG_LOGGING
#define DEBUG_LOG(fmt, ...) printf("[DEBUG] " fmt "\n", ##__VA_ARGS__)
#else
#define DEBUG_LOG(fmt, ...)
#endif// 使用示例
DEBUG_LOG("Processing message ID: %d", message_id);

内存调试

使用Valgrind检查内存泄漏:

valgrind --leak-check=full --show-leak-kinds=all ./coap_server

网络调试

使用tcpdump或Wireshark捕获CoAP数据包:

sudo tcpdump -i lo udp port 5683 -vvv -X

相关文章:

量子密码的轻量级通信协议笔记

代码笔记 本文档提供了项目代码的详细说明&#xff0c;包括代码结构、关键算法实现和重要的代码片段。 代码结构 . ├── Makefile # 构建系统配置 ├── coap_client.c # CoAP客户端实现 ├── coap_server.c # CoAP服务端实现 ├─…...

探索 C++ 在行业应用与技术融合中的核心价值

引言 在科技飞速发展的今天&#xff0c;C 作为一门兼具高性能与灵活性的编程语言&#xff0c;正深度融入游戏开发、人工智能、区块链等多个关键领域。其高效的内存管理、底层控制能力以及对现代硬件架构的深度优化&#xff0c;使其成为复杂系统开发的首选语言。本文将深入探讨…...

雷赛伺服电机

ACM0经济 编码器17位&#xff1a; ACM1基本 编码器23位磁编&#xff0c; ACM2通用 编码器24位光电&#xff0c; 插头定义&#xff1a;...

word文档基本操作: 编辑页眉页脚和插入目录

文章目录 引言I 编辑页眉页脚II 插入目录III 知识扩展基于axure画架构图基于Knife4j导出接口文档基于PDManer导出数据库设计文档引言 背景: 信息安全认证需要准备相关文件用于审核 一般的开发设计包含总体设计、概要设计、详细设计、接口设计、数据库设计、部署结构设计、原型…...

数据结构(二)——线性表的链式表示和实现

一、单链表 1.单链表的定义 如图所示每个节点包含两个域:数据域和指针域。数据域存储数据元素&#xff0c;指针域存储下一个节点的地址&#xff0c;因此指针指向的类型也是节点类型。每个指针都指向下一个节点&#xff0c;都是朝一个方向的&#xff0c;这样的链表称为单向链表…...

HTML10:iframe内联框架

iframe内部框架 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>内联框架学习</title> </head> <body> <!--iframe内联框架 src:地址 width-height:高度宽度 --> <iframe…...

C++代码随想录刷题知识分享-----数组交集—LeetCode 349

1  题目描述 给定两个整型数组 nums1 和 nums2&#xff0c;请返回它们的交集。 交集中 每个元素必须是唯一的。输出结果的顺序可以任意。 示例输入输出说明1nums1 [1,2,2,1], nums2 [2,2][2]2 只出现一次2nums1 [4,9,5], nums2 [9,4,9,8,4][4,9] 或 [9,4]顺序不作要求…...

Wireshark基本使用

本文会对Wireshark做简单介绍&#xff0c;带大家熟悉一下Wireshark的界面&#xff0c;以及如何使用过滤器。 接着会带大家查看TCP五层模型下&#xff0c;带大家回顾各层首部的格式。 最后会演示 Wireshark 如何抓取三次握手和四次挥手包的过程。 目录 一.Wireshark简介 二…...

学习c语言的链表的概念、操作(另一篇链表的笔记在其他的栏目先看这个)

在学习Linux之间我们先插入一下链表的知识 学习链表&#xff08;一种数据结构思想&#xff09; 链表和数组的区别和实现&#xff1a; 链表&#xff08;链表是个好东西&#xff09; 链表概念&#xff08;什么是链表&#xff09;&#xff1f; 链表就是数据结构->数据的存储…...

快速上手Pytorch Lighting框架 | 深度学习入门

快速上手Pytorch Lighting框架 | 深度学习入门 前言参考官方文档 介绍快速上手基本流程常用接口LightningModule\_\_init\_\_ & setup()\*\_step()configure_callbacks()configure_optimizers()load_from_checkpoint Trainer常用参数 可选接口LoggersTensorBoard Logger Ca…...

ffmpeg多媒体(音视频)处理常用命令

概览 总结一些音视频常用的ffmpeg处理命令&#xff0c;会不断更新&#xff0c;涉及一些重要命令&#xff0c;各位读者也可在评论区不断更新&#xff0c;维护起来&#xff0c;希望可以帮助大家快速解决问题&#xff01; 1、音频相关 1.1 音频信息查看 ffmpeg -i test.wav 该命…...

QT中的网络请求

一、主程序&#xff08;main.cpp&#xff09; #include <QCoreApplication> #include <QNetworkAccessManager> #include <QNetworkReply> #include <QNetworkRequest> #include <QUrlQuery> #include <QJsonDocument> #include <QJso…...

Nacos源码—6.Nacos升级gRPC分析二

大纲 1.Nacos 2.x版本的一些变化 2.客户端升级gRPC发起服务注册 3.服务端进行服务注册时的处理 4.客户端服务发现和服务端处理服务订阅的源码分析 4.客户端服务发现和服务端处理服务订阅的源码分析 (1)Nacos客户端进行服务发现的源码 (2)Nacos服务端处理服务订阅请求的源…...

如何选择自己喜欢的cms

选择内容管理系统cms what is cms1.whatcms.org2.IsItWP.com4.Wappalyzer5.https://builtwith.com/6.https://w3techs.com/7. https://www.netcraft.com/8.onewebtool.com如何在不使用 CMS 检测器的情况下手动检测 CMS 结论 在开始构建自己的数字足迹之前&#xff0c;大多数人会…...

前端面经 作用域和作用域链

含义&#xff1a;JS中变量生效的区域 分类&#xff1a;全局作用域 或者 局部作用域 局部作用域&#xff1a;函数作用域 和 块级作用域ES6 全局作用域:在代码中任何地方都生效 函数中定义函数中生效&#xff0c;函数结束失效 块级作用域 使用let或const 声明 作用域链:JS查…...

开启智能Kubernetes管理新时代:kubectl-ai让操作更简单!

在如今的科技世界中,Kubernetes 已经成为容器编排领域的标杆,几乎所有现代应用的基础设施都离不开它。然而,面对复杂的集群管理和日常运维,许多开发者常常感到无所适从。今天,我们将为大家介绍一款结合了人工智能的强大工具——kubectl-ai。它不仅能帮助开发者更加顺畅地与…...

STM32 ADC

目录 ADC简介 逐次逼近型ADC STM32 ADC框图 输入通道 转换模式 •单次转换&#xff0c;非扫描模式 •连续转换&#xff0c;非扫描模式 •单次转换&#xff0c;扫描模式 •连续转换&#xff0c;扫描模式 触发控制 数据对齐 转换时间 校准 硬件电路 A…...

nextjs站点地图sitemap添加

app/sitemap.xml/route.ts (主站点地图索引) sitemap.xml 为文件夹名称 route.ts代码如下&#xff1a; import { NextResponse } from next/server; import { url } from /config/navigation; export async function GET() {// const entries generateMonthlyEntries();con…...

TCP/IP和OSI对比

​TCP/IP模型的实际特性 ​网络层&#xff08;IP层&#xff09;​ ​仅提供无连接的不可靠服务&#xff1a;TCP/IP模型的网络层核心协议是IP&#xff08;Internet Protocol&#xff09;&#xff0c;其设计是无连接且不可靠的。IP数据包独立传输&#xff0c;不保证顺序、不确认交…...

【hadoop】Hbase java api 案例

代码实现&#xff1a; HBaseConnection.java package com.peizheng.bigdata;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client…...

深入理解Spring缓存注解:@Cacheable与@CacheEvict

在现代应用程序开发中&#xff0c;缓存是提升系统性能的重要手段。Spring框架提供了一套简洁而强大的缓存抽象&#xff0c;其中Cacheable和CacheEvict是两个最常用的注解。本文将深入探讨这两个注解的工作原理、使用场景以及最佳实践。 1. Cacheable注解 基本概念 Cacheable…...

[git]如何关联本地分支和远程分支

主题 本文总结如何关联git本地分支和远程分支的相关知识点。 详情 查看本地分支 git branch 查看远程分支 git branch -r 查看所有分支(本地远程) git branch -a 查看本地分支及其关联的远程分支(如有) git branch -vv 关联本地分支到远程分支&#xff1a; git branch …...

Linux58 ssh服务配置 jumpserver 测试双网卡 为何不能ping通ip地址

判断为NAT模式网卡 能ping 通外网 ens34为仅主机模式网卡 [rootlocalhost network-scripts]# ip route show default default via 10.1.1.254 dev ens33 proto static metric 100 10.0.0.0/8 dev ens33 proto kernel scope link src 10.1.1.37 metric 100 11.0.0.0/8 dev…...

chart.js 柱状图Y轴数据设置起始值

事情的起因&#xff0c; 我以为是&#xff1a; chart.js 柱状图Y轴数据显示不全&#xff0c; 因为数据是浮点数&#xff0c; 换了整数测试还不行&#xff0c; 多次更换数据&#xff0c; 数据显示不全仍然存在&#xff0c; 而且是不固定位置的不显示。 直到相同数据换了折…...

算法题(142):木材加工

审题&#xff1a; 本题需要我们找到可以将木头切割至少k段的单段长度最长值 思路&#xff1a; 方法一&#xff1a;暴力解法 首先我们知道单段长度的最长值就是数组中数据的最大值max&#xff0c;所以我们可以遍历1~max的数据&#xff0c;将他们确定为l&#xff0c;然后计算出当…...

嵌入式学习--江协51单片机day3

今天学的东西挺多的&#xff0c;包括&#xff1a;自己设计的小应用&#xff0c;矩阵键盘&#xff0c;矩阵键盘密码锁&#xff0c;控制按键led流水灯&#xff0c;定时器时钟 &#xff08;那个视频真的煎熬&#xff0c;连续两个1小时的简直要命&#xff0c;那个时钟也是听的似懂…...

Linux命令行参数注入详解

本文主要聚焦 Linux 系统及其 ELF 二进制文件&#xff0c;深入探讨参数注入的原理与防范措施。 核心术语解析 在进入主题之前&#xff0c;我们先厘清几个关键术语&#xff0c;以确保理解的准确性&#xff1a; 参数解析器 当程序被调用时&#xff0c;操作系统会向程序的 main…...

【HCIP】----OSPF综合实验

实验题目 实验需求&#xff1a; 1&#xff0c;R5为ISP&#xff0c;其上只能配置IP地址&#xff1b;R4作为企业边界路由器&#xff0c; 出口公网地址需要通过PPP协议获取&#xff0c;并进行chap认证 2&#xff0c;整个OSPF环境IP基于172.16.0.0/16划分&#xff1b; 3&#xff0…...

C++模板笔记

Cpp模板笔记 文章目录 Cpp模板笔记1. 为什么要定义模板2. 模板的定义2.1 函数模板2.1.1 函数模板的重载2.1.2 头文件与实现文件形式&#xff08;重要&#xff09;2.1.3 模板的特化2.1.4 模板的参数类型2.1.5 成员函数模板2.1.6 使用模板的规则 2.2 类模板2.3 可变参数模板 模板…...

二极管的动态特性

主要内容 二极管的单向导电特性并不十分理想&#xff0c;这是因为二极管的本质是有P型半导体和N型半导体接触形成的PN结。 PN结除了除了构成单向到点的二极管外&#xff0c;还存在一个结电容&#xff0c;这个结电容会导致"双向"导电。 也就是说&#xff0c;这会让二…...

WSL(Windows Subsystem for Linux)入门

目录 1.简介2.安装与配置3.常用命令4.进阶使用4.1 文件系统交互4.2 网络互通4.3 配置代理4.4 运行 GUI 程序4.5 Docker 集成 1.简介 WSL 是 Windows 系统内置的 Linux 兼容层&#xff0c;允许直接在 Windows 中运行 Linux 命令行工具和应用程序&#xff0c;无需虚拟机或双系统…...

k8s术语之secret

在kubernetes中&#xff0c;还存在一种和ConfigMap非常类似的对象&#xff0c;称之为Secret对象。它主要用于存储敏感信息&#xff0c;例如密码、密钥、证书等等。 首先使用base64对数据进行编码 rootmaster pvs ]# echo -n admin | base64 YWRtaW4 实例&#xff1a;隐藏mysql密…...

Vue2 中 el-dialog 封装组件属性不生效的深度解析(附 $attrs、inheritAttrs 原理)

Vue2 中 el-dialog 封装组件属性不生效的深度解析&#xff08;附 $attrs、inheritAttrs 原理&#xff09; 在使用 Vue2 和 Element UI 进行组件封装时&#xff0c;我们常会遇到父组件传入的属性不生效的情况&#xff0c;比如在封装的 el-dialog 组件中传入 width"100%&qu…...

使用Compose编排工具搭建Ghost博客系统

序&#xff1a;需要提前自备一台部署好docker环境的虚拟机&#xff0c;了解并熟练compose编排工具 在Centos7中&#xff0c;在线/离线安装Docker&#xff1a;https://blog.csdn.net/2301_82085712/article/details/147140694 Docker编排工具---Compose的概述及使用&#xff1…...

车载网络TOP20核心概念科普

一、基础协议与总线技术 CAN总线 定义&#xff1a;控制器局域网&#xff0c;采用差分信号传输&#xff0c;速率最高1Mbps&#xff0c;适用于实时控制&#xff08;如动力系统&#xff09;。形象比喻&#xff1a;如同“神经系统”&#xff0c;负责传递关键控制信号。 LIN总线 定…...

机器学习第一讲:机器学习本质:让机器通过数据自动寻找规律

机器学习第一讲&#xff1a;机器学习本质&#xff1a;让机器通过数据自动寻找规律 资料取自《零基础学机器学习》。 查看总目录&#xff1a;学习大纲 一、从婴儿学说话说起 &#x1f476; 想象你教1岁宝宝认「狗」&#xff1a; 第一阶段&#xff1a;指着不同形态的狗&#x…...

Android ImageView 加载 Base64编码图片

在 Android 中显示服务端返回的 Base64 编码的 GIF 图片&#xff08;如 data:image/gif;base64,...&#xff09;&#xff0c;需要以下步骤&#xff1a; 首先从字符串中分离出纯 Base64 部分&#xff08;去掉 data:image/gif;base64, 前缀&#xff09;image/gif 表示图片是 gif…...

如何使用 QuickAPI 推动医院数据共享 —— 基于数据仓库场景的实践

目录 01 医疗行业面临的数据孤岛问题 02 QuickAPI&#xff1a;将 SQL 变为数据 API 的利器 03 快速落地的应用实践 ✅ 步骤一&#xff1a;统一 SQL 逻辑&#xff0c;模块化管理 ✅ 步骤二&#xff1a;配置权限与调用策略 ✅ 步骤三&#xff1a;上线并接入调用 04 核心收…...

【5G通信】bwp和redcap 随手记 2

好的&#xff0c;让我们重新解释Cell-Defined BWP (CD BWP) 和 Non-Cell-Defined BWP (NCD BWP)&#xff0c;并结合RedCap终端和非RedCap终端的应用进行说明。 一、定义 Cell-Defined BWP (CD BWP) 定义&#xff1a;由网络&#xff08;基站&#xff09;通过RRC信令为终端配置的…...

AI时代企业应用系统架构的新思路与CIO变革指南

作为制造企业CIO&#xff0c;我们看问题需要有前瞻性&#xff0c;AI时代企业应用系统架构需要进行全面转型。 一、新思想与新技术 1. 核心新思想 可视化开发AI的融合模式&#xff1a;不再只依赖纯代码开发或传统低代码&#xff0c;而是两者结合&#xff0c;通过AI理解自然语…...

kotlin JvmName注解的作用和用途

1. JvmName 注解的作用 JvmName 是 Kotlin 提供的一个注解&#xff0c;用于在编译为 Java 字节码时自定义生成的类名或方法名。 作用对象&#xff1a; 文件级别&#xff08;整个 .kt 文件&#xff09;函数、属性、类等成员 主要用途&#xff1a; 控制 Kotlin 编译后生成的 JV…...

为什么强调 RESTful 的无状态性?-优雅草卓伊凡

为什么强调 RESTful 的无状态性&#xff1f;-优雅草卓伊凡 RESTful 架构的核心原则之一是 无状态性&#xff08;Statelessness&#xff09;&#xff0c;它要求 每次客户端请求必须包含服务器处理该请求所需的所有信息&#xff0c;服务器不会存储客户端的状态&#xff08;如会话…...

信息系统项目管理工程师备考计算类真题讲解十五

一、决策论问题 分析&#xff1a;首先要明白几个概念&#xff1a; 1&#xff09;最大最大准则&#xff08;Maxmax&#xff09;:也称乐观主义准则&#xff0c;其决策原则为“大中取大” 2&#xff09;最大最小准则&#xff08;Maxmin&#xff09;:也称悲观主义准则&#xff0c…...

android-ndk开发(9): undefined reference to `__aarch64_ldadd4_acq_rel` 报错分析

1. 概要 基础库 libbase.a 基于 android ndk r18b 编译&#xff0c; 被算法库 libfoo.so 和算法库 libbar.a 依赖&#xff0c; 算法库则分别被 libapp1.so 和 libapp2.so 依赖。 libapp1.so 的开发者向 libfoo.so 的开发者反馈了链接报错&#xff1a; error: undefined symb…...

Java 对象克隆(Object Cloning)详解

Java 对象克隆(Object Cloning)详解 对象克隆是指创建一个对象的精确副本,Java 提供了两种克隆方式:浅克隆(Shallow Clone)和深克隆(Deep Clone)。下面从实现原理、使用场景到注意事项全面解析。 一、克隆的基本概念 1. 为什么要克隆? 需要对象副本时避免修改原始对…...

Asp.Net Core IIS发布后PUT、DELETE请求错误405

一、方案1 1、IIS管理器&#xff0c;处理程序映射。 2、找到aspNetCore&#xff0c;双击。点击请求限制...按钮&#xff0c;并在谓词选项卡上&#xff0c;添加两者DELETE和PUT. 二、方案2 打开web.config文件&#xff0c;添加<remove name"WebDAVModule" />&…...

AI搜索的未来:技术纵深发展与关键突破路径

一、模型架构的颠覆性重构 ‌1、混合专家系统&#xff08;MoE&#xff09;的工程化突破‌ ‌动态路径选择‌&#xff1a;Google Gemini 1.5 Pro采用MoE架构&#xff0c;其门控网络(Gating Network)通过实时计算输入token与128个专家模型的余弦相似度&#xff0c;动态分配计算资…...

从艾米・阿尔文看 CTO 的多面特质与成长路径

在《对话 CTO&#xff0c;驾驭高科技浪潮》的开篇&#xff0c;艾米・阿尔文的经历如同一扇窗&#xff0c;为我们展现出首席技术官丰富而立体的世界。通过深入探究这一章节&#xff0c;我们能洞察 CTO 在技术领域前行所需的特质、面临的挑战&#xff0c;以及成长发展的脉络。 一…...

记录阿里云服务器搭建FTP服务器的注意事项

在阿里云服务器上&#xff08;centos&#xff09;系统&#xff0c;使用vsftpd搭建了一台FTP服务器。 搭建过程中&#xff0c;也留意到了操作防火墙放行端口。但搭建成功后&#xff0c;仍无法访问。 问题是&#xff1a;还需要在阿里云控制台设置一下。 在此记录。 1、登陆账…...

第二章 Logback的架构(三)

Logger, Appenders 和 Layouts 工作原理概述 在介绍了基本的Logback组件之后&#xff0c;我们现在可以描述当用户调用Logger的打印方法时&#xff0c;Logback框架日志请求的执行步骤。 现在让我们分析一下当用户调用名为com.wombat的Logger的info()方法时&#xff0c;Logback…...