微信 MMTLS 协议详解(五):加密实现
常用的解密算法,对称非对称 加密,密钥协商, 带消息认证的加解密
#生成RSA 密钥对
void GenerateRsaKeypair(std::string& public_key,std::string& private_key)
{RSA* rsa = RSA_new();BIGNUM* bn = BN_new();// 生成 RSA 密钥对BN_set_word(bn, RSA_F4);RSA_generate_key_ex(rsa, 2048, bn, nullptr);// 创建内存 BIO 用于存储密钥BIO* bio_private = BIO_new(BIO_s_mem());BIO* bio_public = BIO_new(BIO_s_mem());// 将私钥写入 BIO(PKCS#8 格式)PEM_write_bio_RSAPrivateKey(bio_private, rsa, nullptr, nullptr, 0, nullptr,nullptr);// 将公钥写入 BIO(X.509 格式)PEM_write_bio_RSAPublicKey(bio_public, rsa);// 从 BIO 提取字符串char* priv_data = nullptr;char* pub_data = nullptr;long priv_len = BIO_get_mem_data(bio_private, &priv_data);long pub_len = BIO_get_mem_data(bio_public, &pub_data);private_key = std::string(priv_data, priv_len);public_key = std::string(pub_data, pub_len);// 释放资源BIO_free_all(bio_private);BIO_free_all(bio_public);RSA_free(rsa);BN_free(bn);
}
RSA 公钥加密
// 公钥加密
std::string EncryptWithPublic(const std::string& plaintext,const std::string& public_key) {BIO* bio = BIO_new_mem_buf(public_key.c_str(), -1);RSA* rsa = PEM_read_bio_RSAPublicKey(bio, nullptr, nullptr, nullptr);BIO_free_all(bio);if (!rsa) {return "";}int rsa_size = RSA_size(rsa);int max_plaintext_len =rsa_size - 42; // RSA_PKCS1_OAEP_PADDING 填充后最大明文长度std::string encrypted_str;for (size_t i = 0; i < plaintext.length(); i += max_plaintext_len) {size_t len =std::min(max_plaintext_len, static_cast<int>(plaintext.length() - i));unsigned char* encrypted = new unsigned char[rsa_size];int result = RSA_public_encrypt(len, reinterpret_cast<const unsigned char*>(plaintext.c_str() + i),encrypted, rsa, RSA_PKCS1_OAEP_PADDING);if (result == -1) {RSA_free(rsa);delete[] encrypted;return "";}encrypted_str.append(reinterpret_cast<char*>(encrypted), result);delete[] encrypted;}RSA_free(rsa);return encrypted_str;
}
RSA 私钥解密
// 私钥解密
std::string DecryptWithPrivate(const std::string& ciphertext,const std::string& private_key) {BIO* bio = BIO_new_mem_buf(private_key.c_str(), -1);RSA* rsa = PEM_read_bio_RSAPrivateKey(bio, nullptr, nullptr, nullptr);BIO_free_all(bio);if (!rsa) {return "";}int rsa_size = RSA_size(rsa);std::string decrypted_str;for (size_t i = 0; i < ciphertext.length(); i += rsa_size) {unsigned char* decrypted = new unsigned char[rsa_size];int result = RSA_private_decrypt(rsa_size,reinterpret_cast<const unsigned char*>(ciphertext.c_str() + i),decrypted, rsa, RSA_PKCS1_OAEP_PADDING);if (result == -1) {RSA_free(rsa);delete[] decrypted;return "";}decrypted_str.append(reinterpret_cast<char*>(decrypted), result);delete[] decrypted;}RSA_free(rsa);return decrypted_str;
}
生成ECDH 密钥对
#include <openssl/digest.h>
#include <openssl/ecdh.h>
#include <openssl/ec_key.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/sha.h>
#include <openssl/cipher.h>
#include <openssl/bio.h>
#include <openssl/md5.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
bool GenECDHKeypair(int nid,std::string& public_key,std::string& private_key) {bool ret = false;EC_KEY* ec_key = nullptr;unsigned char* pub_key_buf = nullptr;unsigned char* pri_key_buf = nullptr;do {ec_key = EC_KEY_new_by_curve_name(nid);if (!ec_key) {break;}EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE);ret = EC_KEY_generate_key(ec_key);if (ret != 1) {break;}int pub_key_size = i2o_ECPublicKey(ec_key, &pub_key_buf);if (pub_key_size == 0 || !pub_key_buf) {break;}int pri_key_size = i2d_ECPrivateKey(ec_key, &pri_key_buf);if (pri_key_size == 0 || !pri_key_buf) {break;}public_key.assign((const char*)pub_key_buf, pub_key_size);private_key.assign((const char*)pri_key_buf, pri_key_size);ret = true;} while (false);if (ec_key) {EC_KEY_free(ec_key);}if (pub_key_buf) {OPENSSL_free(pub_key_buf);}if (pri_key_buf) {OPENSSL_free(pri_key_buf);}return ret;
}
生成ECDSA 密钥对
bool GenECDSAKeypair(int nid,std::string& public_key,std::string& private_key) {bool result = false;EC_KEY* ec_key = nullptr;BIO* bio = nullptr;do {ec_key = EC_KEY_new_by_curve_name(nid);if (!ec_key) {break;}EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE);int ret = EC_KEY_generate_key(ec_key);if (ret != 1) {break;}ret = EC_KEY_check_key(ec_key);if (ret != 1) {break;}bio = BIO_new(BIO_s_mem());ret = PEM_write_bio_EC_PUBKEY(bio, ec_key);if (ret != 1 || BIO_flush(bio) != 1) {break;}char* ptr = nullptr;long size = BIO_get_mem_data(bio, &ptr);public_key.assign(ptr, size);BIO_free(bio);bio = BIO_new(BIO_s_mem());ret = PEM_write_bio_ECPrivateKey(bio, ec_key, nullptr, nullptr, 0, nullptr,nullptr);if (ret != 1 || BIO_flush(bio) != 1) {break;}ptr = nullptr;size = BIO_get_mem_data(bio, &ptr);private_key.assign(ptr, size);result = true;} while (false);if (nullptr != bio) {BIO_free(bio);}if (nullptr != ec_key) {EC_KEY_free(ec_key);}return result;
}
生成RSA 密钥对
bool GenRsaKeypair(std::string& public_key, std::string& private_key)
{// 产生RSA密钥RSA* rsa = RSA_new();BIGNUM* bn = BN_new();BN_set_word(bn, RSA_F4);RSA_generate_key_ex(rsa, 1024, bn, NULL);// 提取私钥BIO* bio_private = BIO_new(BIO_s_mem());PEM_write_bio_RSAPrivateKey(bio_private, rsa, NULL, NULL, 0, NULL, NULL);int private_key_len = BIO_pending(bio_private);char* pem_private_key = (char*)calloc(private_key_len + 1, 1);BIO_read(bio_private, pem_private_key, private_key_len);private_key.assign(pem_private_key, private_key_len);free(pem_private_key);BIO_free(bio_private);// 提取公钥BIO* bio_public = BIO_new(BIO_s_mem());PEM_write_bio_RSA_PUBKEY(bio_public, rsa);int public_key_len = BIO_pending(bio_public);char* pem_public_key = (char*)calloc(public_key_len + 1, 1);BIO_read(bio_public, pem_public_key, public_key_len);public_key.assign(pem_public_key, public_key_len);free(pem_public_key);BIO_free(bio_public);// 释放资源RSA_free(rsa);BN_free(bn);return true;
}
SHA256 ECDH 密钥协商
inline void* Sha256(const void* in,size_t in_len,void* out,size_t* out_len) {*out_len = SHA256_DIGEST_LENGTH;return SHA256((const uint8_t*)in, in_len, (uint8_t*)out);
}bool SHA256ECDH(int nid,const std::string& public_key,const std::string& private_key,std::string& result) {bool ret = false;EC_KEY* pub_ec_key = nullptr;EC_KEY* pri_ec_key = nullptr;do {pub_ec_key = EC_KEY_new_by_curve_name(nid);if (!pub_ec_key) {break;}auto uint8_pubkey = (const uint8_t*)public_key.data();pub_ec_key = o2i_ECPublicKey(&pub_ec_key, &uint8_pubkey, public_key.size());if (!pub_ec_key) {break;}pri_ec_key = EC_KEY_new_by_curve_name(nid);if (!pri_ec_key) {break;}auto uint8_privkey = (const uint8_t*)private_key.data();pri_ec_key = d2i_ECPrivateKey(&pri_ec_key, &uint8_privkey, private_key.size());if (!pri_ec_key) {break;}result.resize(SHA256_DIGEST_LENGTH);ECDH_compute_key(result.data(), SHA256_DIGEST_LENGTH,EC_KEY_get0_public_key(pub_ec_key), pri_ec_key, Sha256);ret = true;} while (false);// free memoryif (pub_ec_key) {EC_KEY_free(pub_ec_key);}if (pri_ec_key) {EC_KEY_free(pri_ec_key);}return ret;
}
MD5 ECDH 密钥协商
inline void* MD5(const void* in,size_t in_len,void* out,size_t* out_len) {*out_len = MD5_DIGEST_LENGTH;MD5_CTX ctx;MD5_Init(&ctx);MD5_Update(&ctx, in, in_len);MD5_Final((uint8_t*)out, &ctx);return out;
}bool MD5ECDH(int nid,const std::string& public_key,const std::string& private_key,std::string& result) {bool ret = false;EC_KEY* pub_ec_key = nullptr;EC_KEY* pri_ec_key = nullptr;do {pub_ec_key = EC_KEY_new_by_curve_name(nid);if (!pub_ec_key) {break;}auto uint8_pubkey = (const uint8_t*)public_key.data();pub_ec_key = o2i_ECPublicKey(&pub_ec_key, &uint8_pubkey, public_key.size());if (!pub_ec_key) {break;}pri_ec_key = EC_KEY_new_by_curve_name(nid);if (!pri_ec_key) {break;}auto uint8_privkey = (const uint8_t*)private_key.data();pri_ec_key = d2i_ECPrivateKey(&pri_ec_key, &uint8_privkey, private_key.size());if (!pri_ec_key) {break;}result.resize(MD5_DIGEST_LENGTH);ECDH_compute_key(result.data(), MD5_DIGEST_LENGTH,EC_KEY_get0_public_key(pub_ec_key), pri_ec_key, MD5); ret = true;} while (false);// free memoryif (pub_ec_key) {EC_KEY_free(pub_ec_key);}if (pri_ec_key) {EC_KEY_free(pri_ec_key);}return ret;
}
AES256GCM 加密
std::string Aes256GcmEncrypt(const void* once,int32_t once_len,const void* key,int32_t key_len,const void* aad,int32_t aad_len,const void* data,int32_t data_len,int tag_size,std::string& tag) {std::string result;EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();EVP_CIPHER_CTX_init(ctx);EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr);do {// set iv sizeint ret =EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, once_len, nullptr);if (ret != 1) {break;}ret = EVP_EncryptInit_ex(ctx, nullptr, nullptr, (const uint8_t*)key,(const uint8_t*)once);if (ret != 1) {break;}int out_len = 0;if (aad_len != 0) {ret = EVP_EncryptUpdate(ctx, nullptr, &out_len,(const uint8_t*)aad, aad_len);if (ret != 1) {break;}}result.resize(EVP_CIPHER_CTX_block_size(ctx) + data_len);int encrypt_len = 0;if (data_len != 0) {ret = EVP_EncryptUpdate(ctx, (uint8_t*)result.data(), &out_len,(const uint8_t*)data, data_len);if (ret != 1) {break;}encrypt_len = out_len;}ret = EVP_EncryptFinal_ex(ctx, (uint8_t*)result.data() + encrypt_len,&out_len);if (ret != 1) {break;}encrypt_len += out_len;result.resize(encrypt_len);if (tag_size != 0) {tag.resize(tag_size);ret =EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, tag_size, tag.data());if (ret != 1) {break;}}} while (false);EVP_CIPHER_CTX_free(ctx);return result;
}
AES256 GCM 解密
std::string AesGcmDecrypt(const void* once,int32_t once_len,const void* key,int32_t key_len,const void* aad,int32_t aad_len,const void* tag,int32_t tag_len,const void* data,int32_t data_len) {std::string result;EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();EVP_CIPHER_CTX_init(ctx);EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr);do {int ret =EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, once_len, nullptr);if (ret != 1) {break;}ret = EVP_DecryptInit_ex(ctx, nullptr, nullptr, (const uint8_t*)key,(const uint8_t*)once);if (ret != 1) {break;}int out_len = 0;// set aadif (aad_len != 0) {ret = EVP_DecryptUpdate(ctx, nullptr, &out_len,(const uint8_t*)aad, aad_len);if (ret != 1) {break;}}result.resize(EVP_CIPHER_CTX_block_size(ctx) + data_len);int decrypt_len = 0;if (data_len != 0) {ret = EVP_DecryptUpdate(ctx, (uint8_t*)result.data(), &out_len,(const uint8_t*)data, data_len);if (ret != 1) {break;}decrypt_len = out_len;}ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag_len,(void*)tag);if (ret == 1) {ret = EVP_DecryptFinal_ex(ctx, (uint8_t*)result.data() + decrypt_len,&out_len);if (ret == 1) {decrypt_len += out_len;result.resize(decrypt_len);} else {result.clear();}} else {result.clear();}} while (false);EVP_CIPHER_CTX_free(ctx);return result;
}
AES 加密
std::string AESEncrypt(const std::string& key,const void* data,int32_t data_len) {if ( 0 == data_len){return "";}// 计算paddingint padding = 16 - data_len % 16;std::string padding_data(data_len + padding, (char)padding);memcpy(padding_data.data(), data, data_len);uint8_t tmp_key[16] = {};uint8_t* ptmp_key = nullptr;if (key.length() == 16) {ptmp_key = (uint8_t*)key.data();}else {ptmp_key = tmp_key;memcpy(tmp_key, key.data(), key.length() > 16 ? 16 : key.length());}uint8_t iv[16] = {};memcpy(iv, ptmp_key, 16);std::string result(padding_data.size(), 0);AES_KEY aes_key;AES_set_encrypt_key(ptmp_key, 128, &aes_key);AES_cbc_encrypt((uint8_t*)padding_data.data(), (uint8_t*)result.data(),padding_data.length(), &aes_key, iv, AES_ENCRYPT);return result;
}
AES 解密
std::string AESDecrypt(const std::string& key, const void* data, int32_t len)
{if (key.empty() || len == 0) {return "";}uint8_t tmp_key[16] = {};uint8_t* ptmp_key = nullptr;if (key.length() == 16){ptmp_key = (uint8_t*)key.data();}else{ptmp_key = tmp_key;memcpy(tmp_key, key.data(), key.length() > 16 ? 16 : key.length());}uint8_t iv[16] = {};memcpy(iv, ptmp_key, 16);std::string result(len, 0);AES_KEY aes_key;AES_set_decrypt_key(ptmp_key, 128, &aes_key);AES_cbc_encrypt((uint8_t*)data, (uint8_t*)result.data(), len,&aes_key, iv, AES_DECRYPT);// 去掉paddingchar padding = result[result.length() - 1];if (padding > 0 && padding <= 16){result.resize(result.length() - padding);}return result;
}
相关文章:
微信 MMTLS 协议详解(五):加密实现
常用的解密算法,对称非对称 加密,密钥协商, 带消息认证的加解密 #生成RSA 密钥对 void GenerateRsaKeypair(std::string& public_key,std::string& private_key) {RSA* rsa RSA_new();BIGNUM* bn BN_new();// 生成 RSA 密钥对BN_s…...
Mybatis配置文件解析(详细)
引言 在了解Mybatis如何帮助客户进行数据的存取后,便对Mybatis的配置文件起了兴趣,在查阅官方文档后,总结了平时能用到的配置,希望能对大家有帮助 1.核心配置文件 主要是指Mybatis-config.xml中 其包含了会深深影响Mybatis行为…...
有额外限制的 bellman_ford 算法
题目链接 1.有限制的 B e l l m a n _ F o r d Bellman\_Ford Bellman_Ford 时间复杂度: O ( N ∗ M ) O(N*M) O(N∗M) 在传统的 B e l l m a n _ F o r d Bellman\_Ford Bellman_Ford 中,可以处理边数不大于 K K K 条边的最短距离 但我们只要加一条限制(实际…...
深度剖析 Spring 源码 性能优化:核心原理与最佳实践
深度剖析 Spring 源码 & 性能优化:核心原理与最佳实践 🚀 Spring 框架 作为 Java 生态的核心技术,广泛应用于企业级开发。但很多开发者只会“用”Spring,而不深入其内部原理,导致无法高效排查问题 & 进行性能优…...
【BFS】《单源、多源 BFS:图搜索算法的双生力量》
文章目录 前言单源BFS例题一、迷宫中离入口最近的出口二、 最小基因变化三、单词接龙四、为高尔夫比赛砍树 多源BFS例题一、 01 矩阵二、飞地的数量三、地图中的最高点四、地图分析 结语 前言 什么是单源、多源BFS算法问题呢? BFS(Breadth - First Sear…...
【2025】基于springboot+vue的医院在线问诊系统设计与实现(源码、万字文档、图文修改、调试答疑)
基于Spring Boot Vue的医院在线问诊系统设计与实现功能结构图如下: 课题背景 随着互联网技术的飞速发展和人们生活水平的不断提高,传统医疗模式面临着诸多挑战,如患者就医排队时间长、医疗资源分配不均、医生工作压力大等。同时,…...
【前端】原生项目与框架项目区别
不定期更新,建议关注收藏点赞。 使用 HTML CSS JS 和 Vue 或 React 开发的项目各有其优势与不足,适用于不同的场景。目前基本上都采用框架, 总结 何时选择 HTML CSS JS: 适用于 小型项目、简单静态页面、不需要复杂交互 或 …...
STM32基础教程——PWM驱动舵机
目录 前言 技术实现 原理图 接线图 代码实现 内容要点 PWM基本结构 开启外设时钟 配置GPIO端口 配置时基单元 初始化输出比较单元 调整PWM占空比 输出比较通道重映射 舵机角度设置 实验结果 问题记录 前言 舵机(Servo)是一种位置ÿ…...
ThreadLocal详解与高频场景实战指南
ThreadLocal详解与高频场景实战指南 1. ThreadLocal概述 ThreadLocal是Java提供的线程本地变量机制,用于实现线程级别的数据隔离。每个访问该变量的线程都会获得独立的变量副本,适用于需要避免线程间共享数据的场景。 特点: 线程封闭性&a…...
odata 搜索帮助
参考如下链接: FIORI ELement list report 细节开发,设置过滤器,搜索帮助object page跳转等_fiori element label 变量-CSDN博客 注:odata搜索帮助可以直接将值带出来,而不需要进行任何的重定义 搜索帮助metedata配置…...
RK3588开发笔记-RTL8852wifi6模块驱动编译报错解决
目录 前言 一、问题背景 二、驱动编译 总结 前言 在基于 RK3588 进行开发,使用 RTL8852 WiFi6 模块时,遇到了一个让人头疼的驱动编译报错问题:“VFs_internal_I_am_really_a_filesystem_and_am_NoT_a_driver, but does”。经过一番摸索和尝试,最终成功解决了这个问题,在…...
Docker基本命令VS Code远程连接
Docker基本命令 创建自己的docker容器:docker run --net host --name Container_name --gpus all --shm-size 1t -it -v Your_Path:Your_Dir mllm:mac /bin/bashdocker run:用于创建并启动一个新容器-name:为当前新建的容器命名-gpus&#x…...
第二天 开始Unity Shader的学习之旅之熟悉顶点着色器和片元着色器
Shader初学者的学习笔记 第二天 开始Unity Shader的学习之旅之熟悉顶点着色器和片元着色器 文章目录 Shader初学者的学习笔记前言一、顶点/片元着色器的基本结构① Shader "Unity Shaders Book/Chapter 5/ Simple Shader"② SubShader③ CGPROGRAM和ENDCG④ 指明顶点…...
大疆上云api直播功能如何实现
概述 流媒体服务器作为直播画面的中转站,它接收推流端的相机画面,同时拉流端找它获取相机的画面。整个流程如下: 在流媒体服务器上创建流媒体应用(app),一个流媒体服务器上面可以创建多个流媒体应用约定推拉流的地址。假设流媒体服务器工作在1935端口上面,假设创建的流…...
理解文字识别:一文读懂OCR商业化产品的算法逻辑
文字识别是一项“历久弥新”的技术。早在上世纪初,工程师们就开始尝试使用当时有限的硬件设备扫描并识别微缩胶片、纸张上的字符。随着时代和技术的发展,人们在日常生活中使用的电子设备不断更新换代,文字识别的需求成为一项必备的技术基础&a…...
使用 Cursor、MCP 和 Figma 实现工程化项目自动化,提升高达 200% 效率
直接上手不多说其他的! 一、准备动作 1、Cursor下载安卓 1.1访问官方网站 打开您的网络浏览器,访问 Cursor 的官方网站:https://www.cursor.com/cn 1.2开始下载: 点击"Download for free" 根据您的浏览器设置,会自…...
Arduino、ESP32驱动GUVA-S12SD UV紫外线传感器(光照传感器篇)
目录 1、传感器特性 2、控制器和传感器连线图 3、驱动程序 UV紫外线传感器是一个测试紫外线总量的最佳传感器,它不需要使用波长滤波器,只对紫外线敏感。 Arduino UV紫外线传感器,直接输出对应紫外线指数(UV INDEX)的线性电压,输出电压范围大约0~1100mV(对应UV INDEX值…...
PTA 1097-矩阵行平移
给定一个𝑛𝑛nn的整数矩阵。对任一给定的正整数𝑘<𝑛k<n,我们将矩阵的奇数行的元素整体向右依次平移1、……、𝑘、1、……、𝑘、……1、……、k、1、……、k、……个位置,平移…...
Notepad++ 替换 换行符 为 逗号
多行转一行,逗号分隔 SPO2025032575773 SPO2025032575772 SPO2025032575771 SPO2025032575771 SPO2025032575770为了方便快速替换,我们需要先知道这样类型的数据都存在哪些换行符。 点击【视图】-【显示符号】-【显示行尾符】 对于显示的行尾换行符【C…...
使用飞书API自动化更新共享表格数据
飞书API开发之自动更新共享表格 天马行空需求需求拆解1、网站数据爬取2、飞书API调用2.1 开发流程2.2 创建应用2.3 配置应用2.4 发布应用2.5 修改表格权限2.6 获取tenant_access_token2.7 调用API插入数据 总结 天马行空 之前一直都是更新的爬虫逆向内容,工作中基本…...
使用vscode搭建pywebview集成vue项目示例
文章目录 前言环境准备项目源码下载一、项目说明1 目录结构2 前端项目3 后端项目获取python安装包(选择对应版本及系统) 三、调试与生成可执行文件1 本地调试2 打包应用 四、核心代码说明1、package.json2、vite.config.ts设置3、main.py后端入口文件说明 参考文档 前言 本节我…...
蓝桥杯嵌入式十六届模拟三
由硬件框图可以知道我们要配置LED 和按键 一.LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 二.按键 按键配置,由原理图按键所对引脚要GPIO_Input 生成代码,在文件夹中添加code文件夹,code中添加fun.…...
onedav一为导航批量自动化导入网址(完整教程)
OneNav作为一个功能强大的导航工具,支持后台管理、加密链接、浏览器书签批量导入等功能,能够帮助用户轻松打造专属的导航页面。今天,我将为大家详细介绍如何实现OneNav导航站的批量自动化导入网址。 1、建立要批量导入的表格 格局需要创建表格,表格的要求是一定要有需要,…...
Linux之编辑器vim命令
vi/vim命令: 终端下编辑文件的首选工具,号称编辑器之神 基本上分为三种模式,分别是 命令模式(command mode)>输入vi的命令和快捷键,默认打开文件的时候的模式插入模式(insert mode&#x…...
备赛蓝桥杯之第十六届模拟赛2期职业院校组第四题:地址识别
提示:本篇文章仅仅是作者自己目前在备赛蓝桥杯中,自己学习与刷题的学习笔记,写的不好,欢迎大家批评与建议 由于个别题目代码量与题目量偏大,请大家自己去蓝桥杯官网【连接高校和企业 - 蓝桥云课】去寻找原题࿰…...
多模态自动驾驶混合渲染HRMAD:将NeRF和3DGS进行感知验证和端到端AD测试
基于3DGS和NeRF的三维重建技术在过去的一年中取得了快速的进步,动态模型也变得越来越普遍,然而这些模型仅限于处理原始轨迹域内的对象。 HRMAD作为一种混合方案,将传统的基于网格的动态三维神经重建和物理渲染优势结合,支持在任意…...
mac m3 pro 部署 stable diffusion webui
什么是Stable Diffusion WebUI ? Stable Diffusion WebUI 是一个基于Stable Diffusion模型开发的图形用户界面(GUI)工具。通过这个工具,我们可以很方便的基于提示词,描述一段文本来指导模型生成相应的图像。相比较通过…...
多层感知机实现
激活函数 非线性 ReLU函数 修正线性单元 rectified linear unit relu(x)max(0,x) relu的导数: sigmoid函数 s i g m o i d ( x ) 1 1 e − x sigmoid(x)\frac{1}{1e^{-x}} sigmoid(x)1e−x1 是一个早期的激活函数 缺点是: 幂运算相对耗时&…...
ngx_http_index_set_index
定义在 src\http\modules\ngx_http_index_module.c static char * ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {ngx_http_index_loc_conf_t *ilcf conf;ngx_str_t *value;ngx_uint_t i, n;ngx_http_inde…...
怎样实现CAN数据的接收和发送?
在裸机环境下实现CAN数据的接收和发送,需要通过 硬件寄存器操作 或 HAL库函数 结合 手动实现的队列 来完成。以下是完整的接收和发送流程实现: 1. 硬件初始化 首先初始化CAN控制器和GPIO: void CAN_Init(void) {// 1. 使能CAN时钟__HAL_RCC…...
