fenc/
lib.rs

1mod common;
2mod crc32;
3mod dec;
4mod enc;
5
6pub use crate::common::Error;
7pub use crate::common::ErrorKind;
8pub use crate::common::Result;
9
10use java_data_io;
11use mersenne_twister::MersenneTwister;
12
13#[derive(Clone)]
14pub struct Fenc {
15    mt: Box<MersenneTwister>,
16}
17
18pub struct FencDecContent<R> {
19    dc: crate::dec::DecContent<R>,
20}
21
22impl std::fmt::Debug for Fenc {
23    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        write!(f, "Fenc{{...}}")
25    }
26}
27
28impl<R> std::fmt::Debug for FencDecContent<R> {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        write!(f, "FencDecContent{{...}}")
31    }
32}
33
34impl Fenc {
35    pub fn new(password: &str) -> Self {
36        let key = password_to_key(password);
37        Self {
38            mt: Box::new(MersenneTwister::new_by_array(&key)),
39        }
40    }
41
42    pub fn enc<R, W>(self, file_name: &str, src_len: u64, src: R, dst: W) -> Result<()>
43    where
44        R: std::io::Read,
45        W: std::io::Write,
46    {
47        let args = crate::enc::Arguments {
48            mt: self.mt,
49            file_name: file_name,
50            src_len: src_len,
51            src: src,
52            dst: dst,
53        };
54        crate::enc::enc(args)
55    }
56
57    pub fn enc_data(self, file_name: &str, src: &[u8]) -> Result<Vec<u8>> {
58        let mut dst: Vec<u8> = Vec::new();
59        self.enc(file_name, src.len() as u64, src, &mut dst)?;
60        Ok(dst)
61    }
62
63    pub fn dec<R, W, F>(self, src: R, dst: W, file_name: F) -> Result<()>
64    where
65        R: std::io::Read,
66        W: std::io::Write,
67        F: std::fmt::Write,
68    {
69        let args = crate::dec::Arguments {
70            mt: self.mt,
71            src: src,
72            file_name: file_name,
73        };
74        crate::dec::dec(args)?.dec_content(dst)
75    }
76
77    pub fn dec_data<R>(self, src: R) -> Result<(String, Vec<u8>)>
78    where
79        R: std::io::Read,
80    {
81        let mut dst: Vec<u8> = Vec::new();
82        let mut file_name = String::new();
83        self.dec(src, &mut dst, &mut file_name)?;
84        Ok((file_name, dst))
85    }
86
87    pub fn dec_file_name<R, F>(self, src: R, file_name: F) -> Result<FencDecContent<R>>
88    where
89        R: std::io::Read,
90        F: std::fmt::Write,
91    {
92        let args = crate::dec::Arguments {
93            mt: self.mt,
94            src: src,
95            file_name: file_name,
96        };
97        let dc = crate::dec::dec(args)?;
98        Ok(FencDecContent::new(dc))
99    }
100
101    pub fn dec_file_name_string<R>(self, src: R) -> Result<String>
102    where
103        R: std::io::Read,
104    {
105        let mut s = String::new();
106        self.dec_file_name(src, &mut s)?;
107        Ok(s)
108    }
109}
110
111fn password_to_key(password: &str) -> Vec<u32> {
112    let s = java_data_io::to_java_string(password);
113    let mut res = Vec::<u32>::new();
114    for (i, v) in s.iter().enumerate() {
115        let p = s.len() - 1 - i;
116        res.push(((*v as u32) << 16) | (s[p] as u32));
117    }
118    res
119}
120
121impl<R: std::io::Read> FencDecContent<R> {
122    fn new(dc: crate::dec::DecContent<R>) -> Self {
123        Self { dc }
124    }
125
126    pub fn dec_content<W: std::io::Write>(self, dst: W) -> Result<()> {
127        self.dc.dec_content(dst)
128    }
129}
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134
135    #[test]
136    fn it_works() {
137        let password = "Password1";
138        let file_name = "READMEEE.txt";
139        let src = b"0123456789ABCDEF";
140
141        let fenc = Fenc::new(password);
142        let dec = fenc.clone();
143        let dec2 = fenc.clone();
144        let dec3 = fenc.clone();
145        let data = fenc.enc_data(file_name, src).unwrap();
146
147        let (name, dst) = dec.dec_data(data.as_slice()).unwrap();
148
149        assert_eq!(name, file_name);
150        assert_eq!(dst, src);
151
152        let name2 = dec2.dec_file_name_string(data.as_slice()).unwrap();
153
154        assert_eq!(name2, file_name);
155
156        let mut name3 = String::new();
157        let mut dst2: Vec<u8> = Vec::new();
158        dec3.dec_file_name(data.as_slice(), &mut name3)
159            .unwrap()
160            .dec_content(&mut dst2)
161            .unwrap();
162
163        assert_eq!(name3, file_name);
164        assert_eq!(dst2, src);
165    }
166}