密码学笔记——RSA算法
整理一下RSA算法的内容,主要参考维基百科。 对称加密与非对称加密 首先从对称加密开始,Alice和Bob需要进行加密的通信,Alice传递信息 \(m\) 给Bob。 为了信息安全,Alice首先用字母表替换的方式 \(A\) 将明文m变成密文 \(m'=f_A(m)\),然后通过公开方式传递给Bob,Bob使用同样约定好的字母表替换方式 \(A\) ,将收到的密文 \(m'\) 变成明文 \(f_A^{−1}(m')=f_A^{−1}(fA(m))=m\) 。 这里我们对信息都视作字符串,从而字母表替换规则 \(A\) 实际上定义了字符串到字符串的加密函数 \(f_A\) 和解密函数 \(f_A^{−1}\) ,这里加密函数和解密函数都是通过 \(A\) 决定的,并且极容易从其中一个推出另一个,因此双方都必须保管好密码本 \(A\) 。 例如,使用替换的字母表 \(A\) 为 11->3, 2->4, 3->2, 4->1 用轮换的记号就是\((1324)\),此时的加密函数 \(f_A\) ,明文\(1234\),密文 \(f...
C 语言练习——实现终端进度条
记录一下通过C语言实现在终端中展示进度条的动画效果,代码同时支持 Linux 和 Windows。 头文件如下 pbar.h12345678910111213141516171819202122#ifndef PBAR_H#define PBAR_H#ifdef __cplusplusextern "C" {#endifstruct pbar *pbar_create();struct pbar *pbar_create_colorful();struct pbar *pbar_create_simple();struct pbar *pbar_create_simple_colorful();void pbar_update(struct pbar *pb, double pct);double pbar_time_cost(struct pbar *pb);#ifdef __cplusplus}#endif#endif // PBAR_H 这里导出的接口同时支持 C 和 Cpp。 具体实现的源文件如下 pbar.c1234567891...
Docsify 搭建记录
需要一个小型的在线文档系统,Docsify 可以满足需求,记录一下搭建记录,主要 Docsify 官方的中文文档。 本地搭建 前提:本地需要安装 nodejs 并完成相应配置。 新建 DocBase/ 文件夹,在其中本地安装 docsify-cli 1npm i docsify-cli -g 由于 docsify-cli 不是全局安装的,存在找不到 hexo 命令的问题,对于 Windows 可以通过临时添加路径到 PATH 解决,在 DocBase 目录下执行 1$env:Path += ";$((Get-Item -Path .\node_modules\.bin -Force).FullName)" 初始化项目 1docsify init ./docs 初始化过程会自动新建 ./docs 子文件夹,并生成如下文件: index.html:项目入口 README.md:内容会被渲染成项目主页 .nojekyll:防止 Github 忽视下划线开头文件 使用下面的命令可以在本地预览 123cd ./docsdocsify serve# or do...
Cpp 基础笔记整理
一些零散的不同主题的 Cpp 基础笔记,单独拆开显得内容太少,干脆整理到一起。 类型别名 typedef typedef是用于为类型定义别名的关键字,在C和C++中都可以使用。 最简单的用法是对基本类型起别名,例如 1typedef int Length; 下面的是MSVC的stdint.h中的部分源码,对基本数据类型起了意义更明确的别名 12345678typedef signed char int8_t;typedef short int16_t;typedef int int32_t;typedef long long int64_t;typedef unsigned char uint8_t;typedef unsigned short uint16_t;typedef unsigned int uint32_t;typedef unsigned long long uint64_t; 数组类型和指针类型可以通过typedef起别名达到简化语法和提升可读性...
Linux 学习笔记:控制台,终端,tty
整理一下关于下面这些概念的学习: 终端(terminal) 控制台(console) 电传打字机 tty(teletype) 这些概念在早期是有明确的定义的,但是随着计算机的发展,它们的物理实体逐渐消失,各种概念主要靠计算机软件模拟,它们之间的区别变得模糊难以理解,因此学习整理一下,以Linux系统为主。 TODO shell 控制台与终端 早期的计算机是一套巨大的机器,就像工厂的大型机器一样,如此的庞然大物必然需要一个专门的操作台, 用于陈列各种仪表盘、指示灯、按钮、电线,专业操作人员通过这个操作台控制计算机的启动、运行、停止,结果也会实时反馈到操作台,这个操作台就叫“控制台”(console)。 控制台是附着在机器上的设备,可以实现对计算机的完全操控,但是主要是用来管理计算机的。 对于多用户操作系统(特别是UNIX),控制台并不方便给用户提供计算服务。 因此自然产生了终端(terminal)的硬件概念:每个用户通过终端设备与主机远程连接(还不是现代意义上的基于互联网的远程连接),管理员给每个用户分配一个账户,用户“登录”到系统获得计算机使用权。在这个阶段,计算机通常只...
Cpp 并行计算学习笔记
基本概念 首先学习几组基本概念: 同步(Synchronous)/异步(Asynchronous) 并发(Concurrency)/并行(Parallelism) 进程(Process)/线程(Thread) 同步 / 异步 同步是指任务按照顺序依次执行,每个任务在前一个任务完成后开始执行。在同步模式中,任务之间需要等待其他任务完成才能继续执行。 异步是指任务可以独立于其他任务进行执行,它们的执行过程不会产生堵塞。在异步模式中,任务可以在后台执行,执行结果可能需要等待一段时间才能获得,但这不会影响其他任务的执行。 举个例子: 手洗衣服的流程是同步的:先将衣物放入盆中,再加入洗衣粉,然后开始洗衣,等到洗衣完成,最后取出衣物晾干或烘干,每一步的开始都依赖于前一步的完成,在过程中也干不了其他事。 使用洗衣机洗衣服是异步的:将衣物放入洗衣机并启动,洗衣机开始运作,此时人不需要等待在洗衣机旁,可以干其它任何事,等到洗衣机完成后会发出通知,然后取出衣物晾晒即可,当然也可以选择等在一边,不干其他事。 并发 / 并行 并发指的是多个任务在同一时间段内被同时推进,可能是同时执行不同的...
GCC 源码编译安装(离线,普通用户)
gcc 的非 root 用户离线编译安装比其他的软件的源码安装都要复杂:因为它有依赖,在服务器上无法通过联网下载,要提前下载依赖的压缩包,而且gcc的编译时间很长。 安装过程主要参考CentOS7 离线升级安装gcc到6.3.0 和Linux 非root安装GCC9.1.0 下载依赖 在官网或者镜像网站下载 gcc-11.4.0.tar.gz,传到服务器上解压为~/tmp/gcc-11.4.0 进入~/tmp/gcc-11.4.0子目录,需要解决下载依赖的问题。在可以联网的情况下,直接执行自带的下载依赖的脚本 ./contrib/download_prerequisites。如果服务器无法联网,则需要手动下载处理 查看上述脚本,找到四个必要的依赖 gmp,mpfr,mpc,isl 以及对应的具体版本,例如 gcc-11.4.0 需要的四个依赖版本及其下载地址如下(不同版本的gcc对应的依赖版本也不一样) 123456gmp='gmp-6.1.0.tar.bz2'mpfr='mpfr-3.1.6.tar.bz2'mpc='mpc-...
Cpp 面向对象——成员函数中的 this
整理一下关于C++类的成员函数所拥有的特殊的this指针的知识,并且学习C++23中的新内容:显式推导this。 隐式this 基础 this指针是C++面向对象编程中的重要机制,在自定义类型的非静态成员函数中,都存在这一个自动传递的this指针指向当前对象自身,例如 12345678910111213#include <iostream>struct Test { int data = 0; void call() { std::cout << "call: " << data << "\n"; }};int main() { Test test{1}; test.call(); return 0;} 对于编译器来说,这里的定义和调用过程等效于下面的形式(因为this是关键词,在代码中使用this_来代表) 1234567891011121314#include <iostre...
Cpp 未定义行为/小坑/冷知识
未定义行为 概述 C/C++存在很多的未定义行为,如果程序中使用了未定义行为,那么得到的结果是不可知的,编译器给出任何反馈都是符合语法标准的,因为未定义行为导致的BUG是难以察觉的。 未定义行为可能会导致编译报错,也可能导致运行出错等,还可能无事发生,具体结果可能与平台/编译器有关,不过在大部分情况下不同编译器会得到类似的结果。 未定义行为的存在是有客观原因的,一方面语法标准无法穷尽所有的可能情况;另一方面有些可能非法的行为(例如下标越界)在编译期难以直接检测,如果在运行期进行检测(例如检查下标越界),又会牺牲很多的运行效率。 如果我们在不经意间使用了未定义行为,那么即使是相同的代码,在C++的编译器不同等级的优化措施下,也可能得到完全不同的结果,例如: Debug模式正常,Release模式异常 例如产生随机的结果,通常的原因是使用没有正确初始化的变量,在Debug模式下被编译器初始化为0,但是Release模式下直接使用了内存中的随机值; 其它未定义行为,在Release模式下经过编译器优化中,产生不合理的结果。 Debug模式异常,Release模式正常 代码中的未...
编程语言中的整数和浮点数
整理一下编程语言中的整数和浮点数的相关内容,针对的情景是科学计算。 整数 整数模型 编程语言中的整数类型不同于数学意义上的整数,而只是它的一个有限子集,因为计算机为了计算效率,会使用固定的字节数来存储一个整数数据,例如 \(n\) 个字节,这意味这只有 \(2^{8n}\) 个不同状态,只能表示 \(2^{8n}\) 个整数。 将 \(n\) 个字节所对应的 \(8n\) 比特的值依次记作 \(a_i \in \{0,1\}\),这里 \(i=0,\dots,8n-1\),那么通常有两类方案: 第一种方案是无符号整数,表示的值 \(V\) 为 \[ V = 2^0 a_0 + 2^1 a_1 + \dots + 2^{8n-2} a_{8n-2} + 2^{8n-1} a_{8n-1} \] 表示的范围为 \[ [0,2^{8n}-1] \] 第二种方案是有符号整数,表示的值 \(V\) 为 \[ V = 2^0 a_0 + 2^1 a_1 + \dots + 2^{8n-2} a_{8n-2} - 2^{8n-1} a_{8n-1} \] 表示的范围为 \[ [-2^{8n-1...
