语言: C11
编译: GCC13.1.0
构建: CMake3.26
IDE: CLion2023.2.1
版本: Git2.41.0
文档: Doxygen1.9.8
OOP
由于C模拟OOP较为复杂, 此处仅简要记录, 实际开发未能使用.
object-oriented programming, 面向对象编程.
对象: 某一类事物的抽象概念.
类: 对象的表现; 具有属性(变量)和方法(函数).
实例: 根据类构建出的具体事物.
封装: 不需要被外界访问的属性和方法私有化(private); 接口与实现分离, 只暴露接口, 无需关心实现; 良好封装可以解耦合.
继承: 从现有类构造出新的类, 属性和方法(protected)被继承; 破坏了封装, 父类实现对子类暴露; 强耦合, 父类改变时子类随之而变.
多态: 具体类型和方法在编程时不确定, 运行时(编译时)可选择多个状态并最终确定; 编译时多态即函数重载/符号重载.
Git
记录快照和hash值.
modified –(add)–> staged –(commit)–> committed
|
|
提交信息格式(推荐): “<type>(<scope>): <subject>”
<type>: feat(feature) 新功能; fix/to 修复bug; docs 文档; style 修改格式; refactor 重构; perf 优化; test 增加测试; chore 构建过程或辅助工具变动; revert 回滚; merge 合并分支.
<scope>: 影响范围.
项目分支管理 (非快速合并)
项目结构
函数接口 | 函数实现 |
---|---|
头文件(.h) | 源文件(.c)/静态链接库(.a/.lib)/动态链接库(.so/.ddl) |
库文件: 目标文件(.o)的压缩.
静态链接库: 生成的可执行文件可独立运行; 重复调用的模块在链接时被多次复制, 造成代码冗余.
动态链接库(共享链接库): 链接时记录模块位置; 生成的可执行文件无法独立运行.
目录结构
xxx-build/: 构建和编译目录; 下有子目录debug/和release/;在clion中为自动生成; 一般无需追踪
.git/和.gitignore: 版本控制
dist/: 分发目录, 最终发布版本; 下可按版本号划分子目录
docs/: 文档目录
include/: 公共头文件目录; 下可按模块划分子目录
lib/: 外部依赖库目录
src/: 源文件目录; 与头文件目录同结构同名
samples/: 样例程序目录
tests/: 测试文件目录
tools/: 支撑工具目录
copyright: 版权声明文件
CMakeLists.txt或Makefile: 构建配置文件
README: 说明文件
GCC -> Makefile -> CMake
编译过程: .c –(预处理)–> .i –(编译egcs)–> .s –(汇编as)–> .o –(链接ld)–> 可执行文件.
|
|
|
|
|
|
|
|
自动生成文档 (Doxygen)
|
|
单元测试
对每个单元(函数/方法/类/子模块)的输出和异常进行测试.
以下为goolgetest方法, 由于兼容问题实际并未使用.
|
|
远程桌面 (RDP over SSH)
需求为win10客户端远程连接win10服务端.
|
|
修改"C:\ProgramData\ssh\sshd_config"文件, 若无权限保存则复制替换.
修改 Port 选项为55555.
修改 PermitRootLogin 选项为 no.
修改 PasswordAuthentication 选项为 no.
不注释 “PubkeyAuthentication yes”.
不注释 “AuthorizedKeysFile .ssh/authorized_keys”.
注释 “Match Group administrators”.
注释 “AuthorizedKeysFile PROGRAMDATA/ssh/administrators_authorized_keys”.
|
|
|
|
项目细节
命令行参数解释
|
|
内存问题
|
|
文件读写
文件读入, 路径文件不存在时读入为字符串.
|
|
写入文件.
|
|
Base64读写
以ascii读入, 需要进行转换, 每4个base64字符为一组存入3个Byte.
|
|
末尾有2个"=“时, 最后一组只有1个Byte; 末尾有1个”=“时, 最后一组只有2个Byte.
补尾规则: 1个”=“时, 最后字符补"00"得到, 即”=“前字符须整除4; 2个”=“时, 最后字符补"0000"得到, 即”=“前字符须整除16.
bit | Byte | base64("=”) |
---|---|---|
64 | 8 | 12(1) |
128 | 16 | 24(2) |
256 | 32 | 44(1) |
512 | 64 | 88(2) |
1024 | 128 | 172(1) |
base64("=") | Byte |
---|---|
4n(0) | 3n |
4n(1) | 3n-1 |
4n(2) | 3n-2 |
每3个Byte为一组输出4个base64字符.
|
|
Byte | base64("=") |
---|---|
3n | 4n(0) |
3n+1 | 4n+4(2) |
3n+2 | 4n+4(1) |
剩余1Byte时, 增加1个空Byte, 末尾补2个"=", 剩余2Byte时, 增加1个空Byte, 末尾补1个"=".
单元转换
当最小操作单元与最小读写单元一致时, 小端序或大端序实现均不会影响结果.
当最小操作单元与最小读写单元不一致时, 需要进行单元转换; 而直接修改指针类型会由于小端序而错误读取.
|
|
字节流
为便于 Bit Padding 和加解密处理, 和出于安全考虑, 对比特流加密前先将字符串型转换为字节流, 结构如下:
|
|
对 begin 使用内存分配函数, end 始终指向字节流末尾.
Bit Padding
可分为直接填充和保留长度信息填充, 直接填充即填充到分组的整数倍, 保留长度信息填充也填充到整数倍, 但最后预留一定位置存储长度信息.
而保留长度填充可在直接填充基础上, 比较填充余量和长度预留, 不足时额外增加一个分组即可.
|
|