From 8b49d695c10c3897f74c101751a949b72fbfcfe5 Mon Sep 17 00:00:00 2001 From: serhiivolynets-256 Date: Wed, 15 Oct 2025 23:54:34 +0300 Subject: [PATCH] upload lab 3 --- Cargo.lock | 7 ++ Cargo.toml | 2 +- bit_stream/src/bit_stream.rs | 96 ++++++++++++++-- decoded_file | 9 ++ encoded_file | Bin 0 -> 2513 bytes huffman_codes/Cargo.toml | 11 ++ huffman_codes/src/algorithms.rs | 116 +++++++++++++++++++ huffman_codes/src/bin/main.rs | 23 ++++ huffman_codes/src/lib.rs | 2 + huffman_codes/src/tree.rs | 190 ++++++++++++++++++++++++++++++++ test.txt | 12 +- test.txt.base64 | 7 -- test.txt.base64.txt | 7 -- 13 files changed, 454 insertions(+), 28 deletions(-) create mode 100644 decoded_file create mode 100644 encoded_file create mode 100644 huffman_codes/Cargo.toml create mode 100644 huffman_codes/src/algorithms.rs create mode 100644 huffman_codes/src/bin/main.rs create mode 100644 huffman_codes/src/lib.rs create mode 100644 huffman_codes/src/tree.rs delete mode 100644 test.txt.base64 delete mode 100644 test.txt.base64.txt diff --git a/Cargo.lock b/Cargo.lock index 11a2fbe..06452bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,13 @@ dependencies = [ name = "bit_stream" version = "0.1.0" +[[package]] +name = "huffman_codes" +version = "0.1.0" +dependencies = [ + "bit_stream", +] + [[package]] name = "proc-macro2" version = "1.0.101" diff --git a/Cargo.toml b/Cargo.toml index 9c0ee09..82be719 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" members = [ "base64lab", "bit_stream" -] +, "huffman_codes"] resolver = "2" [profile.test] diff --git a/bit_stream/src/bit_stream.rs b/bit_stream/src/bit_stream.rs index 68c100b..3221f1b 100644 --- a/bit_stream/src/bit_stream.rs +++ b/bit_stream/src/bit_stream.rs @@ -1,12 +1,13 @@ use std::fs::File; use std::io::{Read, Write, Seek, SeekFrom}; +use std::os::unix::fs::FileExt; #[derive(Debug)] pub struct BitStreamWriter { - file: File, - bit_len: usize, - current_byte: u8, - bit_count: usize, + pub file: File, + pub bytes_written: usize, + pub current_byte: u8, + pub bit_count: usize, } impl BitStreamWriter { @@ -14,7 +15,7 @@ impl BitStreamWriter { let file = File::create(path)?; Ok(Self { file, - bit_len: 0, + bytes_written: 0, current_byte: 0u8, bit_count: 0, }) @@ -46,9 +47,35 @@ impl BitStreamWriter { buffer.push(self.current_byte); } - self.file.seek(SeekFrom::Start(self.bit_len as u64))?; + self.file.seek(SeekFrom::Start(self.bytes_written as u64))?; + + if self.bit_count % 8 == 0 { + self.bytes_written += buffer.len(); + } else { + self.bytes_written += buffer.len() - 1 + } + self.file.write_all(&buffer)?; - self.bit_len += to_take / 8; + + // self.bit_len += to_take / 8; + + Ok(()) + } + + pub fn write_byte_sequence_unchecked_at(&mut self, bytes: &[u8], start: u64) -> std::io::Result<()> { + self.file.seek(SeekFrom::Start(start))?; + self.file.write_all(&bytes)?; + + Ok(()) + } + + pub fn skip_bytes(&mut self, amount: usize) { + self.bytes_written += amount; + } + + pub fn finish(self) -> std::io::Result<()> { + + Ok(()) } } @@ -96,6 +123,59 @@ impl BitStreamReader { Ok(out) } + + pub fn read_all(path: &str) -> std::io::Result> { + let mut reader = Self::open(path)?; + let mut buf = Vec::new(); + reader.file.read_to_end(&mut buf)?; + + Ok(buf) + } + + pub fn bit_len(&self) -> usize { + self.bit_len + } + + pub fn byte_len(&self) -> usize { + (self.bit_len + 7) / 8 + } +} + +pub struct BitReader<'a> { + bytes: &'a [u8], + current_byte: usize, + current_bit: u8, +} + +impl<'a> BitReader<'a> { + pub fn new(bytes: &'a [u8] ) -> Self { + Self { + bytes, + current_byte: 0, + current_bit: 0, + } + } +} + +impl<'a> Iterator for BitReader<'a> { + type Item = bool; + + fn next(&mut self) -> Option { + if self.current_byte >= self.bytes.len() { + return None; + } + + let byte = self.bytes[self.current_byte]; + let bit = (byte >> self.current_bit) & 1; + + self.current_bit += 1; + if self.current_bit == 8 { + self.current_bit = 0; + self.current_byte += 1; + } + + Some(bit == 1) + } } @@ -162,4 +242,4 @@ mod tests { [0x77], ); } -} \ No newline at end of file +} diff --git a/decoded_file b/decoded_file new file mode 100644 index 0000000..cb28d1c --- /dev/null +++ b/decoded_file @@ -0,0 +1,9 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas posuere vehicula metus id convallis. Etiam consequat ut quam non hendrerit. Nullam sit amet lobortis quam. Aliquam rhoncus feugiat pellentesque. Fusce dictum sem at mauris hendrerit bibendum. Integer vitae nisl nisl. Suspendisse potenti. Vestibulum mollis dui eget facilisis laoreet. Pellentesque nec odio interdum, pharetra nisl a, luctus magna. Aliquam erat volutpat. + +Suspendisse eu ligula dui. Praesent auctor urna volutpat, sollicitudin turpis non, tempus justo. Nulla malesuada ex ac aliquam laoreet. Integer aliquet nisl egestas finibus mattis. Duis at congue massa. Vivamus sed mi eget turpis imperdiet venenatis. Curabitur pulvinar lectus enim, ac convallis nulla imperdiet eu. Cras ultrices feugiat nisl, quis aliquet elit maximus quis. Cras scelerisque ac nisl vel venenatis. + +Etiam vel risus diam. Proin pellentesque purus eget augue commodo, a aliquam odio fermentum. Quisque maximus convallis egestas. Aliquam tempus sed arcu eget varius. Sed libero nulla, tempor hendrerit nulla ut, scelerisque molestie ligula. Aliquam erat volutpat. Vestibulum ut nulla magna. Integer id facilisis diam, ac viverra erat. Praesent molestie consectetur lacus, et auctor eros rhoncus eget. Donec arcu turpis, dictum dignissim condimentum rhoncus, ornare non massa. In facilisis, justo eget aliquam placerat, mi magna lacinia eros, ac pretium velit nibh id metus. Nulla vel diam eget augue auctor elementum. Praesent porta sodales arcu id sollicitudin. + +Sed eget orci eu purus fringilla ullamcorper. Cras consequat arcu ac tincidunt cursus. Donec lorem ex, lobortis nec sapien eu, consectetur pretium tellus. Proin accumsan quam nisi. Nullam viverra ante vitae sapien convallis, eget tempor diam fringilla. Nulla eu bibendum risus, vehicula venenatis metus. In tortor dui, tincidunt imperdiet molestie sed, pharetra ut enim. Fusce hendrerit placerat sem ac blandit. Proin condimentum sapien quis justo finibus sodales. Phasellus vestibulum tristique ex at commodo. Integer scelerisque justo ut felis accumsan vulputate. Nulla ac imperdiet turpis, non ultricies leo. + +Fusce vitae felis eget nisi semper dapibus sed ut tortor. Duis euismod laoreet justo, quis cursus lectus pulvinar ut. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque feugiat erat ut erat pellentesque semper. Fusce et mauris ac tortor rhoncus tincidunt et et velit. Vivamus bibendum eros urna, eu fringilla nunc blandit sed. Pellentesque non quam id lorem euismod porttitor mattis non sem. Etiam dictum dapibus massa malesuada placerat. Duis pharetra tristique lacus vel vestibulum. Duis non libero molestie, tristique velit vitae, lobortis turpis. Curabitur luctus ante quis tortor luctus dignissim ac ac enim. \ No newline at end of file diff --git a/encoded_file b/encoded_file new file mode 100644 index 0000000000000000000000000000000000000000..45cf761cd26ca4f85b0962eacb676a9d9e299fa1 GIT binary patch literal 2513 zcmeH{do>G2)Q-XYC>~iC{w1Ggj|~lozk!*lVrwdWINKjjZ177MrkrETBesB_wXI`x0gIiL4;d7t<9`#$gcJdcZ|+&3BG zo4mi?IaU7aeId_PAKmS~ZP^#S6+h0x!Bq*M0QmF{no@>_j|Rzwfczjs0zQTC`I^t~ zWsYAMYQdZ?z#Fg`fB+xV09ONmI-mytX@e{i5CJ#=2nOH*kRKON2dD?M0t^9=eOkBl z^nLuk1OMNFyio@eW}(Q@YJg=6FIabGej&RJI84X#?52u~Y+|m2 z97(lY+`2d?AuH$bgNQ~6w}cH&B|_N5{IdOT;?tGP3>ok<#ioO_#=JUJKP$K*oHpbp z|A4rNu92gv^Z0%bI!CQkwXO_@z0FM%vFSlcq;yMB|MdF&+?Kv$NutD}Detu|r^dV7 zQv5}7hM}?g{cFxX?$pp4jG`E0NF@K{N_UBajl5F>*~JS!-9g+}5gz)Fu*4Vrp(QzV z(ml&S+vMm&F~tf_ac*saKdX_G38+@{=scCCsvs{9ODpI<7F|R&V@t?I8lJnF*`dg- zO}_Vaq;Z0)L8y(F8@N<`cWTG^$@z6mj(JU$V5M@7ppT)*(y9;f&|5_v^Gjm-)7yXpf#AQyjnP|a{hHY^S*hlM%84d&B#r^ zubT6yB7E!(N%^`Cxb;zMT8cmF z4{oIiJFEngAINlZtrT{V_Wd0h=Tp%gkdFfb7Pc-N)ZwYYU}wOYjI3QxsBu(M%z3cN z{Y7cahT~zums+bsOGGIpe;N!I*=Ru_q#hrJ?Y>j^gJRAl?!SL28g3%9j1uBJ#SwS= z8c6aU^E-*XSU1ZjUeUOzJkv}ni=H@DmQ^!KC`IxPWQ|zJP7H`;qLxHpFV_rt&eP#0 zfye-)%WdU;ls5H#hI;$iDyw`8Fc;= zmm4-o;n)Ozfx&=|gWl%bk?Qn%cR9h8u5Mi^_28cP5LuiRu9Mb0EV3y|oXSlRuaD*7 z_*1%Q&s*es2AZz(@X%oqeka2uV0*nVry0KbZ2lg(^f!Twlcg}@ffp-0N7cNZK94u0b@R2h@Psq>^3c_% zInw$=TN>l(ZJqSP#)l|97OkAdLMjT>4bvw4sskmdiXq@g!!s_r@ z#q8@U6rBPA2bO>zX!0$}GPvV5KTeY+6m&qt?@(8X-M^^`!csJ#3WPm+?_bP^HfTYF z<9i?0SM}T#Wp9+AKh%kk0-63~uMMncuzHGdO~D7rMv1v-h9Ov6v=V;_Azjfwb0Mr3 zBg-i8zu!YG+{@O#b@KoVaGLc9M^rJ6Y9}T8eZ=lVjc=HZBh7)+HpIuWI5( zJ+MO{G=K(acQ9->$U0g|#vCc8Lf;(UI`R&8dUnHr2(M8~9m_h-m>Hn;wxrv@P~LWc!w?s{1@G!}IX%sh`aoT5TeG_rTq^-HO-k=F_z)a-PCToPvWeE)ynvO^ zPzn=!@kwuQ<4*6f?xV<>#{p+3*@7B% z$1Cqv4alFv0Vr^q@fXh<9>O^;?9jxjRyD%fTvZacE_5V-GYe%_@g#+hcvAV~iK D+aS4$ literal 0 HcmV?d00001 diff --git a/huffman_codes/Cargo.toml b/huffman_codes/Cargo.toml new file mode 100644 index 0000000..9c13858 --- /dev/null +++ b/huffman_codes/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "huffman_codes" +version = "0.1.0" +edition = "2024" + +[[bin]] +name = "lab3" +path = "src/bin/main.rs" + +[dependencies] +bit_stream = { path = "../bit_stream" } \ No newline at end of file diff --git a/huffman_codes/src/algorithms.rs b/huffman_codes/src/algorithms.rs new file mode 100644 index 0000000..2e01584 --- /dev/null +++ b/huffman_codes/src/algorithms.rs @@ -0,0 +1,116 @@ +use std::io::ErrorKind; + +use bit_stream::{BitStreamReader, BitStreamWriter, BitReader}; +use crate::tree::{Direction, Node}; + +pub fn encode(input_path: &str, output_path: &str) -> std::io::Result<()> { + let file_bytes = BitStreamReader::read_all(input_path)?; + + let mut node_weights= vec![0; 256]; + for byte in file_bytes { + node_weights[byte as usize] += 1; + } + + println!("node_weights: {:?}", node_weights); + + let mut non_zero_nodes = Vec::new(); + for (byte, weight) in node_weights.iter().enumerate() { + if *weight != 0 { + non_zero_nodes.push(Node::Leaf { + value: byte as u8, + weight: *weight, + }); + } + } + + let huffman_root = Node::huffman_tree(non_zero_nodes).unwrap(); + + // write dict + let mut writer = BitStreamWriter::create(output_path)?; + writer.skip_bytes(8); + for weight in node_weights { + writer.write_bit_sequence(weight.to_le_bytes().as_slice(), 32)? + } + + let dictionary = huffman_root.generate_dict(); + + // encode file + let bytes = BitStreamReader::read_all(input_path)?; + for byte in bytes { + let (numeric_repr, bit_len) = dictionary[&byte]; + let bytes = numeric_repr.to_le_bytes(); + writer.write_bit_sequence(&bytes, bit_len as usize)? + } + + let data_length = (writer.bytes_written - 8 - 1024) * 8 + writer.bit_count; + println!("data_length: {}", data_length); + writer.write_byte_sequence_unchecked_at(&data_length.to_le_bytes(), 0)?; + + Ok(()) +} + +pub fn decode(input_path: &str, output_path: &str) -> std::io::Result<()> { + let mut reader: BitStreamReader = BitStreamReader::open(input_path)?; + + let length_bytes = reader.read_bit_sequence(64)?; + let length_bytes_slice = <&[u8; 8]>::try_from(&*length_bytes) + .map_err(|_| std::io::Error::new(ErrorKind::InvalidData, "slice length is not 8"))?; + + let data_length = u64::from_le_bytes(*length_bytes_slice); + println!("data_length: {}", data_length); + + let dict_files_bytes: Vec = reader.read_bit_sequence(1024 * 8)?; + let mut byte_weights: Vec = Vec::from([0u32; 256]); + for (i, ctr) in (0..dict_files_bytes.len()).step_by(4).enumerate() { + if let Ok(arr) = <&[u8; 4]>::try_from(&dict_files_bytes[ctr..ctr + 4]) { + byte_weights[i] = u32::from_le_bytes(*arr); + } + } + + println!("byte_weights: {:?}", byte_weights); + + let mut nodes: Vec = Vec::new(); + for (byte, weight) in byte_weights.iter().enumerate() { + if *weight != 0 { + nodes.push(Node::Leaf { + value: byte as u8, + weight: *weight, + }); + } + } + + let huffman_root = Node::huffman_tree(nodes).unwrap(); + + // decode file + let mut writer: BitStreamWriter = BitStreamWriter::create(output_path)?; + let mut current_node = &huffman_root; + let mut processed_bits = 0; + let read_window = 8 * 2048; + + let mut bytes = reader.read_bit_sequence(read_window)?; + while !bytes.is_empty() { + for bit in BitReader::new(&bytes) { + let dir = match bit { + true => Direction::Right, + false => Direction::Left, + }; + if let Some(potential_leaf) = current_node.get_child(dir) { + if potential_leaf.is_leaf() { + writer.write_bit_sequence(&[potential_leaf.value().unwrap()], 8)?; + current_node = &huffman_root; + } else { + current_node = potential_leaf; + } + } + + processed_bits += 1; + if processed_bits == data_length { + break; + } + } + + bytes = reader.read_bit_sequence(read_window)?; + } + + Ok(()) +} diff --git a/huffman_codes/src/bin/main.rs b/huffman_codes/src/bin/main.rs new file mode 100644 index 0000000..9bedfce --- /dev/null +++ b/huffman_codes/src/bin/main.rs @@ -0,0 +1,23 @@ +use huffman_codes::algorithms::{encode, decode}; +use std::time::Instant; + +fn run() { + // let input_path = "sample3.xls"; + let input_path = "test.txt"; + let encoded_file_path = "encoded_file"; + let decoded_file_path = "decoded_file"; + + println!("Encoding file ..."); + let start = Instant::now(); + encode(&input_path, &encoded_file_path).unwrap(); + println!("Encoding time: {:?}", start.elapsed()); + + println!("Decode file ..."); + let start = Instant::now(); + decode(&encoded_file_path, &decoded_file_path).unwrap(); + println!("Decoding time: {:?}", start.elapsed()); +} + +fn main() { + run(); +} diff --git a/huffman_codes/src/lib.rs b/huffman_codes/src/lib.rs new file mode 100644 index 0000000..956e512 --- /dev/null +++ b/huffman_codes/src/lib.rs @@ -0,0 +1,2 @@ +pub mod tree; +pub mod algorithms; \ No newline at end of file diff --git a/huffman_codes/src/tree.rs b/huffman_codes/src/tree.rs new file mode 100644 index 0000000..c2c74e1 --- /dev/null +++ b/huffman_codes/src/tree.rs @@ -0,0 +1,190 @@ +use std::{cmp::Reverse, collections::HashMap}; + + +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +pub enum Direction { + Left, + Right, +} + +impl Direction { + pub fn other(&self) -> Self { + match self { + Self::Left => Self::Right, + Self::Right => Self::Left + } + } +} + +impl From for u32 { + fn from(dir: Direction) -> u32 { + match dir { + Direction::Left => 0, + Direction::Right => 1, + } + } +} + +impl From for Direction { + fn from(a: u32) -> Direction { + match a { + 0 => Direction::Left, + _ => Direction::Right, + } + } +} + +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +pub enum Node { + Leaf { + value: u8, + weight: u32, + }, + Inner { + l: Box, + r: Box, + weight: u32, + } +} + +impl Node { + pub fn huffman_tree(mut nodes: Vec) -> Option { + loop { + nodes.sort_by_key(|n| Reverse(n.weight())); + + match (nodes.pop(), nodes.pop()) { + (Some(right), Some(left)) => nodes.push(Node::from_children(left, right)), + (Some(root), None) => return Some(root), + _ => return None + } + } + } + + pub fn from_children(l: Node, r: Node) -> Self { + let weight = l.weight() + r.weight(); + Self::Inner { + l: Box::new(l), + r: Box::new(r), + weight,} + } + + pub fn value(&self) -> Option { + match self { + Self::Inner { .. } => None, + Self::Leaf { value, ..} => Some(*value), + } + } + + pub fn weight(&self) -> u32 { + match self { + Self::Inner { weight, .. } => *weight, + Self::Leaf { weight, ..} => *weight, + } + } + + pub fn get_child(&self, dir: Direction) -> Option<&Self> { + match self { + Self::Inner { l, r, ..} => { + match dir { + Direction::Left => Some(l.as_ref()), + Direction::Right => Some(r.as_ref()), + } + }, + Self::Leaf { .. } => None + } + } + + pub fn is_leaf(&self) -> bool { + matches!(self, Self::Leaf { .. }) + } + + pub fn generate_dict(&self) -> HashMap { + let mut encoding_dictionary = HashMap::::new(); + + for (node, path) in NodeIter::new(self) { + if node.is_leaf() { + let path: Vec = path.iter().map(|(_, dir)| *dir).collect::>(); + let mut numeric_repr: u32 = 0u32; + let mut bit_len: u32 = 0u32; + for dir in path { + numeric_repr |= u32::from(dir) << bit_len; + bit_len += 1; + } + encoding_dictionary.insert(node.value().unwrap(), (numeric_repr, bit_len)); + } + } + + encoding_dictionary + } +} + +#[derive(Debug, Clone)] +pub struct NodeIter<'a>{ + pub current_node: Option<&'a Node>, + pub path: Vec<(&'a Node, Direction)>, +} + +impl<'a> NodeIter<'a> { + pub fn new(root: &'a Node) -> Self { + NodeIter { + current_node: Some(root), + path: vec![], + } + } +} + +impl<'a> Iterator for NodeIter<'a> { + type Item = (&'a Node, Vec<(&'a Node, Direction)>); + + fn next(&mut self) -> Option { + if let Some(current_node) = self.current_node { + let return_item = (current_node, self.path.clone()); + + match ¤t_node { + Node::Inner { l, .. } => { + // Try to go further down, to the left. The right case will be handled by the leaf case. + self.path.push((current_node, Direction::Left)); + self.current_node = Some(l.as_ref()); + } + Node::Leaf{ .. } => { + loop { + if let Some((parent, last_direction)) = self.path.pop() { + if let Node::Inner { .. } = &parent { + // Try to go right, or else go up + if last_direction == Direction::Right { + // Go up. + self.current_node = Some(parent); + } else if last_direction == Direction::Left { + // go on the right. + self.path.push((parent, Direction::Right)); + self.current_node = parent + .get_child(Direction::Right); + break; + } + } + } else { + self.current_node = None; + return Some(return_item); + } + } + } + } + + return Some(return_item); + } + + None + } +} + +impl<'a> IntoIterator for &'a Node { + type Item = (&'a Node, Vec<(&'a Node, Direction)>); + type IntoIter = NodeIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + Self::IntoIter { + current_node: Some(self), + path: vec![], + } + } +} diff --git a/test.txt b/test.txt index d34926c..cb28d1c 100644 --- a/test.txt +++ b/test.txt @@ -1,7 +1,9 @@ -abra-ca-dabra -anxli7s34vartc4l74ix3fyq940afvc98pwexnqwlaheckms -lorem ipsum sit dolor amet -abu baren cudai marei inomo repel +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas posuere vehicula metus id convallis. Etiam consequat ut quam non hendrerit. Nullam sit amet lobortis quam. Aliquam rhoncus feugiat pellentesque. Fusce dictum sem at mauris hendrerit bibendum. Integer vitae nisl nisl. Suspendisse potenti. Vestibulum mollis dui eget facilisis laoreet. Pellentesque nec odio interdum, pharetra nisl a, luctus magna. Aliquam erat volutpat. +Suspendisse eu ligula dui. Praesent auctor urna volutpat, sollicitudin turpis non, tempus justo. Nulla malesuada ex ac aliquam laoreet. Integer aliquet nisl egestas finibus mattis. Duis at congue massa. Vivamus sed mi eget turpis imperdiet venenatis. Curabitur pulvinar lectus enim, ac convallis nulla imperdiet eu. Cras ultrices feugiat nisl, quis aliquet elit maximus quis. Cras scelerisque ac nisl vel venenatis. -chap cahrom ri ele mono si dira \ No newline at end of file +Etiam vel risus diam. Proin pellentesque purus eget augue commodo, a aliquam odio fermentum. Quisque maximus convallis egestas. Aliquam tempus sed arcu eget varius. Sed libero nulla, tempor hendrerit nulla ut, scelerisque molestie ligula. Aliquam erat volutpat. Vestibulum ut nulla magna. Integer id facilisis diam, ac viverra erat. Praesent molestie consectetur lacus, et auctor eros rhoncus eget. Donec arcu turpis, dictum dignissim condimentum rhoncus, ornare non massa. In facilisis, justo eget aliquam placerat, mi magna lacinia eros, ac pretium velit nibh id metus. Nulla vel diam eget augue auctor elementum. Praesent porta sodales arcu id sollicitudin. + +Sed eget orci eu purus fringilla ullamcorper. Cras consequat arcu ac tincidunt cursus. Donec lorem ex, lobortis nec sapien eu, consectetur pretium tellus. Proin accumsan quam nisi. Nullam viverra ante vitae sapien convallis, eget tempor diam fringilla. Nulla eu bibendum risus, vehicula venenatis metus. In tortor dui, tincidunt imperdiet molestie sed, pharetra ut enim. Fusce hendrerit placerat sem ac blandit. Proin condimentum sapien quis justo finibus sodales. Phasellus vestibulum tristique ex at commodo. Integer scelerisque justo ut felis accumsan vulputate. Nulla ac imperdiet turpis, non ultricies leo. + +Fusce vitae felis eget nisi semper dapibus sed ut tortor. Duis euismod laoreet justo, quis cursus lectus pulvinar ut. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque feugiat erat ut erat pellentesque semper. Fusce et mauris ac tortor rhoncus tincidunt et et velit. Vivamus bibendum eros urna, eu fringilla nunc blandit sed. Pellentesque non quam id lorem euismod porttitor mattis non sem. Etiam dictum dapibus massa malesuada placerat. Duis pharetra tristique lacus vel vestibulum. Duis non libero molestie, tristique velit vitae, lobortis turpis. Curabitur luctus ante quis tortor luctus dignissim ac ac enim. \ No newline at end of file diff --git a/test.txt.base64 b/test.txt.base64 deleted file mode 100644 index 7775107..0000000 --- a/test.txt.base64 +++ /dev/null @@ -1,7 +0,0 @@ -YWJyYS1jYS1kYWJyYQ== -YW54bGk3czM0dmFydGM0bDc0aXgzZnlxOTQwYWZ2Yzk4cHdleG5xd2xhaGVja21z -bG9yZW0gaXBzdW0gc2l0IGRvbG9yIGFtZXQ= -YWJ1IGJhcmVuIGN1ZGFpIG1hcmVpIGlub21vIHJlcGVs - - -Y2hhcCBjYWhyb20gcmkgZWxlIG1vbm8gc2kgZGlyYQ== \ No newline at end of file diff --git a/test.txt.base64.txt b/test.txt.base64.txt deleted file mode 100644 index d34926c..0000000 --- a/test.txt.base64.txt +++ /dev/null @@ -1,7 +0,0 @@ -abra-ca-dabra -anxli7s34vartc4l74ix3fyq940afvc98pwexnqwlaheckms -lorem ipsum sit dolor amet -abu baren cudai marei inomo repel - - -chap cahrom ri ele mono si dira \ No newline at end of file