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}