news 2026/9/14 4:04:14

Flipper Zero 凯撒密码(Caesar Cipher)应用实战指南:算法原理、GUI 实现与 fbt 编译

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flipper Zero 凯撒密码(Caesar Cipher)应用实战指南:算法原理、GUI 实现与 fbt 编译

Flipper Zero 凯撒密码(Caesar Cipher)应用实战指南:算法原理、GUI 实现与 fbt 编译

【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper

本文以 Flipper 仓库中 grnch/caesarcipher 应用为核心,完整讲解这个运行在 Flipper Zero 屏幕上的凯撒密码移位器:从设备上的输入与输出操作流程,到caesar_cipher.c中的字符位移算法与双视图 GUI 架构,再到通过fbt构建 FAP 插件的完整方法。读完本文,你既能立刻上手使用该工具对任意文本做 25 种位移的暴力枚举,也能理解一个典型 Flipper 外部应用(External App)的代码组织方式。

一、这是什么:一个运行在 Flipper Zero 上的凯撒密码移位器

凯撒密码(Caesar Cipher)是最古老的替换式加密算法之一:明文中的每个字母沿字母表向后(或向前)移动固定位数 N,即得到密文。Flipper Zero 上的这款 Caesar Cipher 应用,正是把这一经典算法搬上了 128×64 的单色屏幕。

它位于仓库的 Applications/Official/source-OLDER/grnch/caesarcipher/ 目录下,作者在 README 中将其定位为:

A caesar cipher encoder for the Flipper Zero device.

需要特别说明的是它的实际工作方式:从源码实现看,它并非让你选择某个固定的位移数,而是一次性把输入文本按 rot = 1 到 25 的全部 25 种位移都算出来并逐行显示(详见下文"算法实现"一节)。这意味着:

  • 当你加密时,25 行输出中的每一行都是输入明文在某个密钥下的密文,你只需找到目标密钥那一行即可;
  • 当你解密时,无论密文用了哪个位移,由于 25 种可能密钥被全部枚举出来,人眼扫一眼即可挑出语义通顺的明文——这是一种朴素但有效的暴力破解方式。

README 将其描述为 encoder,同时在使用说明中又要求"输入你的密文(ciphertext)",二者并不矛盾:正是因为全量输出了 25 种位移,它天然就是一个加解密两用的"穷举移位器"。你可以在 ReadMe.md 中看到整个仓库对这种玩具/工具类 Flipper 应用的收录定位。

二、设备上的使用流程

原文档的使用说明非常精简,但它是操作的唯一权威依据,完整继承如下,并补充设备交互细节:

  1. 启动应用:在 Flipper Zero 上进入应用列表(该应用类别为 Misc,见后文application.fam),打开 Caesar Cipher。
  2. 输入文本:使用屏幕上的虚拟键盘(on-screen keyboard)逐字符输入你要处理的文本。上图中的第一张截图即为输入界面,顶部标题为Input,键盘布局为 qwerty 三行字母加数字行,并提供下划线_与回退删除键。
  3. 空格替换为下划线:由于屏幕键盘没有空格键,所有空格必须用下划线_代替。这是使用该应用最容易踩的坑——如果密文中含有空格,请先手动替换为_再输入。
  4. 按 Save 生成结果:输入完成后按下Save按钮,应用会立即计算 25 种位移并切换到输出界面。
  5. 滚动查看输出:输出界面(第二张截图)以多行文本展示结果,右侧有滚动条,可上下滚动逐行查看所有位移结果。

从应用内截图可以直观验证整个流程:输入Syucore_mreb_uf_njrfbzr(这是一段 ROT13 处理过的文本),输出列表中就出现了FLIPPER_ZERO_IS_AWESO...这样语义清晰的明文行——这正是 rot=13 那一行命中的结果。

三、核心算法实现源码解析

应用的全部逻辑都集中在一个单文件 caesar_cipher.c 中,算法部分由两个静态函数构成。

3.1 输入规范化:string_to_uppercase

static void string_to_uppercase(char* input) { int i; for(i = 0; input[i] != '\0'; i++) { if(input[i] >= 'a' && input[i] <= 'z') { input[i] = input[i] - 32; } else { input[i] = input[i]; } } }

这段代码(caesar_cipher.c)在生成输出前把输入中的全部小写字母转换为大写:ASCII 中小写字母比对应大写字母大 32,因此input[i] - 32即完成小写转大写。非字母字符原样保留。这一步保证了后续位移运算只需要处理AZ一个连续区间。

3.2 位移生成核心:build_output

static void build_output(char* input, char* output) { int out = 0; for(int rot = 1; rot < 26; rot++) { int in; for(in = 0; input[in] != '\0'; in++) { if(input[in] >= 'A' && input[in] <= 'Z') { output[out] = 65 + (((input[in] - 65) + rot) % 26); } else { output[out] = input[in]; } out++; } output[out] = '\n'; out++; } output[out] = '\0'; }

这段代码(caesar_cipher.c)是整个应用的计算核心,逐行拆解如下:

  • 外层循环rot从 1 遍历到 25,恰好覆盖凯撒密码全部 25 种非平凡位移(rot=0 等于原文,无意义,故被跳过)。
  • 内层循环逐字符处理输入:对于落在A(65) 到Z(90) 区间内的字母,执行65 + ((字符 - 65 + rot) % 26)的取模运算,实现字母环上的循环移位——加 26 后自然回绕到字母表开头(如Z位移 1 得到A)。
  • 非字母字符(下划线、数字、标点等)不做位移,原样复制到输出,这正是前面要求"空格用下划线代替"能在输出中保持语义可读的原因。
  • 行分隔:每一行位移结果末尾写入\n换行,最终以\0终止字符串。

由此,输入 N 个字符,输出即为25行、每行 N 个字符(加换行)的完整枚举。输出缓冲区的尺寸也因此被精心设计为char output[(TEXT_BUFFER_SIZE * 26) + (26)](caesar_cipher.c):25 行 × 每行最多 256 字符,加上每行 1 个换行与结尾的\0,即256×26 + 26,正好不越界。

3.3 关键输入约束

  • 输入缓冲区TEXT_BUFFER_SIZE定义为 256(caesar_cipher.c),即单次最多处理 255 个可见字符,超出部分会被截断。
  • 仅支持 ASCII 大写字母的位移,中文、带重音字母等均不在算法处理范围内(会原样保留在输出中)。
  • 由于是纯枚举输出,应用本身不涉及任何密钥选择、频率分析或自动判定明文——"哪一行是正确的"完全靠肉眼判断。

四、GUI 架构:TextInput + TextBox 双视图

该应用的界面层是理解 Flipper 官方 GUI 框架(gui模块)的一个极简范例。其状态结构如下:

typedef struct { ViewDispatcher* view_dispatcher; TextInput* text_input; TextBox* text_box; char input[TEXT_BUFFER_SIZE]; char output[(TEXT_BUFFER_SIZE * 26) + (26)]; // linebreaks } CaesarState;

(caesar_cipher.c)

应用采用典型的ViewDispatcher(视图调度器)架构,注册了两个视图:

视图 IDGUI 模块用途注册代码
0TextInput屏幕键盘输入caesar_cipher.c
1TextBox多行结果展示caesar_cipher.c

整个生命周期在入口函数caesar_cipher_app()(caesar_cipher.c)中完成,关键节点如下:

  1. 分配状态与互斥锁malloc一个CaesarState,并通过init_mutex创建值为该结构体的ValueMutex,用于保护跨视图共享的输入/输出缓冲区(失败时返回 255)。
  2. 注册输入回调text_input_set_result_callbacktext_input_callback绑定到 TextInput,同时传入状态互斥锁与输入缓冲区指针;text_input_set_header_text设置输入页标题为"Input"
  3. 获取 GUI 记录:通过furi_record_open("gui")打开系统 GUI 服务。
  4. 挂载视图调度器view_dispatcher_enable_queue启用事件队列,随后将两个视图注册到 dispatcher,并通过view_dispatcher_attach_to_gui(..., ViewDispatcherTypeFullscreen)以全屏方式挂载到 GUI。
  5. 事件回调back_event_callback响应返回键,调用view_dispatcher_stop结束事件循环;text_input_callback则承担真正的"计算+跳转"职责。
  6. 启动与清理view_dispatcher_run进入事件循环;退出后依次关闭 GUI 记录、删除互斥锁、释放视图与状态内存。

其中最关键的是回调函数text_input_callback(caesar_cipher.c),它在用户按下 Save 后被触发,执行完整的数据流:

static void text_input_callback(void* ctx) { CaesarState* caesar_state = acquire_mutex((ValueMutex*)ctx, 25); FURI_LOG_D("caesar_cipher", "Input text: %s", caesar_state->input); // this is where we build the output. string_to_uppercase(caesar_state->input); FURI_LOG_D("caesar_cipher", "Upper text: %s", caesar_state->input); build_output(caesar_state->input, caesar_state->output); text_box_set_text(caesar_state->text_box, caesar_state->output); view_dispatcher_switch_to_view(caesar_state->view_dispatcher, 1); release_mutex((ValueMutex*)ctx, caesar_state); }

即:加锁 → 获取输入 → 转大写 → 枚举 25 种位移 → 把结果文本设置进 TextBox → 切换到视图 1 → 解锁。其中FURI_LOG_D会通过 USB/蓝牙串口输出调试日志(Input text:Upper text:),便于在开发阶段观察数据流。text_box_set_font(..., TextBoxFontText)在初始化时被调用(caesar_cipher.c),保证输出使用等宽文本字体以对齐每一行。

五、应用元数据:application.fam

Flipper 官方 SDK 使用.fam(Flipper Application Manifest)文件声明应用构建信息,本应用的 application.fam 内容如下:

App( appid="Caesar_Cipher", name="Caesar Cipher", apptype=FlipperAppType.EXTERNAL, entry_point="caesar_cipher_app", cdefines=["APP_CAESAR_CIPHER"], requires=[ "gui", ], stack_size=2 * 1024, fap_icon="caesar_cipher_icon.png", fap_category="Misc", order=20, )

各字段含义与影响:

  • apptype=FlipperAppType.EXTERNAL:声明这是一个外部应用(FAP,Flipper Application Package),以.fap文件形式分发,运行在独立的用户空间进程中,无需刷入固件。
  • entry_point="caesar_cipher_app":指定应用入口函数,与源码中的int32_t caesar_cipher_app()一一对应。
  • requires=["gui"]:声明依赖 GUI 系统服务,对应源码中furi_record_open("gui")的使用。
  • stack_size=2 * 1024:为该应用分配 2 KB 任务栈空间。这个数值对仅有少量局部数组和循环的应用足够;如果未来把TEXT_BUFFER_SIZE大幅调大并在栈上放置大数组,则需要同步考虑增加该值。
  • fap_category="Misc":决定应用在 Flipper 应用菜单中的分类归属,因此启动应用时应在"杂项"类别下查找。
  • fap_icon="caesar_cipher_icon.png":指定应用图标,即同目录下的 caesar_cipher_icon.png。
  • order=20:影响应用在同类列表中的排序位置。
  • cdefines=["APP_CAESAR_CIPHER"]:编译期宏定义,可用于条件编译。

六、编译与构建

在 Flipper Zero 官方固件 SDK 环境中,编译本应用只需在固件仓库根目录执行:

./fbt firmware_caesar_cipher

该命令(源自 README.md 的 Compiling 一节)由 Flipper 的构建工具fbt(Flipper Build Tool)执行。由于apptype为 EXTERNAL,构建产物是一个独立.fap文件;将其拷贝到 Flipper Zero 的 SD 卡对应应用目录后,即可在设备菜单中启动。仓库中同属 grnch 系列的 minesweeper、tuning_fork 等应用也沿用了./fbt firmware_<app>的同类构建约定,可作为交叉参考。

七、限制与可扩展方向

基于对源码的分析,可以总结出该应用当前的设计边界,这也是未来二次开发(fork)时最值得动手的地方:

  • 纯枚举、无智能识别:25 行输出全部交给肉眼筛选,不提供频率分析或词典匹配来自动标出最可能的明文;
  • 输入约束多:空格必须替换为_、仅支持大写 ASCII 字母、单次输入上限 255 字符,交互体验仍显"痛苦"(README 原话是 "painfully input your ciphertext");
  • 无密钥选择功能:不能指定固定 rot 只输出一行,也不能直接进行"解密方向"(即-rot)的定向换算——虽然 25 行全量枚举在功能上已覆盖所有情况。

如果要在此之上做增强,可从三处入手:在build_output中增加 rot 选择与反向位移分支;在 GUI 层引入更多视图(如结果行选择与复制);或为TEXT_BUFFER_SIZE提供运行时可调能力并同步调整输出缓冲区尺寸公式。

八、小结

Caesar Cipher 应用麻雀虽小,五脏俱全:它完整展示了 Flipper Zero 外部应用从"屏幕键盘取输入 → 核心算法处理 → 多行文本展示"的典型数据流,覆盖了furi记录系统、ValueMutex互斥、ViewDispatcher双视图调度、TextInput/TextBoxGUI 模块,以及application.fam元数据声明与fbt构建这一整条开发链路。无论你是想在设备上快速破解一段经典凯撒密文,还是想以此为模板编写自己的第一个 Flipper 应用,这份源码与本文的对照分析都是很好的起点。

【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 4:02:26

DeepSeek V4.1 Flash部署实战:显存估算与vLLM/SGLang启动命令详解

DeepSeek V4.1 Flash 发布之后&#xff0c;我周围做推理部署的朋友几乎都在问同一件事&#xff1a;这玩意到底要多大显存&#xff0c;vLLM 和 SGLang 到底怎么起服务。说实话&#xff0c;显存算错一步&#xff0c;模型起都起不来&#xff1b;命令抄错一个参数&#xff0c;服务起…

作者头像 李华
网站建设 2026/9/14 4:01:58

GEO优化五大误区:为何你的内容不被AI引用?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 4:00:17

微信聊天记录导出:三步跑通本地的完整指南

微信聊天记录导出&#xff1a;三步跑通本地的完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg 换…

作者头像 李华
网站建设 2026/9/14 4:00:15

Linux守护进程完全指南:从SIGHUP到systemd的进程管理实战

你有没有遇到过这种情况&#xff1a;通过 SSH 登录服务器&#xff0c;启动一个服务&#xff0c;测试一下功能&#xff0c;一切正常&#xff0c;网络也能通。结果一关掉终端&#xff0c;再访问服务&#xff0c;发现它挂了。重新登录一看&#xff0c;进程没了&#xff0c;日志里只…

作者头像 李华
网站建设 2026/9/14 4:00:11

ROS2零基础保姆级教程:从环境搭建到SLAM导航全流程

大一新生最容易踩的坑&#xff0c;就是看见“ROS2”三个字母就发怵&#xff0c;觉得这是研究生或者工程师才能碰的东西。实际上&#xff0c;ROS2并没有想象中那么高不可攀&#xff0c;它本质上就是一套帮机器人开发者省事的“软件拼装工具箱”。你不需要先精通Linux内核&#x…

作者头像 李华
网站建设 2026/9/14 3:59:32

海洋锚系建模与仿真:从集中质量法到数字孪生

简介&#xff1a;本资源是一款面向海洋工程与结构设计领域的MATLAB锚系计算工具包&#xff0c;专为从事海上平台、浮式风电、FPSO等项目的设计工程师及高校相关专业研究生开发&#xff0c;解决锚型选型、系泊系统受力分析、动态响应模拟等核心工程问题。压缩包共174个文件&…

作者头像 李华