bacon_cipher/codecs/
char_codec.rs

1// Copyright 2019 astonbitecode
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14use std::marker::PhantomData;
15
16use crate::BaconCodec;
17
18#[derive(PartialEq, Clone)]
19/// A codec that encodes data of type `char`.
20///
21/// The encoding is done by substituting with two given elements (`elem_a` and `elem_b`) of type `T`.
22///
23/// The substitution is done using the __first__ version of the Bacon's cipher.
24pub struct CharCodec<T> {
25    pd: PhantomData<char>,
26    elem_a: T,
27    elem_b: T,
28}
29
30impl<T> CharCodec<T> {
31    /// Create a new `CharCodec` using elements `elem_a` and `elem_b` for substitution.
32    pub fn new(elem_a: T, elem_b: T) -> CharCodec<T> {
33        CharCodec { pd: PhantomData, elem_a, elem_b }
34    }
35}
36
37impl Default for CharCodec<char> {
38    /// A `CharCodec` with `CONTENT=char`, `A='A'` and `B='B'`
39    ///
40    /// It encodes the following secret:
41    /// `['M', 'y', ' ', 's', 'e', 'c', 'r', 'e', 't']` is
42    ///
43    /// To:
44    /// ['a', 'b', 'a', 'b', 'b', 'b', 'a', 'b', 'b', 'a', 'b', 'a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'a', 'a', 'a', 'a', 'b', 'a', 'b', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'a', 'b', 'a']
45    fn default() -> CharCodec<char> {
46        CharCodec::new('A', 'B')
47    }
48}
49
50impl<T: PartialEq + Clone> BaconCodec for CharCodec<T> {
51    type ABTYPE = T;
52    type CONTENT = char;
53
54    fn encode_elem(&self, elem: &char) -> Vec<T> {
55        match elem {
56            'a' | 'A' => vec![self.a(), self.a(), self.a(), self.a(), self.a()],
57            'b' | 'B' => vec![self.a(), self.a(), self.a(), self.a(), self.b()],
58            'c' | 'C' => vec![self.a(), self.a(), self.a(), self.b(), self.a()],
59            'd' | 'D' => vec![self.a(), self.a(), self.a(), self.b(), self.b()],
60            'e' | 'E' => vec![self.a(), self.a(), self.b(), self.a(), self.a()],
61            'f' | 'F' => vec![self.a(), self.a(), self.b(), self.a(), self.b()],
62            'g' | 'G' => vec![self.a(), self.a(), self.b(), self.b(), self.a()],
63            'h' | 'H' => vec![self.a(), self.a(), self.b(), self.b(), self.b()],
64            'i' | 'I' => vec![self.a(), self.b(), self.a(), self.a(), self.a()],
65            'j' | 'J' => vec![self.a(), self.b(), self.a(), self.a(), self.a()],
66            'k' | 'K' => vec![self.a(), self.b(), self.a(), self.a(), self.b()],
67            'l' | 'L' => vec![self.a(), self.b(), self.a(), self.b(), self.a()],
68            'm' | 'M' => vec![self.a(), self.b(), self.a(), self.b(), self.b()],
69            'n' | 'N' => vec![self.a(), self.b(), self.b(), self.a(), self.a()],
70            'o' | 'O' => vec![self.a(), self.b(), self.b(), self.a(), self.b()],
71            'p' | 'P' => vec![self.a(), self.b(), self.b(), self.b(), self.a()],
72            'q' | 'Q' => vec![self.a(), self.b(), self.b(), self.b(), self.b()],
73            'r' | 'R' => vec![self.b(), self.a(), self.a(), self.a(), self.a()],
74            's' | 'S' => vec![self.b(), self.a(), self.a(), self.a(), self.b()],
75            't' | 'T' => vec![self.b(), self.a(), self.a(), self.b(), self.a()],
76            'u' | 'U' => vec![self.b(), self.a(), self.a(), self.b(), self.b()],
77            'v' | 'V' => vec![self.b(), self.a(), self.a(), self.b(), self.b()],
78            'w' | 'W' => vec![self.b(), self.a(), self.b(), self.a(), self.a()],
79            'x' | 'X' => vec![self.b(), self.a(), self.b(), self.a(), self.b()],
80            'y' | 'Y' => vec![self.b(), self.a(), self.b(), self.b(), self.a()],
81            'z' | 'Z' => vec![self.b(), self.a(), self.b(), self.b(), self.b()],
82            _ => vec![]
83        }
84    }
85
86    fn decode_elems(&self, elems: &[T]) -> char {
87        match elems {
88            m if m == vec![self.a(), self.a(), self.a(), self.a(), self.a()].as_slice() => 'A',
89            m if m == vec![self.a(), self.a(), self.a(), self.a(), self.b()].as_slice() => 'B',
90            m if m == vec![self.a(), self.a(), self.a(), self.b(), self.a()].as_slice() => 'C',
91            m if m == vec![self.a(), self.a(), self.a(), self.b(), self.b()].as_slice() => 'D',
92            m if m == vec![self.a(), self.a(), self.b(), self.a(), self.a()].as_slice() => 'E',
93            m if m == vec![self.a(), self.a(), self.b(), self.a(), self.b()].as_slice() => 'F',
94            m if m == vec![self.a(), self.a(), self.b(), self.b(), self.a()].as_slice() => 'G',
95            m if m == vec![self.a(), self.a(), self.b(), self.b(), self.b()].as_slice() => 'H',
96            m if m == vec![self.a(), self.b(), self.a(), self.a(), self.a()].as_slice() => 'I',
97            m if m == vec![self.a(), self.b(), self.a(), self.a(), self.a()].as_slice() => 'J',
98            m if m == vec![self.a(), self.b(), self.a(), self.a(), self.b()].as_slice() => 'K',
99            m if m == vec![self.a(), self.b(), self.a(), self.b(), self.a()].as_slice() => 'L',
100            m if m == vec![self.a(), self.b(), self.a(), self.b(), self.b()].as_slice() => 'M',
101            m if m == vec![self.a(), self.b(), self.b(), self.a(), self.a()].as_slice() => 'N',
102            m if m == vec![self.a(), self.b(), self.b(), self.a(), self.b()].as_slice() => 'O',
103            m if m == vec![self.a(), self.b(), self.b(), self.b(), self.a()].as_slice() => 'P',
104            m if m == vec![self.a(), self.b(), self.b(), self.b(), self.b()].as_slice() => 'Q',
105            m if m == vec![self.b(), self.a(), self.a(), self.a(), self.a()].as_slice() => 'R',
106            m if m == vec![self.b(), self.a(), self.a(), self.a(), self.b()].as_slice() => 'S',
107            m if m == vec![self.b(), self.a(), self.a(), self.b(), self.a()].as_slice() => 'T',
108            m if m == vec![self.b(), self.a(), self.a(), self.b(), self.b()].as_slice() => 'U',
109            m if m == vec![self.b(), self.a(), self.a(), self.b(), self.b()].as_slice() => 'V',
110            m if m == vec![self.b(), self.a(), self.b(), self.a(), self.a()].as_slice() => 'W',
111            m if m == vec![self.b(), self.a(), self.b(), self.a(), self.b()].as_slice() => 'X',
112            m if m == vec![self.b(), self.a(), self.b(), self.b(), self.a()].as_slice() => 'Y',
113            m if m == vec![self.b(), self.a(), self.b(), self.b(), self.b()].as_slice() => 'Z',
114            _ => ' '
115        }
116    }
117
118    fn a(&self) -> T { self.elem_a.clone() }
119
120    fn b(&self) -> T { self.elem_b.clone() }
121
122    fn encoded_group_size(&self) -> usize { 5 }
123
124    fn is_a(&self, elem: &T) -> bool {
125        elem == &self.a()
126    }
127
128    fn is_b(&self, elem: &T) -> bool {
129        elem == &self.b()
130    }
131}
132
133// ---------------------------------------------- V2 ---------------------------------------------//
134
135#[derive(PartialEq, Clone)]
136/// A codec that encodes data of type `char`.
137///
138/// The encoding is done by substituting with two given elements (`elem_a` and `elem_b`) of type `T`.
139///
140/// The substitution is done using the __second__ version of the Bacon's cipher.
141pub struct CharCodecV2<T> {
142    pd: PhantomData<char>,
143    elem_a: T,
144    elem_b: T,
145}
146
147impl<T> CharCodecV2<T> {
148    /// Create a new `CharCodec` using elements `elem_a` and `elem_b` for substitution.
149    pub fn new(elem_a: T, elem_b: T) -> CharCodecV2<T> {
150        CharCodecV2 { pd: PhantomData, elem_a, elem_b }
151    }
152}
153
154impl Default for CharCodecV2<char> {
155    /// A `CharCodec` with `CONTENT=char`, `A='A'` and `B='B'`
156    ///
157    /// It encodes the following secret:
158    /// `['M', 'y', ' ', 's', 'e', 'c', 'r', 'e', 't']` is
159    ///
160    /// To:
161    /// ['a', 'b', 'a', 'b', 'b', 'b', 'a', 'b', 'b', 'a', 'b', 'a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'a', 'a', 'a', 'a', 'b', 'a', 'b', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'a', 'b', 'a']
162    fn default() -> CharCodecV2<char> {
163        CharCodecV2::new('A', 'B')
164    }
165}
166
167impl<T: PartialEq + Clone> BaconCodec for CharCodecV2<T> {
168    type ABTYPE = T;
169    type CONTENT = char;
170
171    fn encode_elem(&self, elem: &char) -> Vec<T> {
172        match elem {
173            'a' | 'A' => vec![self.a(), self.a(), self.a(), self.a(), self.a()],
174            'b' | 'B' => vec![self.a(), self.a(), self.a(), self.a(), self.b()],
175            'c' | 'C' => vec![self.a(), self.a(), self.a(), self.b(), self.a()],
176            'd' | 'D' => vec![self.a(), self.a(), self.a(), self.b(), self.b()],
177            'e' | 'E' => vec![self.a(), self.a(), self.b(), self.a(), self.a()],
178            'f' | 'F' => vec![self.a(), self.a(), self.b(), self.a(), self.b()],
179            'g' | 'G' => vec![self.a(), self.a(), self.b(), self.b(), self.a()],
180            'h' | 'H' => vec![self.a(), self.a(), self.b(), self.b(), self.b()],
181            'i' | 'I' => vec![self.a(), self.b(), self.a(), self.a(), self.a()],
182            'j' | 'J' => vec![self.a(), self.b(), self.a(), self.a(), self.b()],
183            'k' | 'K' => vec![self.a(), self.b(), self.a(), self.b(), self.a()],
184            'l' | 'L' => vec![self.a(), self.b(), self.a(), self.b(), self.b()],
185            'm' | 'M' => vec![self.a(), self.b(), self.b(), self.a(), self.a()],
186            'n' | 'N' => vec![self.a(), self.b(), self.b(), self.a(), self.b()],
187            'o' | 'O' => vec![self.a(), self.b(), self.b(), self.b(), self.a()],
188            'p' | 'P' => vec![self.a(), self.b(), self.b(), self.b(), self.b()],
189            'q' | 'Q' => vec![self.b(), self.a(), self.a(), self.a(), self.a()],
190            'r' | 'R' => vec![self.b(), self.a(), self.a(), self.a(), self.b()],
191            's' | 'S' => vec![self.b(), self.a(), self.a(), self.b(), self.a()],
192            't' | 'T' => vec![self.b(), self.a(), self.a(), self.b(), self.b()],
193            'u' | 'U' => vec![self.b(), self.a(), self.b(), self.a(), self.a()],
194            'v' | 'V' => vec![self.b(), self.a(), self.b(), self.a(), self.b()],
195            'w' | 'W' => vec![self.b(), self.a(), self.b(), self.b(), self.a()],
196            'x' | 'X' => vec![self.b(), self.a(), self.b(), self.b(), self.b()],
197            'y' | 'Y' => vec![self.b(), self.b(), self.a(), self.a(), self.a()],
198            'z' | 'Z' => vec![self.b(), self.b(), self.a(), self.a(), self.b()],
199            _ => vec![]
200        }
201    }
202
203    fn decode_elems(&self, elems: &[T]) -> char {
204        match elems {
205            m if m == vec![self.a(), self.a(), self.a(), self.a(), self.a()].as_slice() => 'A',
206            m if m == vec![self.a(), self.a(), self.a(), self.a(), self.b()].as_slice() => 'B',
207            m if m == vec![self.a(), self.a(), self.a(), self.b(), self.a()].as_slice() => 'C',
208            m if m == vec![self.a(), self.a(), self.a(), self.b(), self.b()].as_slice() => 'D',
209            m if m == vec![self.a(), self.a(), self.b(), self.a(), self.a()].as_slice() => 'E',
210            m if m == vec![self.a(), self.a(), self.b(), self.a(), self.b()].as_slice() => 'F',
211            m if m == vec![self.a(), self.a(), self.b(), self.b(), self.a()].as_slice() => 'G',
212            m if m == vec![self.a(), self.a(), self.b(), self.b(), self.b()].as_slice() => 'H',
213            m if m == vec![self.a(), self.b(), self.a(), self.a(), self.a()].as_slice() => 'I',
214            m if m == vec![self.a(), self.b(), self.a(), self.a(), self.b()].as_slice() => 'J',
215            m if m == vec![self.a(), self.b(), self.a(), self.b(), self.a()].as_slice() => 'K',
216            m if m == vec![self.a(), self.b(), self.a(), self.b(), self.b()].as_slice() => 'L',
217            m if m == vec![self.a(), self.b(), self.b(), self.a(), self.a()].as_slice() => 'M',
218            m if m == vec![self.a(), self.b(), self.b(), self.a(), self.b()].as_slice() => 'N',
219            m if m == vec![self.a(), self.b(), self.b(), self.b(), self.a()].as_slice() => 'O',
220            m if m == vec![self.a(), self.b(), self.b(), self.b(), self.b()].as_slice() => 'P',
221            m if m == vec![self.b(), self.a(), self.a(), self.a(), self.a()].as_slice() => 'Q',
222            m if m == vec![self.b(), self.a(), self.a(), self.a(), self.b()].as_slice() => 'R',
223            m if m == vec![self.b(), self.a(), self.a(), self.b(), self.a()].as_slice() => 'S',
224            m if m == vec![self.b(), self.a(), self.a(), self.b(), self.b()].as_slice() => 'T',
225            m if m == vec![self.b(), self.a(), self.b(), self.a(), self.a()].as_slice() => 'U',
226            m if m == vec![self.b(), self.a(), self.b(), self.a(), self.b()].as_slice() => 'V',
227            m if m == vec![self.b(), self.a(), self.b(), self.b(), self.a()].as_slice() => 'W',
228            m if m == vec![self.b(), self.a(), self.b(), self.b(), self.b()].as_slice() => 'X',
229            m if m == vec![self.b(), self.b(), self.a(), self.a(), self.a()].as_slice() => 'Y',
230            m if m == vec![self.b(), self.b(), self.a(), self.a(), self.b()].as_slice() => 'Z',
231            _ => ' '
232        }
233    }
234
235    fn a(&self) -> T { self.elem_a.clone() }
236
237    fn b(&self) -> T { self.elem_b.clone() }
238
239    fn encoded_group_size(&self) -> usize { 5 }
240
241    fn is_a(&self, elem: &T) -> bool {
242        elem == &self.a()
243    }
244
245    fn is_b(&self, elem: &T) -> bool {
246        elem == &self.b()
247    }
248}
249
250#[cfg(test)]
251mod char_codec_tests {
252    use std::iter::FromIterator;
253
254    use super::*;
255
256    #[test]
257    fn encode_chars_to_cipher_of_chars() {
258        let codec = CharCodec::new('A', 'B');
259        let secret: Vec<char> = "My secret".chars().collect();
260        let encoded = codec.encode(&secret);
261        let string = String::from_iter(encoded.iter());
262        assert_eq!("ABABBBABBABAAABAABAAAAABABAAAAAABAABAABA", string);
263    }
264
265    #[test]
266    fn encode_all_chars_to_cipher_of_chars() {
267        let codec = CharCodec::new('a', 'b');
268        let encoded = codec.encode(&['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']);
269        let string = String::from_iter(encoded.iter());
270        assert_eq!("aaaaaaaaabaaabaaaabbaabaaaababaabbaaabbbabaaaabaaaabaabababaababbabbaaabbababbbaabbbbbaaaabaaabbaababaabbbaabbbabaabababbabbababbb", string);
271    }
272
273    #[test]
274    fn encode_all_chars_to_cipher_of_chars_v2() {
275        let codec = CharCodecV2::new('a', 'b');
276        let encoded = codec.encode(&['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']);
277        let string = String::from_iter(encoded.iter());
278        assert_eq!("aaaaaaaaabaaabaaaabbaabaaaababaabbaaabbbabaaaabaabababaababbabbaaabbababbbaabbbbbaaaabaaabbaababaabbbabaabababbabbababbbbbaaabbaab", string);
279    }
280
281    #[test]
282    fn encode_all_capital_chars_to_cipher_of_chars() {
283        let codec = CharCodec::new('a', 'b');
284        let encoded = codec.encode(&['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']);
285        let string = String::from_iter(encoded.iter());
286        assert_eq!("aaaaaaaaabaaabaaaabbaabaaaababaabbaaabbbabaaaabaaaabaabababaababbabbaaabbababbbaabbbbbaaaabaaabbaababaabbbaabbbabaabababbabbababbb", string);
287    }
288
289    #[test]
290    fn encode_all_capital_chars_to_cipher_of_chars_v2() {
291        let codec = CharCodecV2::new('a', 'b');
292        let encoded = codec.encode(&['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']);
293        let string = String::from_iter(encoded.iter());
294        assert_eq!("aaaaaaaaabaaabaaaabbaabaaaababaabbaaabbbabaaaabaabababaababbabbaaabbababbbaabbbbbaaaabaaabbaababaabbbabaabababbabbababbbbbaaabbaab", string);
295    }
296
297    #[test]
298    fn decode_cipher_of_chars_to_chars() {
299        let codec = CharCodec::new('a', 'b');
300        let decoded = codec.decode(&['a', 'b', 'a', 'b', 'b', 'b', 'a', 'b', 'b', 'a', 'b', 'a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'a', 'a', 'a', 'a', 'b', 'a', 'b', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'a', 'b', 'a']);
301        let string = String::from_iter(decoded.iter());
302        assert_eq!("MYSECRET", string);
303    }
304
305    #[test]
306    fn decode_cipher_of_all_chars_to_chars() {
307        let codec = CharCodec::new('a', 'b');
308        let decoded = codec.decode(&['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'a', 'a', 'a', 'b', 'a', 'a', 'a', 'a',
309            'b', 'b', 'a', 'a', 'b', 'a', 'a', 'a', 'a', 'b', 'a', 'b', 'a', 'a', 'b', 'b', 'a', 'a', 'a', 'b', 'b', 'b', 'a', 'b', 'a', 'a', 'a', 'a',
310            'b', 'a', 'a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'a', 'b', 'a', 'b', 'b', 'a', 'b', 'b', 'a', 'a', 'a', 'b', 'b', 'a',
311            'b', 'a', 'b', 'b', 'b', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'a', 'a', 'a', 'a', 'b', 'a', 'a', 'a', 'b', 'b', 'a', 'a', 'b', 'a', 'b', 'a',
312            'a', 'b', 'b', 'b', 'a', 'a', 'b', 'b', 'b', 'a', 'b', 'a', 'a', 'b', 'a', 'b', 'a', 'b', 'b', 'a', 'b', 'b', 'a', 'b', 'a', 'b', 'b', 'b']);
313        let string = String::from_iter(decoded.iter());
314        assert_eq!("ABCDEFGHIIKLMNOPQRSTUUWXYZ", string);
315    }
316
317    #[test]
318    fn encode_chars_to_cipher_of_bools() {
319        let codec = CharCodec::new(false, true);
320        let encoded = codec.encode(&['M', 'y', ' ', 's', 'e', 'c', 'r', 'e', 't']);
321        assert_eq!(vec![false, true, false, true, true, true, false, true, true, false, true, false, false, false, true, false, false, true, false, false, false, false, false, true, false, true, false, false, false, false, false, false, true, false, false, true, false, false, true, false], encoded);
322    }
323
324    #[test]
325    fn decode_cipher_of_bools_to_chars() {
326        let codec = CharCodec::new(false, true);
327        let decoded = codec.decode(&vec![false, true, false, true, true, true, false, true, true, false, true, false, false, false, true, false, false, true, false, false, false, false, false, true, false, true, false, false, false, false, false, false, true, false, false, true, false, false, true, false]);
328        let string = String::from_iter(decoded.iter());
329        assert_eq!("MYSECRET", string);
330    }
331}