↓ Skip to main content
Affine Cipher Analysis Tool Explained

Affine Cipher Analysis Tool Explained

·4075 words·9 mins· loading · loading ·
Author
Dawn Magnet
Tech enthusiast & daily solver.

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:

$$E(x) = (ax + b) \bmod 26$$

where:

  • a is the multiplication key, which must satisfy \(\gcd(a, 26) = 1\) (it must be coprime with 26)
  • b is the shift key, which can be any integer from 0 to 25
  • 26 is 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:

  1. Limited key space:

    • a has only \(\phi(26) = 12\) valid values (the numbers coprime with 26)
    • b has 26 valid values
    • There are only \(12 × 26 = 312\) possible key combinations
  2. Vulnerability to known-plaintext attacks: knowing only two plaintext-ciphertext character correspondences is enough to fully recover the key

  3. 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 a and b
  • ✅ 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
#

ParameterDescription
ciphertextThe ciphertext to decrypt
ciphertext_char_1The first known character in the ciphertext
plaintext_char_1The corresponding plaintext character
ciphertext_char_2The second known character in the ciphertext
plaintext_char_2The 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 l

Explanation:

  • 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:

$$a(x_1 - x_2) \equiv (c_1 - c_2) \pmod{26}$$
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:

  1. Brute-force every possible value of a (0–25)
  2. For each a, check whether the equation \(\mathrm{diff}_x \times a \equiv \mathrm{diff}_c \pmod{26}\) is satisfied
  3. Once a suitable a is found, calculate b from the first equation: \(b = c_1 - ax_1 \pmod{26}\)
  4. 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 Rust
  • rem_euclid always 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:

  1. Build an inverse mapping table: encrypted position → original position
  2. Traverse every character in the ciphertext
  3. For letters, use the inverse mapping table to look up the original position (an O(1) lookup)
  4. 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?
#

  1. Performance: compile to machine code with zero-cost abstractions, approaching C++ speed
  2. Safety:
    • A strong type system prevents type-related vulnerabilities
    • The ownership system eliminates memory problems
    • const fn supports compile-time computation, reducing runtime overhead
  3. Ease of use:
    • The clap library provides convenient CLI argument parsing
    • Concise syntax and powerful pattern matching
    • Helpful error messages and compiler diagnostics

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 platformArchitectureDescription
x86_64-unknown-linux-gnuLinux x86-64The most common server platform
x86_64-pc-windows-msvcWindows x86-64Uses the MSVC toolchain
x86_64-apple-darwinmacOS IntelIntel-based Mac
aarch64-apple-darwinmacOS SiliconApple Silicon M1/M2
aarch64-unknown-linux-gnuLinux ARM64Raspberry Pi and mobile devices
armv7-unknown-linux-gnueabihfLinux ARM32Embedded systems
x86_64-pc-windows-gnuWindows MinGWNo MSVC dependency
wasm32-unknown-unknownWebAssemblyBrowser 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?
#
ToolLinuxWindowsmacOSARMAdvantagesDisadvantages
GCC✅⚠️❌✅Broad supportCross-compilation is complex
MSVC❌✅❌❌Native Windows supportWindows only
Clang✅✅✅✅General-purpose and powerfulRequires multiple toolchains
Zig compiler✅✅✅✅One toolchain handles everythingEmerging 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-macos

Rust/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 --release

The 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-gnu

Key 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?

  1. Size: only a few hundred bytes are needed; a crypto library would add several MB
  2. Dependency chain: cryptography libraries commonly introduce 20+ indirect dependencies
  3. Simplicity: the mathematics of the affine cipher is simple enough that a self-contained implementation is clearer
  4. 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 --version
2. 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 x2

Comparison
#

Distribution methodDownload sizeDependenciesStartup time
Python script10KBRequires Python + libraries1–2 seconds
Node.js tool50KBRequires Node.js0.5 seconds
Java JAR5MBRequires JRE2–5 seconds
Rust binary3–5MBNone<50ms
Docker image100MB+Requires DockerSeveral seconds

Performance Benchmarks
#

Actual performance on modern hardware (for a 100KB ciphertext):

Linux x86-64:  12ms
macOS ARM64:   15ms
Windows AMD64: 13ms
ARM Linux:     18ms

Startup 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 w

2. 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?
#

  1. Polyalphabetic substitution: use different keys to encrypt letters at different positions
  2. Add noise: mix in fake punctuation and digits
  3. 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
#

  1. Cryptographic mathematics: linear congruences and modular arithmetic
  2. Cryptanalysis: the power of known-plaintext attacks
  3. Software design: efficient algorithms and data structures
  4. 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
#

  1. Container-friendly: no runtime needs to be preinstalled in the base image
  2. Cloud-native: fast cold starts, suitable for serverless workloads
  3. Edge computing: native ARM support with no additional dependencies
  4. Security: one binary means one auditable attack surface
  5. 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 明文字符2

Advantage: 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 x2

Use 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.exe

Advantage: 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 x2

Image 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
done

Parallel 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:

  1. Check that the input characters are correct
  2. Try other known character pairs
  3. 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
done

Q: Cross-platform compilation failed
#

Symptom: error: could not compile dependency

Solution:

# 清理旧的构建缓存
cargo clean

# 更新工具链
rustup update

# 指定特定目标后重试
cargo build --release --target x86_64-unknown-linux-gnu

Q: 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#

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.