密码学笔记——AES算法
现在仔细学习整理一下对称加密算法的典型代表——AES算法,并进行C++实现。
算法结构
这里我们只考虑AES-128,即密钥是128bit 的具体算法。
对于输入的明文,首先经过某种扩充处理,保证长度是128bit
的整数倍,然后对明文进行分组,每一组128bit
即16个字节的数据,在具体算法描述中通常会按列拼接为一个\(4\times 4\)的字节矩阵,并称为状态矩阵。
对于每一个分组执行相同的加密处理得到密文,将每一组的密文拼接即可得到最终的密文。
我们主要考虑单个分组的处理,下面的明文以及密钥均为16个字节的数据,
记明文为\(P\),密钥为\(K\),密文为\(C\)。
首先我们要进行密钥的扩展,从16字节的原始密钥\(K\)经过某种扩展算法得到10个辅助密钥\(K_1,\dots,K_{10}\),每一个\(K_i\)均是16字节的,对应一个状态矩阵,记\(K_0 = K\)。
加密算法大致分成10轮(9轮是完整的,还有1轮不完整,以及额外的初始步),输入明文\(M=P\)、密钥\(K\)以及扩展密钥\(\{K_1,\dots,K_{10}\}\),具体计算为:
初始 ...
密码学入门笔记
简单学习一点密码学基础知识。
概述
密码学是研究如何保护信息免受未经授权访问和篡改的科学。它是信息安全的一个重要组成部分,涉及加密、解密、身份验证、数据完整性等多个方面。
主要应用情景:
数据加密:保护敏感数据,如金融信息、个人数据等。
身份验证:保护系统免受未经授权的访问。
数据完整性:确保数据未被篡改。
主要算法分类:
对称加密:对称加密是一种加密方法,其中加密和解密使用相同的密钥。
非对称加密:非对称加密使用一对不同的密钥:一个用于加密(公钥),一个用于解密(私钥)。
哈希算法(摘要算法):哈希算法将输入数据转换为固定长度的输出,通常用于传输数据的完整性验证和密码的服务端存储。
注意:现代密码算法的具体实现都是公开的,使用者仅仅需要对密钥进行保密和安全传输,破解通常只能基于暴力穷举,密钥的长度往往决定了算法的安全性。
我们只关注数据的加密解密部分,包括常见的对称加密和非对称加密算法,只是宏观地介绍,并不涉及算法具体的细节。
对称加密
对称加密的特点是加密和解密过程是对等的,在加密解密过程中使用相同的密钥。
对称密码的安全性完全依赖于密钥的严格保密,加密以后的密文可以在 ...
Cpp 结构化绑定 学习笔记
结构化绑定是C++17引入的一个重要的语法糖,可以让代码写得简洁不少,值得好好整理一下语法。
概述
结构化绑定(structured binding)是 C++17 标准引入的一项特性,
允许开发者在解包元组
(std::tuple)、std::pair、数组或自定义结构体等数据结构时,
将其中各个元素直接绑定到多个变量上,使得代码更加简洁易读。
基本用法
最基本的语法形如 1auto [a0,a1,a2] = data;
这一行语句可以对data进行结构化绑定,要求:
左侧必须使用auto开头(其实还可以加上const,&等修饰,这里暂不讨论,见下文)
左侧具体需要的变量个数由右侧数据决定。
a0等是合法的C++标识符,并且不能是已经定义过的标识符
结构化绑定过程中会自动用a0等作为标识符定义变量,将其依次对应data中的元素值。
假设data是一个具有三个元素的自定义结构体 12345struct Person { std::string name; int age; double height;};
那么结构化绑定的语法基本等效于 ...
Cpp std::tuple 学习笔记
关于C++元组 std::tuple 的整理笔记。
概述
std::tuple是一个非常重要的C++标准库模块,它是一个固定大小且类型安全的数据容器,
提供了一种将任意数量的不同类型元素有序地打包组合在一起的方式,
在某些原本需要临时定义结构体的场合可以用std::tuple替代,使得代码更加简洁。
std::tuple的最大特点是编译期运算,与元组相关的标准库函数的实现属于模板元编程的范畴。在模板元编程中,元组也是一个重要角色,因为元组在编译期既含有整数信息也含有类型信息。
事实上从C++11开始,标准库的<tuple>就提供了std::tuple,但是语法既繁琐又简陋,一些直观的语法是不支持的。
在后续的标准中对std::tuple的支持在不断完善,用法变得更加简洁。
在本文中主要涉及的是C++20标准支持的用法,部分语法在C++11标准下是编译不过的。
简单示例
下面提供一个基于std::tuple实现具有多个返回值的函数示例
12345678910111213141516171819202122#include <format>#include < ...
Cpp std::format 学习笔记
已经2024年了,C++20标准正式收编fmtlib得到的格式化方案std::format已经被三大编译器支持得很好了,
虽然部分特性在后续的标准中仍然在改进,但是值得好好学习整理一下了。
std::format在形式上和Python的字符串格式化非常类似,对用户很友好。当然由于Python自身是动态的,f-string可以玩得花样更多,写起来更方便,这是C++无论如何也比不了的。
简单示例
从HelloWorld开始 12345678#include <format>#include <iostream>int main() { std::string str = std::format("Hello, {}!", "World"); std::cout << str << std::endl; return 0;}
主要是用来测试编译器支持的,编译器版本不能太低,并且还需要加入-std=c++20之类的选项,确保编译器可以顺利编译。
...
Cpp VSCode 配置
记录一下VSCode配置C++的内容吧。
插件列表
首先列一下目前在VSCode上使用的,涉及到C++的核心插件:
C/C++
(Microsoft):微软官方默认的C/C++插件,禁用了代码提示,但是调试这些还需要用它,不能完全禁用
clangd (LLVM):LLVM官方提供的,当前代码提示的主力插件
CMake (twxs):CMake的语言支持,CMakeLists的语法高亮等
CMake Tools
(Microsoft):微软官方提供的CMake支持,提供CMake命令工具条和快捷指令
CodeLLDB (Vadim Chugunov):lldb调试支持,非官方支持
还有两个不太重要的插件:
C/C++ Themes (Microsoft)
Better C++ Syntax (Jeff Hykin)
C/C++ 插件和 clangd 插件配置
主要的内容是禁用默认C/C++插件的主要功能,然后用clangd以及对应插件替换掉,并对clangd进行配置。
12345678910111213141516171819202122232425262728293031323 ...
Cpp 编译环境笔记
整理一下关于C++编译器的笔记,这部分由于不是科班出身,没学过编译原理之类的课程,细节总是搞不懂,
本文只是基于网络搜集到的各种零散的描述进行整理,不保证正确性!!!
在本文中只关注x64平台,Windows或Linux(Ubuntu)系统的C/C++编译环境,并且不考虑交叉编译等问题。
除了系统原生的MSVC和GCC,重点关注两个概念:
MinGW,MinGW-W64,MSYS...
LLVM,clang
将它们并列是不合适的,因为它们不是一个层面上的东西,但是这两个确实是我在理解C++编译环境配置时遇到的最大困难。
基本概念
c 语言的标准分成两部分:
语法,指导我们应该怎么编程,在源文件中必须满足某些规则
标准库(头文件),相对于系统层面向 c
语言程序提供的一些基础接口,例如printf等,但语法标准只是规定了接口的形式,并没有具体的实现
对 c 语言的支持,也分成两个部分:
c 编译器,从源代码得到可执行文件和库文件
c
标准库的具体实现,以库文件的形式提供最基础的功能(以及对应的头文件),供其他程序使用
由于Liunx系统和Windows系统都是基于c/c++编 ...
Cpp 日志库 spdlog 配置与使用
整理一下关于C++项目中日志库的学习,在之前曾经陆续实现过几次较为简单的日志工具,
但是在编程逐步正式化之后,自己造这种基础的轮子还是没必要的,采用成熟的spdlog日志库比较合适。
概述
spdlog是一个快速的、跨平台的C++日志库,它提供了简单易用的API,支持多种日志级别、多线程安全、异步日志写入等功能。
它具有灵活的配置选项,允许开发者根据需要自定义日志记录行为,支持日志文件的轮换和分割等常见功能。
因为spdlog的使用简单直观,文档齐全,社区活跃,它已经成为当前最常用的C++日志记录工具之一。
spdlog对使用者非常友好:
可以作为纯头文件库使用,直接复制到项目中
可以在编译安装后通过CMake导入
可以将源码直接放在项目文件夹下,作为CMake子项目添加并使用(作为头文件库或二进制库均可)
spdlog更推荐通过编译使用,因为可以节约整体的编译时间,否则每次编译时spdlog也要占用相当的时间,可能是用了大量模板的原因。在导入spdlog的头文件时,采用按需取用的策略,而不是某些库采用的只需要include一个万能头文件即可。
spdlog依赖fmtlib进行 ...
Github workflow学习笔记
学习一下Github仓库的工作流语法,希望在Github仓库中自动执行测试。
重点关注两类项目所需要的基本测试工作流,分别是跨平台CMake项目和LaTex项目。
概述
Github仓库提供工作流来自动化执行应用的部署,测试和发布等流程。工作流的实质是在Github服务器上提供了几个临时的虚拟环境(Docker),让用户在提交或其他Git行为后触发工作流,然后在虚拟机环境中自动执行相关的指令。
例如,可以使用一个工作流来构建和测试拉取请求,使用另一个工作流在每次创建版本时部署应用程序,
还有另一个工作流程在每次有人打开新问题时添加标签。
注意:
Github仓库支持多个工作流,它们可以同时触发或分别触发。
Github对公开仓库提供的这类服务是无限制的,但是对私有仓库是受限的,每个月提供免费的时间额度和存储额度,超额需要付费。
如果在仓库中触发的一个工作流运行失败了,Github可能通过邮件通知。
一个典型的工作流(workflow)包含:
触发工作流的一个或多个事件
一个或多个作业(job),每个作业都将在运行器机器上执行并运行一系列的一个或多个步骤(step),每个步骤都可以 ...
GoogleTest + CTest 配置与使用
现在我们关注CMake项目中的测试部分,具体包括GoogleTest和CTest的使用。
概述
Google Test(简称为 gtest)是 Google 开发的一个开源的 C++
测试框架,用于编写和运行单元测试、集成测试和功能测试。主要特点包括:
支持各种平台和编译器,包括 Linux、Windows 和 macOS,并且与主流的 C++
编译器兼容。
提供了丰富的断言宏,如
EXPECT_EQ、ASSERT_TRUE
等,用于验证代码行为是否符合预期。
支持参数化测试,允许以不同的参数运行同一个测试用例。
可以生成详细的测试报告,包括测试通过的数量、失败的数量、失败的原因等信息。
可以扩展测试框架,编写自定义的测试扩展和断言宏。
CTest 是 CMake
附带的一个测试工具,用于管理和执行项目中的测试。它是一个命令行工具,可以通过简单的命令来执行测试,并生成测试报告。主要特点包括:
可以在构建系统中自动发现项目中的测试,并执行它们。
支持各种测试框架,包括 Google Test、Catch、Boost.Test 等。
可以通过简单的命令行选项来控制测试的执行,如选择特 ...