时光酒馆 - 精选文章：技术&分享
type: channel
link: https://www.siguangblog.cc/category/x/
items: 在UE5中，使用`GConfig`类操作配置文件的核心方法
items: 开源项目推荐
items: 解读那些令人困惑 Git 术语
items: 白话 C++ 第一章
items: MyBatis 源码解析
items: fluffos编译构建
items: 精选 10 个最美的 Linux 发行版
items: 假装很忙的三个命令行工具
items: 密码学及公钥基础设施入门

在UE5中，使用`GConfig`类操作配置文件的核心方法
type: item
date: 2025-09-30T10:13:12+08:00
description: 在UE5中，使用GConfig类操作配置文件的核心方法如下：一、基础操作流程创建配置文件路径// 获取项目配置目录（自动创建） FString ConfigPath = FPaths::ProjectConfigDir() / "MyConfig.ini"; // 或直接指定路径 FString CustomPath = FPaths::ProjectDir() / "Config/MyConfig.ini";写入配置数据void UMyFunctionLibrary::WriteConfig( const FString& Section, const FString& Key, const FString& Value, const FString& ConfigPath ) { GConfig->SetString(*Section, *Key, *Value, *ConfigPath); GConfig->Flush(true, *ConfigPath); // 强制刷新到磁盘 }读取配置数据FString UMyFunctionLibrary::ReadConfig( const FString& Section, const FString& Key, const FString& ConfigPath ) { FString Result; GConfig->GetString(*Section, *Key, Result, *ConfigPath); return Result; }二、高级配置方法自动配置类（推荐）UCLASS(config=MyConfig, defaultconfig) class UMyConfig : public UObject { GENERATED_BODY() UPROPERTY(Config, EditAnywhere) float TestValue = 1.0f; UPROPERTY(Config, EditAnywhere) FString TestString = "Default"; };自动保存路径：ProjectName/Config/DefaultMyConfig.ini（默认配置）运行时路径：ProjectName/Saved/Config/Windows/MyConfig.ini【3】全局配置标记UPROPERTY(globalconfig) int32 GlobalSetting = 42;优先级高于局部配置保存在DefaultEngine.ini根目录【9】三、蓝图集成方案创建蓝图库类UCLASS(BlueprintType) class UConfigManager : public UBlueprintFunctionLibrary { GENERATED_BODY() UFUNCTION(BlueprintCallable, Category="Config") static void SaveConfig(FString Section, FString Key, FString Value) { UConfigManager::WriteConfig(Section, Key, Value, FPaths::ProjectConfigDir() / "MyConfig.ini"); } // 对应读取函数... };通过#include "Config/ConfigManager.h"暴露给蓝图【7】四、打包配置设置Build.cs配置public class YourProjectBuild : ModuleRules { public YourProjectBuild(ReadOnlyTargetRules Target) : base(Target) { RuntimeDependencies.Add(Path.Combine(ModuleDirectory, "../../Config", "MyConfig.ini")); } }确保配置文件包含在发布包中【8】五、注意事项路径规范ProjectConfigDir()：ProjectName/Config/GeneratedConfigDir()：ProjectName/Saved/Config/【3】【4】刷新机制GConfig->Flush(true)：强制写入磁盘GConfig->Flush(false)：仅更新内存缓存类型支持基础类型：FString/int32/float复杂类型需序列化处理六、完整示例// MyConfigManager.h #pragma once #include "CoreMinimal.h" #include "UObject/NoExportTy…

开源项目推荐
type: item
date: 2025-01-12T07:50:00+08:00
description: 网站历经 300 天的上线运行，现发布演示！站长将以最低成本维护本站，力求稳定存活长久本站大部分源码已开源至 GitHub 社区域名：gal.saop.cc源码：github.com/AdingApkgg/vns社群：t.me/FullDiveSAO

解读那些令人困惑 Git 术语
type: item
date: 2024-08-30T20:55:23+08:00
description: 我正在一步步解释 Git 的方方面面。在使用 Git 近 15 年后，我已经非常习惯于 Git 的特性，很容易忘记它令人困惑的地方。因此，我在 Mastodon 上进行了调查：你有觉得哪些 Git 术语很让人困惑吗？我计划写篇博客，来解读 Git 中一些奇怪的术语，如：“分离的 HEAD 状态”，“快速前移”，“索引/暂存区/已暂存”，“比 origin/main 提前 1 个提交”等等。我收到了许多有洞见的答案，我在这里试图概述其中的一部分。下面是这些术语的列表：HEAD 和 “heads”“分离的 HEAD 状态”在合并或变基时的 “ours” 和 “theirs”“你的分支已经与 'origin/main' 同步”HEAD^、HEAD~、HEAD^^、HEAD~~、HEAD^2、HEAD~2.. 和 ...“可以快速前移”“引用”、“符号引用”refspecs“tree-ish”“索引”、“暂存的”、“已缓存的”“重置”、“还原”、“恢复”“未跟踪的文件”、“追踪远程分支”、“跟踪远程分支”检出reflog合并、变基和遴选rebase –onto提交更多复杂的术语我已经尽力讲解了这些术语，但它们几乎覆盖了 Git 的每一个主要特性，这对一篇博客而言显然过于繁重，所以在某些地方可能会有一些粗糙。HEAD 和 “heads”有些人表示他们对 HEAD 和 refs/heads/main 这些术语感到困惑，因为听起来像是一些复杂的技术内部实现。以下是一个快速概述：“heads” 就是 “分支”。在 Git 内部，分支存储在一个名为 .git/refs/heads 的目录中。（从技术上讲，官方 Git 术语表 中明确表示分支是所有的提交，而 head 只是最近的提交，但这只是同一事物的两种不同思考方式）HEAD 是当前的分支，它被存储在 .git/HEAD 中。我认为，“head 是一个分支，HEAD 是当前的分支” 或许是 Git 中最奇怪的术语选择，但已经设定好了，想要更清晰的命名方案已经为时已晚，我们继续。“HEAD 是当前的分支” 有一些重要的例外情况，我们将在下面讨论。“分离的 HEAD 状态”你可能已经看到过这条信息：$ git checkout v0.1 You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. [...] （消息译文：你处于 “分离 HEAD” 的状态。你可以四处看看，进行试验性的更改并提交，你可以通过切换回一个分支来丢弃这个状态下做出的任何提交。）这条信息的实质是：在 Git 中，通常你有一个已经检出的 “当前分支”，例如 main。存放当前分支的地方被称为 HEAD。你做出的任何新提交都会被添加到你的当前分支，如果你运行 git merge other_branch，这也会影响你的当前分支。但是，HEAD 不一定必须是一个分支！它也可以是一个提交 ID。Git 会称这种状态（HEAD 是提交 ID 而不是分支）为 “分离的 HEAD 状态”例如，你可以通过检出一个标签来进入分离的 HEAD 状态，因为标签不是分支如果你没有当前分支，一系列事情就断链了：git pull 根本就无法工作（因为它的全部目的就是更新你的当前分支）除非以特殊方式使用 git push，否则它也无法工作git commit、git merge、git rebase 和 git cherry-pick 仍然可以工作，但它们会留下“孤儿”提交，这些提交没有连接到任何分支，因此找到这些提交会很困难你可以通过创建一个新的分支或切换到一个现有的分支来退出分离的 HEAD 状态在合并或变基中的 “ours” 和 “theirs”遇到合并冲突时，你可以运行 git checkout --ours file.txt 来选择 “ours” 版本中的 file.txt。但问题是，什么是 “ours”，什么是 “theirs” 呢？我总感觉此类术语混淆不清，也因此从未用过 git checkout --ours，但我还是查找相关资料试图理清。在合并的过程中，这是如何运作的：当前分支是 “ours”，你要合并进来的分支是 “theirs”，这样看来似乎很合理。$ git checkout merge-into-ours # 当前分支是 “ours” $ git merge fro…

白话 C++ 第一章
type: item
date: 2024-08-14T22:22:11+08:00
description: 第一章 程序漫谈 程序漫谈1.1 硬件、软件、程序1.2 计算机语言1.3 语言和实现语言的工具 1.3.1 机器语言 1.3.2 汇编语言 1.3.3 高级语言 1.3.4 语言实现工具 1.3.4.1 C++ Builder 的基ᴀ功能 1.3.4.2 VCL vs. MFC1.1 硬件硬件、、、、软件软件、、、、程序程序对于计算机，也许你是老鸟，也许你是菜鸟……但不管怎样，如果你此时此地你要学习编程，那么你应该多多少少知道点什么叫硬件什么叫软件——反正我不管你懂不懂，为了面子，我很不乐意你问我什么叫硬件什么叫软件——我做在这凳子半个小时了，一直想不出如何给二者下个定义。 美国一个电脑神童说：“凡是摔到地上会坏的就是硬件。”我深感不妥，众所周知，如果把硬盘摔到地上，那么硬盘坏了，里头的那些数据——都是软件——也一样地坏得让你我心疼。 倘若按字面上理解，那就更加的矛盾重重：硬盘硬是硬件；软盘软也是硬件。 还一种说法是：看得见摸得着的为硬件，看不见摸不着的为软件。刚觉得它说得不错，但马上我就发觉了它的破绽：我现在用的 Word2000，它就在屏幕上，界面美观，操作方便……无奈之下，我搬出金山词霸，它说：“硬件：计算机及其它直接参与数据运算或信息交流的物理设备”。挺好。硬件就是设备。平常我们生活中的各种设备，洗衣机，冰箱，电视，还有螺丝刀，钳子，都是硬件。 软件呢？“软件：控制计算机硬件功能及其运行的指令、例行程序和符号语言”。指令、程序和符号语言是什么且不说，至少我们得知：软件是用来控制硬件的运行的。 这就好办点。我们可以打比方：譬如汽车，其ᴀ身自然是硬件，但关于驾驶车的那一套技术，及有关交通规则，我们可称为软件，因为后者控制了前者的运行方式。 （不传之秘笈：如果你英语一般，学习编程时，别忘装上金山词霸。并且装上后立即上网升级） 现在来谈“指令、程序、和符号语言”。我想交通方面的“软件”确实就是这些东西。我不会驾车，但曾多次看到警察在我上班坐的班车前用指头一指，就令我们的司机脸色发青。之后，一套既定的处罚程序被执行。很快，਀说我们的司机又在学习那些用来表示“单行”、“只许右拐”、“不许停车”、“禁鸣”等奇奇怪怪的符号语言了…… 事实上，说软件看不见摸不着其实也正确。因为它们是思想，精神，规则，逻辑。ᴀ身是抽象的，确实不可触及。但软件总是要有载体来存放，要有表达或表现方式，这些使得它们变得形象具体起来。在此意义上，说软件是摔在地上坏不了的东西，也相当行得通，神童毕竟是神童。 最后，什么是程序？我决定斗胆来给它下个定义： 程序是一组按照一定的逻辑的进行组合的指令。 因此，在以后的学习过程上，很多时候我们会觉得程序就是指令；同样很多时候，我们觉得程序就是逻辑。 当然，更多的时候，我们并不区分程序和软件二者。也许前者更趋于抽象，而后者趋于具体。比如我们在写那些表达我们的思想逻辑时，我们喜欢说“写程序”；而当程序完成，可以待价而沽时，我们称它为软件。1.2 计算机语言 计算机语言程序用计算机语言写成。编程的实质就是你用计算机语言来表达你解决问题的逻辑。 那么，什么叫计算机语言？ 先不必去解释。因为，计算机是机器，机器不是生物，它怎么能有语言？小猫小狗有语言我尚可相信，机器也有语言，还要我们去学习，这似乎有渎人类之尊严。 如果我不把这个结解开，可能部分特别在意人类尊严的学生对学习编程从此产生心理障碍，无法继续学习…… 狭义上，我们讲的语言，汉语英语广东话，它是语言，有声音。小鸟之间吱吱喳喳，大抵也是语言。但其实语言二字虽都带口，却不是说非得有声才称为语言：哑语无声，但它也是语言。广义上讲，语言是沟通、交流的一种手段。基于此，我们认为所有的机器或工具，也就包括计算机，都有它们自己的语言。比如锤子，它的语言是敲打；比如螺丝刀，它的语言是拧，如果你非要拧锤子，非要敲打螺丝刀，那么结果就像你用法语和广东佬交谈，用粤语和法国佬说话一样莫名其妙。 一般地，越复杂的机器，人类与其沟通的语言也越复杂。譬如汽车，你想驾驭它，你就必须去驾校参加学习。想一想，开车的时候，我们的确是在和车进行沟通。如果你俩之间的沟通出现差错——你心里右转，手却一个劲向左转方向盘，向机器发出了错误的命令——这将多么可怕！ 至此，我们的心理障碍可以消除了。小猫小狗有语言是因为它们聪明，而机器有语言却是因为它们的笨：它们笨，没办法像动物一样可以通过培训来理会人类的意愿，所以，让人类来反过来为它们定一套沟通的规则，然后人自己去学会这些语言，从而可以方便控制机器。 再所以，我们推论，凡是机器语言都是笨笨的语言。机器语言可以分低级语言和高级语言，但无论何者，都是笨得可爱——学得越多你就会越发现它的笨和可爱。另外，当我说越复杂的机器，其语言也越复杂时，我用“一般地”加以修饰。这是因为，发明和…

MyBatis 源码解析
type: item
date: 2024-08-08T16:40:45+08:00
description: 大家应该都知道 Mybatis 源码也是对 Jbdc 的再一次封装，不管怎么进行包装，还是会有获取链接、preparedStatement、封装参数、执行这些步骤的。配置解析过程 String resource = "mybatis-config.xml"; //1.读取resources下面的mybatis-config.xml文件 InputStream inputStream = Resources.getResourceAsStream(resource); //2.使用SqlSessionFactoryBuilder创建SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //3.通过sqlSessionFactory创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession();Resources.getResourceAsStream (resource) 读取文件public static InputStream getResourceAsStream(String resource) throws IOException { return getResourceAsStream(null, resource); } //loader赋值为null public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException { InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader); if (in == null) { throw new IOException("Could not find resource " + resource); } return in; } //classLoader为null public InputStream getResourceAsStream(String resource, ClassLoader classLoader) { return getResourceAsStream(resource, getClassLoaders(classLoader)); } //classLoader类加载 InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) { for (ClassLoader cl : classLoader) { if (null != cl) { //加载指定路径文件流 InputStream returnValue = cl.getResourceAsStream(resource); // now, some class loaders want this leading "/", so we'll add it and try again if we didn't find the resource if (null == returnValue) { returnValue = cl.getResourceAsStream("/" + resource); } if (null != returnValue) { return returnValue; } } } return null; }总结：主要是通过 ClassLoader.getResourceAsStream () 方法获取指定的 classpath 路径下的 Resource 。通过 SqlSessionFactoryBuilder 创建 SqlSessionFactory//SqlSessionFactoryBuilder是一个建造者模式 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); public SqlSessionFactory build(InputStream inputStream) { return build(inputStream, null, null); } //XMLConfigBuilder也是建造者模式 public SqlSessionFactory build(InputStr…

fluffos编译构建
type: item
date: 2024-08-08T16:37:40+08:00
description: changeme1.安装依赖项sudo apt update sudo apt install build-essential bison libmysqlclient-dev libpcre3-dev libpq-dev \ libsqlite3-dev libssl-dev libz-dev libjemalloc-dev libicu-dev 2.签出 Git 存储库git clone https://github.com/fluffos/fluffos.git cd fluffos git checkout master #(or an release tag) 3.升级你的 cmakesudo pip install --upgrade cmake 4.开始构建mkdir build cd build cmake .. make -j `nproc` install 5.自动化脚本!/bin/bash更新系统软件包列表sudo apt update 安装软件包及依赖库sudo apt install git bison build-essential autoconf automake cmake gcc g++ libjemalloc-dev zlib1g-dev libbz2-dev libssl-dev libmysqlclient-dev libsqlite3-dev libpq-dev libpcre3-dev libevent-dev libicu-dev libdw-dev binutils-dev libgtest-dev telnet python3 -y 进入当前用户的 home 目录cd ~ 如果 fluffos 目录不存在，则从 gitee 克隆 fluffos 仓库if [ ! -d "fluffos" ]; then git clone https://gitee.com/mudren/fluffos.git fi 进入 fluffos 目录并拉取最新代码cd fluffos && git checkout . && git pull 如果 build 目录已存在，则删除if [ -d "build" ]; then rm -rf build fi 创建 build 目录并进入mrkdi build && cd build 记录开始时间starttime=`date +'%Y-%m-%d %H:%M:%S'` 编译 fluffos，使用多线程编译，开启 SQLite 数据库和默认数据库支持cmake -DPACKAGE_DB_SQLITE=2 -DPACKAGE_DB_DEFAULT_DB=2 .. && make -j$(nproc) install 记录结束时间endtime=`date +'%Y-%m-%d %H:%M:%S'` 计算编译时间start_seconds=$(date --date=" $starttime" +%s); end_seconds=$(date --date="$endtime" +%s); 输出编译时间echo Start: $starttime. echo End: $endtime. echo "Build Time: "$((end_seconds-start_seconds))"s." 复制驱动至系统目录sudo cp bin/driver /usr/local/games/ 自动化脚本去掉.txt后缀名即可执行

精选 10 个最美的 Linux 发行版
type: item
date: 2024-08-04T22:47:02+08:00
description: 我们选出 2022 年 10 个最美的 Linux 发行版，在保证系统稳定的前提下，会给你良好的视觉体验。定制化拓展 Linux 发行版以满足需求是非常有意思的事。无论是 Ubuntu 还是 Fedora ，都有各种各样的工具去定制化 Linux 桌面。但是，也有很多不需要任何定制化而且令人眼前一亮的 Linux 发行版。它们的开发者使它们在安装后不需要再定制化就能有非常好的视觉效果。现在，我们编制了一份最美 Linux 发行版列表，你可以现在尝试来更新你电脑的视觉外观。2022 最美的 Linux 发行版1、Zorin OS最先介绍的 Linux 发行版是 Zorin OS。Zorin OS 使用基于 GNOME 的 Zorin 桌面 ，非常适合追求美观的桌面和生产力的新用户。Zorin OS 最有特点的功能之一是，它可以随意转化，让其看起来像其他操作系统桌面，这意味着只需要设置布局选项，就可以改变任务栏、应用菜单、停靠栏，给用户最大的的灵活性，安装即用。阅读有关 Zorin OS 更多信息2、elementary OSelementary OS 是基于 Ubuntu 长期稳定支持（LTS）发行版中最美观的一个。它使用吸引人的 Pantheon 桌面环境，其外观和使用体验受到了 macOS 的启发。elementary OS 非常适合从 macOS 进入 Linux 世界的新用户，因为他们会发现许多熟悉的东西，比如手势和窗口样式。但是，elementary OS 很多地方不能通过设置菜单进行定制，只能依靠外部脚本命令来进一步定制。不过系统默认桌面就已经十分美观了，能满足大部分人的需求。elementary OS 最具特色的是它精心设计的应用商店。应用商店提供各种类别的应用，特别是那些专为 elementary OS 定制而且外观精美、功能强大的应用。阅读有关 elementaryOS 更多信息3、深度操作系统第三个介绍的 Linux 发行版是深度操作系统。它基于 Debian ，由中国深度科技公司开发。它使用自研的基于 Qt 的深度桌面环境（DDE）。深度桌面的部件、配色方案、窗口样式、壁纸看起来都非常不错，给用户安装即享的视觉体验。深度操作系统精心打磨的视觉组件和 macOS 非常相似。并且由于是 Debian 的稳定分支，如果你想要一个外观精美且稳定可靠的 Linux 发行版，深度操作系统是最适合的选择。为什么深度操作系统体验很好？基于 Qt 的酷炫桌面原生部件及支持暗色主题定制化停靠栏的多种选择项透明度、窗口效果、光标主题、图标主题强调色阅读有关深度操作系统更多信息4、CutefishOS第四个介绍的 Linux 发行版是 CutefishOS 。这个基于 Debian 和 Ubuntu 的 Linux 发行版具有一个原生开发的 Cutefish 桌面。 CutefishOS 还在开发中，但由于它的外观，它已经在用户群体中掀起波澜。（LCTT 译注：似乎也是国内团队开发的）CutefishOS 底层基于 Qt 和 KDE 框架构建。这个带有 Cutefish 桌面的高效 Linux 发行版在顶部提供了全局菜单功能。由于其目前正在开发中，定制选项仍在进行中。但在最新的发行版中， CutefishOS 已经支持深色模式、强调色、动画效果、停靠位置（左、右、下）等选项。如果你想体验完全不同的桌面风格，可以尝试 CutefishOS 。 你也可以查看下面提供的关于此桌面的完整评论和教程。Cutefish OS 测评5、Manjaro KDE Plasma 版Manjaro Linux KDE 版是现在外观最好看的 Linux 发行版之一。 Manjaro KDE 基于 Arch Linux ，采用了 KDE Plasma，并额外添加了一些调整工具和组件。 Manjaro 的绿色调色板给你以全新的外观和体验。你可以通过内置的 KDE 工具和设置进一步定制，并从 KDE 商店获得图标和主题。Manjaro KDE 是性能和外观与 Arch Linux 之强大的完美结合。对于 Arch Linux 新用户来说， Manjaro 是一个理想的起点。阅读有关 Manjaro KDE 更多信息6、Garuda Linux出名的 Garuda Linux 是榜单上的第六位。 Garuda Linux 基于 Arch Linux ，带有美观的桌面，其特点是为所有主流桌面环境定制了图标、主题。 Garuda Linux 使用针对硬件优化了性能的 Zen 内核，Garuda Linux 的外观和体验令人印象深刻。其 macOS 风格看起来非常的方便。 Neon 图标主题、可爱的调色板、模糊和透明度与全局菜单的结合是其自身的完美选择。Garuda …

假装很忙的三个命令行工具
type: item
date: 2024-08-04T22:28:25+08:00
description: 有时候你很忙。而有时候你只是需要看起来很忙，就像电影中的黑客一样。有一些开源工具就是干这个的。如果在你在消磨时光时看过谍战片、动作片或犯罪片，那么你就会清晰地在脑海中勾勒出黑客的电脑屏幕的样子。就像是在《黑客帝国》电影中，代码雨 一样的十六进制数字流，又或是一排排快速移动的代码。也许电影中出现一幅世界地图，其中布满了闪烁的光点和一些快速更新的图表。不可或缺的，也可能有 3D 旋转的几何形状。甚至，这一切都会显示在一些完全不符合人类习惯的数量荒谬的显示屏上。 在《剑鱼行动》电影中黑客就使用了七个显示屏。当然，我们这些从事计算机行业的人一下子就明白这完全是胡说八道。虽然在我们中，许多人都有双显示器（或更多），但一个闪烁的数据仪表盘、刷新的数据通常和专注工作是相互矛盾的。编写代码、项目管理和系统管理与日常工作不同。我们遇到的大多数情况，为了解决问题，都需要大量的思考，与客户沟通所得到一些研究和组织的资料，然后才是少许的 敲代码。然而，这与我们想追求电影中的效果并不矛盾，也许，我们只是想要看起来“忙于工作”而已。注：当然，我仅仅是在此胡诌。如果您公司实际上是根据您繁忙程度来评估您的工作时，无论您是蓝领还是白领，都需要亟待解决这样的工作文化。假装工作很忙是一种有毒的文化，对公司和员工都有害无益。这就是说，让我们找些乐子，用一些老式的、毫无意义的数据和代码片段填充我们的屏幕。（当然，数据或许有意义，但不是在这种没有上下文的环境中。）当然有一些用于此用途的有趣的图形界面程序，如 hackertyper.net 或是 GEEKtyper.com 网站（LCTT 译注：是在线假装黑客操作的网站），为什么不使用标准的 Linux 终端程序呢？对于更老派的外观，可以考虑使用 酷炫复古终端，这听起来确实如此：一个酷炫的复古终端程序。我将在下面的屏幕截图中使用酷炫复古终端，因为它看起来的确很酷。Genact我们来看下第一个工具——Genact。Genact 的原理很简单，就是慢慢地无尽循环播放您选择的一个序列，让您的代码在您外出休息时“编译”。由您来决定播放顺序，但是其中默认包含数字货币挖矿模拟器、Composer PHP 依赖关系管理工具、内核编译器、下载器、内存转储等工具。其中我最喜欢的是其中类似《模拟城市》加载显示。所以只要没有人仔细检查，你可以花一整个下午等待您的电脑完成进度条。Genact 发布了 支持 Linux、OS X 和 Windows 的版本。并且其 Rust 源代码 在 GitHub 上开源（遵循 MIT 许可证）。HollywoodHollywood 采取更直接的方法。它本质上是在终端中创建一个随机的数量和配置的分屏，并启动那些看起来很繁忙的应用程序，如 htop、目录树、源代码文件等，并每隔几秒将其切换。它被组织成一个 shell 脚本，所以可以非常容易地根据需求进行修改。Hollywood的 源代码 在 GitHub 上开源（遵循 Apache 2.0 许可证）。Blessed-contribBlessed-contrib 是我个人最喜欢的应用，实际上并不是为了这种表演而专门设计的应用。相反地，它是一个基于 Node.js 的终端仪表盘的构建库的演示文件。与其他两个不同，实际上我已经在工作中使用 Blessed-contrib 的库，而不是用于假装忙于工作。因为它是一个相当有用的库，并且可以使用一组在命令行显示信息的小部件。与此同时填充虚拟数据也很容易，所以可以很容易实现你在计算机上模拟《战争游戏》的想法。Blessed-contrib 的源代码在 GitHub 上（遵循 MIT 许可证）。当然，尽管这些工具很容易使用，但也有很多其他的方式使你的屏幕丰富。在你看到电影中最常用的工具之一就是Nmap，这是一个开源的网络安全扫描工具。实际上，它被广泛用作展示好莱坞电影中，黑客电脑屏幕上的工具。因此 Nmap 的开发者创建了一个 页面，列出了它出现在其中的一些电影，从《黑客帝国 2：重装上阵》到《谍影重重3》、《龙纹身的女孩》，甚至《虎胆龙威 4》。当然，您可以创建自己的组合，使用终端多路复用器（如 screen 或 tmux）启动您希望使用的任何数据切分程序。那么，您是如何使用您的屏幕的呢？

密码学及公钥基础设施入门
type: item
date: 2024-08-04T22:15:46+08:00
description: 学习密码学背后的基本概念，主要是保密性、完整性和身份认证。安全通信正快速成为当今互联网的规范。从 2018 年 7 月起，Google Chrome 将对全部使用 HTTP 传输（而不是 HTTPS 传输）的站点开始显示“不安全”警告。虽然密码学已经逐渐变广为人知，但其本身并没有变得更容易理解。Let's Encrypt 设计并实现了一套令人惊叹的解决方案，可以提供免费安全证书和周期性续签；但如果不了解底层概念和缺陷，你也不过是加入了类似“货物崇拜cargo cult”的技术崇拜的程序员大军。安全通信的特性密码学最直观明显的目标是保密性confidentiality：消息message传输过程中不会被窥探内容。为了保密性，我们对消息进行加密：对于给定消息，我们结合一个密钥key生成一个无意义的乱码，只有通过相同的密钥逆转加密过程（即解密过程）才能将其转换为可读的消息。假设我们有两个朋友 Alice 和 Bob，以及他们的八卦nosy邻居 Eve。Alice 加密类似 "Eve 很讨厌" 的消息，将其发送给 Bob，期间不用担心 Eve 会窥探到这条消息的内容。对于真正的安全通信，保密性是不够的。假如 Eve 收集了足够多 Alice 和 Bob 之间的消息，发现单词 “Eve” 被加密为 "Xyzzy"。除此之外，Eve 还知道 Alice 和 Bob 正在准备一个派对，Alice 会将访客名单发送给 Bob。如果 Eve 拦截了消息并将 “Xyzzy” 加到访客列表的末尾，那么她已经成功的破坏了这个派对。因此，Alice 和 Bob 需要他们之间的通信可以提供完整性integrity：消息应该不会被篡改。而且我们还有一个问题有待解决。假如 Eve 观察到 Bob 打开了标记为“来自 Alice”的信封，信封中包含一条来自 Alice 的消息“再买一加仑冰淇淋”。Eve 看到 Bob 外出，回家时带着冰淇淋，这样虽然 Eve 并不知道消息的完整内容，但她对消息有了大致的了解。Bob 将上述消息丢弃，但 Eve 找出了它并在下一周中的每一天都向 Bob 的邮箱中投递一封标记为“来自 Alice”的信封，内容拷贝自之前 Bob 丢弃的那封信。这样到了派对的时候，冰淇淋严重超量；派对当晚结束后，Bob 分发剩余的冰淇淋，Eve 带着免费的冰淇淋回到家。消息是加密的，完整性也没问题，但 Bob 被误导了，没有认出发信人的真实身份。身份认证Authentication这个特性用于保证你正在通信的人的确是其声称的那样。信息安全还有其它特性，但保密性、完整性和身份验证是你必须了解的三大特性。加密和加密算法加密都包含哪些部分呢？首先，需要一条消息，我们称之为明文plaintext。接着，需要对明文做一些格式上的初始化，以便用于后续的加密过程（例如，假如我们使用分组加密算法block cipher，需要在明文尾部填充使其达到特定长度）。下一步，需要一个保密的比特序列，我们称之为密钥key。然后，基于私钥，使用一种加密算法将明文转换为密文ciphertext。密文看上去像是随机噪声，只有通过相同的加密算法和相同的密钥（在后面提到的非对称加密算法情况下，是另一个数学上相关的密钥）才能恢复为明文。（LCTT 译注：cipher 一般被翻译为密码，但其具体表达的意思是加密算法，这里采用加密算法的翻译）加密算法使用密钥加密明文。考虑到希望能够解密密文，我们用到的加密算法也必须是可逆的reversible。作为简单示例，我们可以使用 XOR。该算子可逆，而且逆算子就是本身（P ^ K = C; C ^ K = P），故可同时用于加密和解密。该算子的平凡应用可以是一次性密码本one-time pad，不过一般而言并不可行。但可以将 XOR 与一个基于单个密钥生成任意随机数据流arbitrary stream of random data的函数结合起来。现代加密算法 AES 和 Chacha20 就是这么设计的。我们把加密和解密使用同一个密钥的加密算法称为对称加密算法symmetric cipher。对称加密算法分为流加密算法stream ciphers和分组加密算法两类。流加密算法依次对明文中的每个比特或字节进行加密。例如，我们上面提到的 XOR 加密算法就是一个流加密算法。流加密算法适用于明文长度未知的情形，例如数据从管道或 socket 传入。RC4 是最为人知的流加密算法，但在多种不同的攻击面前比较脆弱，以至于最新版本 （1.3）的 TLS （“HTTPS” 中的 “S”）已经不再支持该加密算法。Efforts 正着手创建新的加密算法，候选算法 ChaCha20 已经被 TLS 支持。分组加密算法对固定长度的分组，使用固定长度的密钥加密。在分组加密算法…