1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//! # Rail Fence Cipher Implementation
//!
//! The Rail Fence cipher is a classical transposition cipher that arranges the plaintext
//! in a zigzag pattern across multiple "rails" (rows), then reads off the ciphertext
//! by concatenating each rail. It's also known as the Zigzag cipher.
//!
//! ⚠️ **Security Warning**: The Rail Fence cipher is **not secure** for modern use and should
//! only be used for educational purposes or simple text obfuscation.
//!
//! ## How It Works
//!
//! 1. **Write**: Arrange plaintext in a zigzag pattern across N rails
//! 2. **Read**: Concatenate characters from each rail to form ciphertext
//! 3. **Decrypt**: Reverse the process by filling the zigzag pattern with ciphertext
//!
//! ## Example with 3 Rails
//!
//! Plaintext: "HELLO WORLD"
//! ```text
//! H O O D
//! E L W R L
//! L L
//! ```
//! Ciphertext: "HOOD" + "ELWRL" + "LL" = "HOODELWRLLL"
//!
//! ## Examples
//!
//! ```rust
//! use ruscrypt::classical::rail_fence;
//!
//! // Encrypt with 3 rails
//! let encrypted = rail_fence::encrypt("HELLO WORLD", 3).unwrap();
//! println!("Encrypted: {}", encrypted);
//!
//! // Decrypt with same number of rails
//! let decrypted = rail_fence::decrypt(&encrypted, 3).unwrap();
//! println!("Decrypted: {}", decrypted);
//! ```
use Result;
/// Encrypts text using the Rail Fence cipher algorithm.
///
/// Arranges the input text in a zigzag pattern across the specified number of rails,
/// then reads the text row by row to create the ciphertext.
///
/// # Arguments
///
/// * `text` - The plaintext to encrypt
/// * `rails` - Number of rails (rows) to use (must be ≥ 2)
///
/// # Returns
///
/// Returns the encrypted text as a `Result<String>`.
///
/// # Algorithm
///
/// 1. Create N empty strings for each rail
/// 2. Traverse the text, placing each character on the appropriate rail
/// 3. Use a direction indicator to create the zigzag pattern
/// 4. Concatenate all rails to form the ciphertext
///
/// # Zigzag Pattern
///
/// - Start at rail 0, move down
/// - When reaching the last rail, change direction to move up
/// - When reaching the first rail, change direction to move down
/// - Continue until all characters are placed
///
/// # Examples
///
/// ```rust
/// use ruscrypt::classical::rail_fence;
///
/// // With 3 rails: "HELLO" becomes "HOELL"
/// let result = rail_fence::encrypt("HELLO", 3).unwrap();
///
/// // With 2 rails: "HELLO" becomes "HLOEL"
/// let result2 = rail_fence::encrypt("HELLO", 2).unwrap();
/// ```
///
/// # Edge Cases
///
/// - If `rails < 2`, returns the original text unchanged
/// - Preserves all characters including spaces and punctuation
/// - Empty text returns empty string
/// Decrypts text encrypted with the Rail Fence cipher.
///
/// Reconstructs the zigzag pattern from the ciphertext by first determining
/// which positions characters should occupy, then filling those positions
/// with the ciphertext characters.
///
/// # Arguments
///
/// * `text` - The ciphertext to decrypt
/// * `rails` - Number of rails used during encryption
///
/// # Returns
///
/// Returns the decrypted text as a `Result<String>`.
///
/// # Algorithm
///
/// 1. Create a 2D grid to represent the rail fence
/// 2. Mark positions where characters should be placed (using '*')
/// 3. Fill marked positions with ciphertext characters row by row
/// 4. Read the grid in zigzag pattern to recover plaintext
///
/// # Grid Reconstruction
///
/// The function recreates the exact zigzag pattern used during encryption:
/// - Simulates the original character placement to mark positions
/// - Fills marked positions with ciphertext characters in rail order
/// - Reads back the filled grid following the same zigzag pattern
///
/// # Examples
///
/// ```rust
/// use ruscrypt::classical::rail_fence;
///
/// let encrypted = "HOELL";
/// let result = rail_fence::decrypt(encrypted, 3).unwrap();
/// assert_eq!(result, "HELLO");
/// ```
///
/// # Validation
///
/// The function assumes the ciphertext was properly encrypted with the
/// specified number of rails. Incorrect rail count will produce garbled output.
///
/// # Edge Cases
///
/// - If `rails < 2`, returns the original text unchanged
/// - Handles empty input gracefully
/// - Preserves character order and type from original text