extern crate getopts; extern crate byteorder; use std::env; use std::fs; use std::io::BufReader; use std::io::prelude::*; use std::i32; use std::io::Cursor; use getopts::Options; use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian}; fn main() { let args: Vec = env::args().collect(); let mut opts = Options::new(); opts.optflag("c", "", "Compress file"); opts.optflag("x", "", "Extract file"); let matches = match opts.parse(&args[1..]) { Ok(m) => { m } Err(f) => { panic!(f.to_string()) } }; if matches.opt_present("c") { let input = &matches.free[0]; let output = &matches.free[1]; create(&input, &output); } else if matches.opt_present("x") { let input = &matches.free[0]; let output = &matches.free[1]; extract(&input, &output) } } fn create(input: &String, output: &String) { let mut output_file = fs::File::create(output).unwrap(); let input_file = fs::File::open(input).unwrap(); let input_buf = BufReader::new(input_file); let mut i : i32 = 0; for b in input_buf.bytes() { let b = b.unwrap(); for n in 0..i32::MAX { if b == get_byte(n) { i = n; break; } } let mut index : Vec = vec![]; index.write_i32::(i).unwrap(); output_file.write_all(&index).unwrap(); } } fn extract(input: &String, output: &String) { let mut output_file = fs::File::create(output).unwrap(); let mut input_file = fs::File::open(input).unwrap(); let mut buf = vec![0; 4]; loop { let size = input_file.read(&mut buf).unwrap(); if size <= 0 { break; } let mut c = Cursor::new(&buf); let index = c.read_i32::().unwrap(); output_file.write_all(&[get_byte(index)]).unwrap(); } } fn get_byte(id: i32) -> u8 { let pid : f64 = 4.0 * series(1, id) - 2.0 * series(4, id) - series(5, id) - series(6, id); let mut y : f64 = (pid - (pid as i32) as f64 + 1.0).abs(); y = 16.0 * (y - y.floor()); let first : u8 = y as u8; y = 16.0 * (y - y.floor()); let second : u8 = y as u8; (first << 4) | second } fn series(m: i32, id: i32) -> f64 { const EPS : f64 = 1e-17; let mut ak : f64; let mut s : f64 = 0.0; let mut t : f64; for k in 0..id { ak = (8 * k + m) as f64; t = expm((id - k) as f64, ak); s = s + t / ak; s = s - (s as i32) as f64; } for k in id..id + 101 { ak = (8 * k + m) as f64; t = 16f64.powi(id - k) / ak; if t < EPS { break; } s = s + t; s = s - (s as i32) as f64; } s } fn expm(p: f64, ak: f64) -> f64 { const NTP : usize = 25; let mut tp = vec![1f64; NTP]; let mut i : i32 = 0; let mut p1 : f64 = p; let mut pt : f64; let mut r : f64 = 1.0; for n in 1..NTP { tp[n] = 2.0 * tp[n - 1]; } if ak == 1.0 { return 0.0; } for n in 0..NTP { if tp[n] > p { i = n as i32; break; } } pt = tp[(i - 1) as usize]; for _ in 1..i + 1 { if p1 >= pt { r = 16.0 * r; r = r - ((r / ak) as i32) as f64 * ak; p1 = p1 - pt; } pt = 0.5 * pt; if pt >= 1.0 { r = r * r; r = r - ((r / ak) as i32) as f64 * ak; } } r }