diff --git a/README.md b/README.md
index 8562ca0..61cb59c 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,25 @@
 # Cat2Text-rs
 
 This is a port of [Cat2Text](https://github.com/askiiart/Cat2Text) to Rust, with extra functionality, better documentation, and support for using it as a library as well.
+
+## Base4 Format
+
+Using the original base4 format, it works like this. First off, each word is equal to a value in base 4:
+
+| Value | Cat sound |
+| ----- | --------- |
+| 0     | meow      |
+| 1     | mrrp      |
+| 2     | mreow     |
+| 3     | mrow      |
+
+Then, the text is converted into lowercase
+
+## Limitations
+
+This currently only supports lowercase text in the latin alphabet without numbers or anything - however, using `cat2text::core`, you can convert anything to meows, as long as you can put it in integers - which, you can.
+
+## TODO
+
+- Add functionality for converting `Vec<u8>` to cat.
+- Add more bases - adaptable base option?
diff --git a/src/base4.rs b/src/base4.rs
index 7738800..6453142 100644
--- a/src/base4.rs
+++ b/src/base4.rs
@@ -1,3 +1,5 @@
+use crate::core;
+
 pub fn alphabet() -> Vec<String> {
     return vec!["meow", "mrrp", "mreow", "mrow"]
         .into_iter()
@@ -10,8 +12,7 @@ pub fn char_length() -> u32 {
     return 3;
 }
 
-// TODO: Add uppercase support, maybe possible?
-pub fn encode(text: String) {
+pub fn encode(text: String) -> String {
     // makes it lowercase and split by spaces
     let words: Vec<String> = text
         .to_ascii_lowercase()
@@ -24,6 +25,16 @@ pub fn encode(text: String) {
         words_as_bytes.push(word.as_bytes().into_iter().map(|item| item - 96).collect());
     }
 
-    let translation: String = "".to_string();
-    for word in words_as_bytes {}
+    let mut results: Vec<Vec<String>> = Vec::new();
+    for i in 0..words_as_bytes.len() {
+        results.push(Vec::new());
+        for j in 0..words_as_bytes[i].len() {
+            results[i].push(core::num_to_cat(words_as_bytes[i][j] as u32, alphabet(), char_length()));
+        }
+    }
+
+    let results: Vec<String> = results.into_iter().map(|item| item.join(" ")).collect();
+    let results = results.join("; ");
+    return results;
+
 }
diff --git a/src/core.rs b/src/core.rs
index dd4bf95..9f6590c 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -1,9 +1,5 @@
 //! Handles conversion one word at a time for any base
 // based off this SO answer: https://stackoverflow.com/a/1119769
-use std::ops::Index;
-
-use crate::base4::alphabet;
-
 pub fn num_to_cat(num: u32, alphabet: Vec<String>, char_length: u32) -> String {
     let mut num: u32 = num.clone();
     let base: u32 = alphabet.len() as u32;
@@ -16,16 +12,12 @@ pub fn num_to_cat(num: u32, alphabet: Vec<String>, char_length: u32) -> String {
     }
     nums.reverse();
 
-    let mut result = "".to_string();
-    for i in nums.clone() {
-        result += alphabet[i as usize].as_str();
-        // put a space in between if it's not the last one
-        if i != nums.len() as u32 - 1 {
-            result += " "
-        }
+    let mut result: Vec<String> = Vec::new();
+    for item in nums {
+        result.push(alphabet[item as usize].clone());
     }
 
-    return result;
+    return result.join(" ");
 }
 
 /// Converts catspeak to a [`u32`]
diff --git a/src/main.rs b/src/main.rs
index 466be42..8fd3582 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -29,17 +29,8 @@ fn main() {
             stdin.read_line(&mut input).unwrap();
             println!(
                 "{}",
-                core::cat_to_num(
-                    input
-                        .trim()
-                        .to_string()
-                        .split(" ")
-                        .into_iter()
-                        .map(|item| item.to_string())
-                        .collect(),
-                    base4::alphabet(),
-                    base4::char_length()
-                )
+                base4::encode(input.trim().to_string())
+                
             );
         } else {
             println!("Invalid input, exiting...");