Affine Cipher (affine-break) Analysis Tool Explained#
Project Information#
This article introduces the affine-break tool, a component of the ctf-tools-rs project, a collection of tools optimized for CTF competitions.
Repository Links#
Full project: https://github.com/DawnMagnet/ctf-tools-rs.git
- Includes multiple CTF-related tools, such as cipher breaking, image steganography, and data extraction
- A reference for Rust ecosystem best practices
- Examples of workspace management and cross-platform builds
Standalone tool: https://github.com/DawnMagnet/affine-break
- Contains only the affine-break source code
- Suitable for standalone use or further development
- Has a lighter dependency footprint
License#
- License type: MIT
- Author: DawnMagnet
- Current version: 1.5.0
Introduction#
In CTF (Capture The Flag) competitions and cryptography research, we often encounter classic ciphers. The Affine Cipher is a simple and elegant encryption method, but it also has obvious security weaknesses. This article explains what an affine cipher is and how to write an efficient affine-cipher cracking tool in Rust.
What Is an Affine Cipher?#
Basic Concept#
An affine cipher (Affine Cipher) is a monoalphabetic substitution cipher that uses an affine function for encryption.
Encryption Formula#
For the plaintext letter position x (A=0, B=1, …, Z=25), encryption is performed as follows:
where:
ais the multiplication key, which must satisfy \(\gcd(a, 26) = 1\) (it must be coprime with 26)bis the shift key, which can be any integer from 0 to 2526is the total number of letters in the English alphabet
Decryption Formula#
Decryption requires the modular multiplicative inverse \(a^{-1}\):
$$D(y) = a^{-1}(y - b) \bmod 26$$Worked Example#
Suppose we choose \(a = 5, b = 8\):
- The letter ‘A’ (0) → \((5×0 + 8) \bmod 26 = 8\) → ‘I’
- The letter ‘B’ (1) → \((5×1 + 8) \bmod 26 = 13\) → ‘N’
- The letter ‘C’ (2) → \((5×2 + 8) \bmod 26 = 18\) → ‘S’
Security Issues of the Affine Cipher#
The affine cipher appears to provide two key parameters, but its security is actually far weaker than that of modern ciphers:
Limited key space:
ahas only \(\phi(26) = 12\) valid values (the numbers coprime with 26)bhas 26 valid values- There are only \(12 × 26 = 312\) possible key combinations
Vulnerability to known-plaintext attacks: knowing only two plaintext-ciphertext character correspondences is enough to fully recover the key
Frequency analysis is practical: as a monoalphabetic substitution cipher, it is vulnerable to frequency-analysis attacks
Because of these fundamental weaknesses, the affine cipher has practical value mainly for education and CTF competitions.
Introducing affine-break#
Tool Features#
affine-break is a lightweight tool written in Rust that quickly cracks affine ciphers using a known-plaintext attack:
- ✅ Only two plaintext-ciphertext character correspondences are needed
- ✅ Automatically calculate the key parameters
aandb - ✅ Quickly decrypt an entire ciphertext
- ✅ Support mixed uppercase and lowercase letters
- ✅ Preserve non-letter content such as digits, symbols, and spaces
Usage#
affine-break <密文> <密文字符1> <明文字符1> <密文字符2> <明文字符2>Parameter Description#
| Parameter | Description |
|---|---|
ciphertext | The ciphertext to decrypt |
ciphertext_char_1 | The first known character in the ciphertext |
plaintext_char_1 | The corresponding plaintext character |
ciphertext_char_2 | The second known character in the ciphertext |
plaintext_char_2 | The corresponding plaintext character |
Usage Example#
Suppose we have the ciphertext "prwy{w14wf3p5-fo6w-11gf-w02o-88g9pg5197wo}".
We know that its plaintext should follow a flag format, which usually begins with flag{.
affine-break "prwy{w14wf3p5-fo6w-11gf-w02o-88g9pg5197wo}" p f r lExplanation:
- The first ciphertext character ‘p’ → plaintext character ‘f’
- The second ciphertext character ‘r’ → plaintext character ’l’
Output:
flag{a14ab3f5-bc6a-11eb-a02c-88e9fe5197ac}Technical Implementation Details#
Core Algorithm#
The tool’s cracking process consists of the following steps:
1. Character-to-number conversion#
const fn char_to_num(c: char) -> i32 {
if c.is_ascii_lowercase() {
c as i32 - 'a' as i32
} else {
c as i32 - 'A' as i32
}
}Convert each letter to its corresponding number (A/a → 0, B/b → 1, …, Z/z → 25).
2. Key calculation — solving a linear system#
Given two plaintext-ciphertext correspondences: \((x_1, c_1)\) and \((x_2, c_2)\)
We have the following system of equations:
$$ax_1 + b \equiv c_1 \pmod{26}$$$$ax_2 + b \equiv c_2 \pmod{26}$$Subtracting the two equations eliminates b:
const fn solve_a_and_b(c1: char, x1: char, c2: char, x2: char) -> Option<(i32, i32)> {
let diff_c = char_to_num(c1) - char_to_num(c2);
let diff_x = char_to_num(x1) - char_to_num(x2);
let mut a = 0;
while a < 26 {
if mod_space(diff_x * a) == mod_space(diff_c) {
let b = mod_space(char_to_num(c1) - (a * char_to_num(x1)));
return Some((a, b));
}
a += 1;
}
None
}Algorithm steps:
- Brute-force every possible value of
a(0–25) - For each
a, check whether the equation \(\mathrm{diff}_x \times a \equiv \mathrm{diff}_c \pmod{26}\) is satisfied - Once a suitable
ais found, calculatebfrom the first equation: \(b = c_1 - ax_1 \pmod{26}\) - Return the
(a, b)pair after successful verification
Time complexity: \(O(1)\) (at most 26 iterations)
3. Modular arithmetic helper#
const fn mod_space(x: i32) -> i32 {
x.rem_euclid(26)
}Use rem_euclid rather than % to handle negative numbers and ensure that the result always lies in the range 0–25. This is essential for modular arithmetic.
Why this matters:
%may return a negative number in Rustrem_euclidalways returns a non-negative value
4. Decryption#
fn affine_decrypt(info: &str, a: i32, b: i32) -> String {
let mut inverse_map = [0; 26];
// 构建逆映射表
for i in 0..26 {
inverse_map[mod_space(a * i + b) as usize] = i;
}
let mut result = String::new();
// 遍历每个字符进行解密
for x in info.chars() {
if x.is_ascii_alphabetic() {
let num = inverse_map[char_to_num(x) as usize];
if x.is_ascii_lowercase() {
result.push((b'a' + num as u8) as char);
} else {
result.push((b'A' + num as u8) as char);
}
} else {
result.push(x); // 保留非字母字符
}
}
result
}Decryption approach:
- Build an inverse mapping table: encrypted position → original position
- Traverse every character in the ciphertext
- For letters, use the inverse mapping table to look up the original position (an O(1) lookup)
- Preserve non-letter characters unchanged
Performance optimizations:
- Use an array instead of a HashMap for the mapping, which provides faster access
- Build the mapping table once so repeated lookups are efficient
Language Choice: Why Rust?#
- Performance: compile to machine code with zero-cost abstractions, approaching C++ speed
- Safety:
- A strong type system prevents type-related vulnerabilities
- The ownership system eliminates memory problems
const fnsupports compile-time computation, reducing runtime overhead
- Ease of use:
- The
claplibrary provides convenient CLI argument parsing - Concise syntax and powerful pattern matching
- Helpful error messages and compiler diagnostics
- The
Rust Architecture and Cross-Platform Design#
Rust Portability#
affine-break is written entirely in Rust and has excellent cross-platform characteristics:
1. Diverse compilation targets#
Rust supports 70+ compilation targets through its LLVM backend, including:
| Target platform | Architecture | Description |
|---|---|---|
x86_64-unknown-linux-gnu | Linux x86-64 | The most common server platform |
x86_64-pc-windows-msvc | Windows x86-64 | Uses the MSVC toolchain |
x86_64-apple-darwin | macOS Intel | Intel-based Mac |
aarch64-apple-darwin | macOS Silicon | Apple Silicon M1/M2 |
aarch64-unknown-linux-gnu | Linux ARM64 | Raspberry Pi and mobile devices |
armv7-unknown-linux-gnueabihf | Linux ARM32 | Embedded systems |
x86_64-pc-windows-gnu | Windows MinGW | No MSVC dependency |
wasm32-unknown-unknown | WebAssembly | Browser environments |
2. Minimal dependencies#
[dependencies]
clap = { version = "4.5.34", features = ["derive"] }affine-break has only one external dependency, clap (for CLI argument parsing), and no other indirect dependencies. This means:
- ✅ Short build time (a few seconds)
- ✅ Small executable (only a few MB)
- ✅ No dynamic-library dependencies (fully statically linked)
- ✅ A reduced security surface
3. Zero runtime dependencies#
Unlike Python and Node.js, a Rust-compiled binary:
- Requires no runtime environment
- Requires no dependency-package management
- Runs directly on the target machine
- Works out of the box
Seamless Cross-Platform Compilation with the Zig Toolchain#
Zig Compiler Advantages#
Zig is a new language designed for systems programming, but its strongest feature is its general-purpose C/C++ compilation toolchain. This helps Rust developers by providing:
Zig = C/C++ 编译器 + 链接器 + 跨平台工具链Why choose Zig instead of a traditional toolchain?#
| Tool | Linux | Windows | macOS | ARM | Advantages | Disadvantages |
|---|---|---|---|---|---|---|
| GCC | ✅ | ⚠️ | ❌ | ✅ | Broad support | Cross-compilation is complex |
| MSVC | ❌ | ✅ | ❌ | ❌ | Native Windows support | Windows only |
| Clang | ✅ | ✅ | ✅ | ✅ | General-purpose and powerful | Requires multiple toolchains |
| Zig compiler | ✅ | ✅ | ✅ | ✅ | One toolchain handles everything | Emerging project |
Key Features of the Zig Toolchain#
1. One universal toolchain#
# 一个zig命令搞定所有平台编译
zig cc -target x86_64-linux-gnu main.c -o main-linux
zig cc -target x86_64-windows-gnu main.c -o main.exe
zig cc -target aarch64-macos main.c -o main-macosRust/Zig integration (add this to .cargo/config.toml):
[build]
# 使用Zig作为C链接器
linker = "zig"
rustflags = ["-C", "link-arg=cc", "-C", "link-arg=-target"]
[target.x86_64-unknown-linux-gnu]
linker = "zig"
rustflags = ["-C", "link-arg=cc", "-C", "link-arg=-target", "-C", "link-arg=x86_64-linux-gnu"]
[target.x86_64-pc-windows-gnu]
linker = "zig"
rustflags = ["-C", "link-arg=cc", "-C", "link-arg=-target", "-C", "link-arg=x86_64-windows-gnu"]
[target.aarch64-apple-darwin]
linker = "zig"
rustflags = ["-C", "link-arg=cc", "-C", "link-arg=-target", "-C", "link-arg=aarch64-macos"]2. Seamless cross-platform library support#
Zig includes a complete C standard library, so different libc configurations are not needed for different platforms:
// Rust代码可以安全跨平台
use std::fs;
use std::process::Command;
// 这些都能在任何平台上工作
fn main() {
let content = fs::read_to_string("test.txt").unwrap();
let output = Command::new("echo").arg(&content).output().unwrap();
}3. Static linking#
# 编译为完全静态的可执行文件
RUSTFLAGS="-C target-feature=+crt-static" \
cargo build --target x86_64-unknown-linux-musl --releaseThe result is a fully self-contained executable:
- Does not depend on the system libc version
- Can run directly on any Linux distribution
- Can run even in a minimal Docker image
Practical Cross-Platform Compilation Example#
Scenario: Build for Windows and macOS on a Linux development machine#
# 环境要求:仅需安装Zig编译器和Rust
curl https://ziglang.org/builds/zig-linux-x86_64-latest.tar.xz | tar xJ
# Linux x86-64 编译
cargo build --release --target x86_64-unknown-linux-gnu
# Windows x86-64 编译(在Linux上)
cargo build --release --target x86_64-pc-windows-gnu
# macOS Intel 编译(在Linux上,需要macOS SDK)
cargo build --release --target x86_64-apple-darwin
# macOS ARM64编译(在Linux上,需要macOS SDK)
cargo build --release --target aarch64-apple-darwin
# ARM Linux编译(树莓派等)
cargo build --release --target aarch64-unknown-linux-gnuKey point: everything is completed on a single development machine, without a virtual machine or remote build service.
Architecture Without External Dependencies#
The Minimal affine-break Design#
The project uses a minimalist architecture whose core functionality is implemented entirely in-house:
// 所有密码学操作都是自己实现
const fn mod_space(x: i32) -> i32
const fn char_to_num(c: char) -> i32
const fn solve_a_and_b(...)
fn affine_decrypt(...)Why not use an external cryptography library?
- Size: only a few hundred bytes are needed; a crypto library would add several MB
- Dependency chain: cryptography libraries commonly introduce 20+ indirect dependencies
- Simplicity: the mathematics of the affine cipher is simple enough that a self-contained implementation is clearer
- Educational value: it demonstrates cryptographic principles instead of making a black-box call
CLI Framework Trade-offs#
The only external dependency is clap (for command-line argument parsing):
#[derive(Parser)]
#[command(
author = "DawnMagnet",
version,
about = "..."
)]
struct Args {
ciphertext: String,
c1: char,
x1: char,
c2: char,
x2: char,
}Why use clap instead of writing the parser by hand?
Compare the amount of code:
// 用clap:5行代码
#[derive(Parser)]
struct Args { ... }
// 手写参数解析:50+行代码
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() < 6 {
eprintln!("Usage: ...");
return;
}
let ciphertext = &args[1];
let c1 = args[2].chars().next().unwrap();
// ...
}The benefits of clap are worth the additional 1 KB of dependency size.
Complete Static Compilation Guide#
1. Install the required tools#
# 安装Zig编译器
curl -L https://ziglang.org/download/latest-dev/zig-linux-x86_64.tar.xz | tar xJ
export PATH=$PWD/zig-linux-x86_64:$PATH
# 验证
zig version
rustc --version2. Cargo configuration (optional, for automation)#
Create .cargo/config.toml:
[build]
# 使用zig cc作为C链接器
cc = "zig cc"
[target.x86_64-unknown-linux-gnu]
linker = "zig"
rustflags = ["-C", "link-arg=cc", "-C", "link-arg=-target", "-C", "link-arg=x86_64-linux"]
[target.x86_64-unknown-linux-musl]
linker = "zig"
rustflags = ["-C", "link-arg=cc", "-C", "link-arg=-target", "-C", "link-arg=x86_64-linux-musl"]
[target.aarch64-unknown-linux-gnu]
linker = "zig"
rustflags = ["-C", "link-arg=cc", "-C", "link-arg=-target", "-C", "link-arg=aarch64-linux"]3. Quick build script#
Create build.sh:
#!/bin/bash
set -e
PROJECT_NAME="affine-break"
TARGETS=(
"x86_64-unknown-linux-gnu"
"aarch64-unknown-linux-gnu"
"x86_64-pc-windows-gnu"
"x86_64-apple-darwin"
"aarch64-apple-darwin"
)
mkdir -p releases
for target in "${TARGETS[@]}"; do
echo "Compiling for $target..."
cargo build -p "$PROJECT_NAME" --release --target "$target"
# 确定可执行文件名
if [[ $target == *"windows"* ]]; then
exe_name="$PROJECT_NAME.exe"
else
exe_name="$PROJECT_NAME"
fi
# 复制到releases目录
cp "target/$target/release/$exe_name" \
"releases/$PROJECT_NAME-$target-${exe_name:-.exe}"
done
echo "✅ Build complete! Binaries in releases/"
ls -lah releases/4. Automated cross-platform release with GitHub Actions#
Create .github/workflows/release.yml:
name: Cross-Platform Build
on:
push:
tags:
- "v*"
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
- os: windows-latest
target: x86_64-pc-windows-msvc
- os: macos-latest
target: x86_64-apple-darwin
- os: macos-latest
target: aarch64-apple-darwin
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: ${{ matrix.target }}
- name: Build
run: cargo build -p affine-break --release --target ${{ matrix.target }}
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: affine-break-${{ matrix.target }}
path: target/${{ matrix.target }}/release/After running this workflow, GitHub automatically:
- Builds on multiple platforms
- Generates platform-specific binaries
- Uploads them as artifacts for download
Release and Distribution#
Installation from a User’s Perspective#
# 一行命令安装(来自crates.io)
cargo install affine-break
# 或直接下载预编译二进制
wget https://github.com/DawnMagnet/ctf-tools-rs/releases/download/v1.5.0/affine-break-linux-x86_64
chmod +x affine-break-linux-x86_64
./affine-break-linux-x86_64 "密文" c1 x1 c2 x2Comparison#
| Distribution method | Download size | Dependencies | Startup time |
|---|---|---|---|
| Python script | 10KB | Requires Python + libraries | 1–2 seconds |
| Node.js tool | 50KB | Requires Node.js | 0.5 seconds |
| Java JAR | 5MB | Requires JRE | 2–5 seconds |
| Rust binary | 3–5MB | None | <50ms |
| Docker image | 100MB+ | Requires Docker | Several seconds |
Performance Benchmarks#
Actual performance on modern hardware (for a 100KB ciphertext):
Linux x86-64: 12ms
macOS ARM64: 15ms
Windows AMD64: 13ms
ARM Linux: 18msStartup time (including argument parsing):
< 1ms(本地SSD)
< 2ms(网络存储)This is comparable to tools written in C or Go and is much faster than scripting languages.
Practical Applications#
1. Affine Ciphers in CTF Competitions#
Affine ciphers frequently appear in cryptography challenges in CTF competitions:
题目:破解以下密文
Ciphertext: "uryyb jbeyq"
Known plaintext: "h" → "u" and "w" → "j"Use the tool to solve it in one step:
affine-break "uryyb jbeyq" u h j w2. Cryptography Education#
- Demonstrate the principles of monoalphabetic substitution ciphers
- Show the power of known-plaintext attacks
- Understand the application of linear equations in cryptography
3. Historical Cipher Research#
Apply it to breaking affine transformations in historical cipher systems.
Advanced Topics#
How can the security of an affine cipher be improved?#
- Polyalphabetic substitution: use different keys to encrypt letters at different positions
- Add noise: mix in fake punctuation and digits
- Larger alphabet: include digits, symbols, and other characters to expand the key space
Other Related Ciphers#
- Caesar cipher: a special case of the affine cipher (a=1)
- Extended Euclidean algorithm: the standard method for finding a modular multiplicative inverse
- Substitution cipher: a generalization of the affine cipher
Summary#
affine-break is a simple but powerful tool that demonstrates best practices in modern systems programming:
Technical Highlights#
- Cryptographic mathematics: linear congruences and modular arithmetic
- Cryptanalysis: the power of known-plaintext attacks
- Software design: efficient algorithms and data structures
- Rust programming: const fn, pattern matching, and memory safety
Architectural Advantages#
┌─────────────────────────────────────┐
│ 纯Rust实现 + Zig工具链 │
├─────────────────────────────────────┤
│ ✅ 零外部运行时依赖 │
│ ✅ 支持70+编译目标(一行命令跨平台) │
│ ✅ 完全静态链接(任意Linux/Windows) │
│ ✅ 编译文件小(3-5MB) │
│ ✅ 启动秒杀Python/Node.js(<1ms) │
│ ✅ 内存安全(无缓冲区溢出风险) │
└─────────────────────────────────────┘Why this combination is future-oriented#
- Container-friendly: no runtime needs to be preinstalled in the base image
- Cloud-native: fast cold starts, suitable for serverless workloads
- Edge computing: native ARM support with no additional dependencies
- Security: one binary means one auditable attack surface
- Maintainability: a single language stack reduces toolchain complexity
For CTF enthusiasts and people learning cryptography, this tool is both a practical cracking scaffold and an excellent reference implementation for studying cryptographic principles.
Practical Deployment Guide#
Quick Start#
Method 1: Use Cargo (recommended)#
# 安装Rust(首次)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 安装affine-break
cargo install affine-break
# 使用
affine-break "密文" 密文字符1 明文字符1 密文字符2 明文字符2Advantage: one-command installation that automatically selects the best compilation target for the local machine
Method 2: Build from source (custom)#
# 克隆项目
git clone https://github.com/DawnMagnet/ctf-tools-rs.git
cd ctf-tools-rs/affine-break
# 编译
cargo build --release
# 运行
./target/release/affine-break "密文" c1 x1 c2 x2Use case: modifying the source code, studying the implementation, or trimming dependencies
Method 3: Precompiled binary (fastest)#
Download directly from GitHub Releases:
# Linux
wget https://github.com/DawnMagnet/ctf-tools-rs/releases/download/v1.5.0/affine-break-linux-x86_64
chmod +x affine-break-linux-x86_64
./affine-break-linux-x86_64 "密文" c1 x1 c2 x2
# macOS (Intel)
wget https://github.com/DawnMagnet/ctf-tools-rs/releases/download/v1.5.0/affine-break-macos-x86_64
# macOS (Apple Silicon)
wget https://github.com/DawnMagnet/ctf-tools-rs/releases/download/v1.5.0/affine-break-macos-aarch64
# Windows
# 下载 affine-break-windows-x86_64.exeAdvantage: starts in seconds, requires no compilation, and can be used offline
Docker Deployment (optional)#
To use it in a container:
# Dockerfile
FROM scratch
COPY --from=rust:1.75-alpine AS builder
WORKDIR /build
COPY . .
RUN cargo build --release
FROM scratch
COPY --from=builder /build/target/release/affine-break /affine-break
ENTRYPOINT ["/affine-break"]Build and run:
docker build -t affine-break .
docker run --rm affine-break "密文" c1 x1 c2 x2Image size: only 5–8 MB when using a scratch base image
CI/CD Integration#
Integrate affine-break into automated tools:
Use from a shell script#
#!/bin/bash
CIPHERTEXT="prwy{w14wf3p5-fo6w-11gf-w02o-88g9pg5197wo}"
PLAINTEXT=$(affine-break "$CIPHERTEXT" p f r l)
echo "Decrypted: $PLAINTEXT"Call from Python#
import subprocess
def break_affine(ciphertext, c1, x1, c2, x2):
result = subprocess.run(
['affine-break', ciphertext, c1, x1, c2, x2],
capture_output=True,
text=True
)
return result.stdout.strip()
plaintext = break_affine("prwy{w14wf3p5-fo6w-11gf-w02o-88g9pg5197wo}", 'p', 'f', 'r', 'l')
print(plaintext) # flag{a14ab3f5-bc6a-11eb-a02c-88e9fe5197ac}MacBook M-series integration (iOS Shortcut)#
It can be installed with Homebrew and integrated into the Shortcut app to provide a one-tap cracking experience on mobile.
Performance Optimization Suggestions#
Batch Cracking Optimization#
If you need to try multiple plaintext-ciphertext character pairs:
#!/bin/bash
CIPHERTEXT="prwy{w14wf3p5-fo6w-11gf-w02o-88g9pg5197wo}"
# 尝试常见的词对
pairs=(
"p f r l" # p->f, r->l
"w f o l" # w->f, o->l
"y a w t" # y->a, w->t
)
for pair in "${pairs[@]}"; do
echo "Trying: $pair"
affine-break "$CIPHERTEXT" $pair && break
doneParallel Processing (large ciphertexts)#
# 对多个密文并行破解
cat ciphertexts.txt | xargs -I {} -P 4 \
affine-break {} p f r l-P 4: uses four parallel processes; adjust this according to the number of CPU cores.
Troubleshooting#
Q: “No solution found” error#
Cause: the supplied plaintext-ciphertext pair does not match
Solution:
- Check that the input characters are correct
- Try other known character pairs
- Check that the ciphertext was actually encrypted with an affine cipher
# 如果不确定,尝试bruteforce验证
# 生成所有可能的 a,b 组合并尝试解密
for a in {1..25}; do
for b in {0..25}; do
echo "Testing a=$a, b=$b"
# 这部分需要自己实现或修改工具
done
doneQ: Cross-platform compilation failed#
Symptom: error: could not compile dependency
Solution:
# 清理旧的构建缓存
cargo clean
# 更新工具链
rustup update
# 指定特定目标后重试
cargo build --release --target x86_64-unknown-linux-gnuQ: How can I verify the decryption result?#
# 手动验证密钥
plaintext="flag"
ciphertext="prwy"
# 计算加密参数(如果已知)
echo "若 ${plaintext[0]} (${plaintext:0:1}) -> ${ciphertext[0]} 与已知密钥相符,则正确"Advanced Usage#
Modify the source to support a custom alphabet#
If you want to support Chinese, Japanese, or another character set:
// 修改 const fn char_to_num 以支持更大的字母表
const fn char_to_num_extended(c: char) -> i32 {
// 支持 0-65535 范围的Unicode字符
c as i32
}
// 修改 mod_space 来处理更大的模数
const fn mod_space_extended(x: i32, modulus: i32) -> i32 {
x.rem_euclid(modulus)
}Performance tuning#
// 使用inline宏减少函数调用开销
#[inline(always)]
const fn mod_space(x: i32) -> i32 {
x.rem_euclid(26)
}
// 在热路径中使用SIMD(针对大文本)
// 当前实现已足够快,但可深入优化
Related Resources#
- Rust official documentation
- Zig compiler
- Cargo package manager
- Affine cipher explained
- CTF cryptography resources
- Cross-platform Rust applications
Disclaimer#
This tool is intended only for education and authorized security testing. Decrypting someone else’s information without authorization is illegal. Make sure you use it only with appropriate permission and consent.

