Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python.pythonPath": "/opt/anaconda3/bin/python"
}
111 changes: 111 additions & 0 deletions Decoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import java.util.*;
import java.io.*;

// Note: there is something wrong with the encoder that I can't quite figure out.
// every file, when encoded then decoded, begins with the binary sequence 10101100111011010000000000000101
// -Peter Shen

public class Decoder {

// name of method is self-explanatory
public static void decode(String inputFile, String outputFile) throws IOException
{
StringBuilder binaryString = new StringBuilder();
FileInputStream in = new FileInputStream(inputFile);
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(outputFile)));
byte[] byteArray = in.readAllBytes();

// converts byte array into a giant binary String
for(int i = 0; i < byteArray.length; i++)
{
binaryString.append(toBinary(byteArray[i]));
}

// sanity check: binary String for accuracy
System.out.println(binaryString);

ArrayList<Integer> binaryValues = new ArrayList<Integer>();

// converts the String of binary to an ArrayList of ints, each 9 digits long
for(int i = 0 ;i <= binaryString.length() - 9; i += 9)
{
binaryValues.add(toBinaryValue(binaryString.substring(i, i+9)));
}

// sanity check: ArrayList for accuracy
System.out.println(binaryValues);

// initial dictionary values
HashMap<Integer, String> map = new HashMap<Integer,String>();
for(int i = 0; i < 256; i++)
map.put(i, "" + (char)i);

// decoding part, involving dictionary and writing to outputFile
int nextKey = 256;
int current = binaryValues.get(0);
String str = map.get(current);
String ch = "" + str.charAt(0);
out.print(str);
for(int i = 1; i < binaryValues.size(); i++)
{
int next = binaryValues.get(i);

// adding keys to dictionary, reverse-engineering compression dictionary following LZW rules
if(!map.containsKey(next))
{
str = map.get(current);
str = str + ch;
}
else
{
str = map.get(next);
}
out.print(str);
ch = "" + str.charAt(0);
map.put(nextKey, map.get(current) + ch);
nextKey++;
current = next;
}

out.println();

out.close();
}

// converts number to a String of binary
public static String toBinary(int num)
{
String current = Integer.toBinaryString(num);
StringBuilder str = new StringBuilder();
while(current.length()+str.length() < 8)
{
str.append("0");
}
if(current.length() > 8)
{
current = current.substring(current.length() - 8);
}
str.append(current);
return str.toString();
}

// converts a binary String into an integer
public static int toBinaryValue(String str)
{
int end = 0;
for(int i = 0; i < 9; i++)
{
if(str.charAt(i) == '1')
{
end += (1 << (8 - i));
}
}
return end;
}

// tester
public static void main (String [] args) throws IOException
{
decode("encoded3.bin", "decoded.txt");
}
}
6 changes: 1 addition & 5 deletions InputFile.txt

Large diffs are not rendered by default.

80 changes: 51 additions & 29 deletions LZW.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
// import org.apache.commons.io.IOUtils;



public class LZW
{
private ArrayList<Integer> compressedAscii;
private HashMap<String, Integer> dictionary;
private HashMap<Integer, String> Invertedictionary;
// private HashMap<Integer, String> Invertedictionary;
private String fileInAString;
private ArrayList<String> inputFileInAnArrayList;
private ArrayList<String> preDictionary;
Expand All @@ -25,23 +26,24 @@ public class LZW
private ObjectInputStream is;
private BufferedReader input;
private ObjectOutputStream os;
private FileInputStream fis;

public LZW() throws Exception
{
decodedFileUnicodeValues = new ArrayList<Integer>();
dictionary = new HashMap<String, Integer>();
Invertedictionary = new HashMap<Integer, String>();
String fileName = "encoded.bin";
// Invertedictionary = new HashMap<Integer, String>();
String fileName = "encoded3.bin";
FileOutputStream fileOs = new FileOutputStream(fileName);
os = new ObjectOutputStream(fileOs);
compressedAscii = new ArrayList<Integer>();
inputFileInAnArrayList = new ArrayList<String>();
preDictionary = new ArrayList<String>();
update = new ArrayList<String>();
FileInputStream fileIS = new FileInputStream(fileName);
is = new ObjectInputStream(fileIS);
input = new BufferedReader(new FileReader("InputFile.txt"));
decodedFile = new BufferedWriter(new FileWriter("decoded.txt"));
fis = new FileInputStream(fileName);
is = new ObjectInputStream(fis);
input = new BufferedReader(new FileReader("lzw-file3.txt"));
// decodedFile = new BufferedWriter(new FileWriter("decoded2.txt"));
fileInAString = "";
}

Expand Down Expand Up @@ -92,8 +94,8 @@ else if(preDictionary.contains(temp+temp2) == true)

public void dictionaryPopulators()
{
int counter = 257;
for(int i = 0; i < 257; i++)
int counter = 256;
for(int i = 0; i < 256; i++)
{
char ascii = (char) i;
dictionary.put(Character.toString(ascii), i);
Expand All @@ -104,16 +106,7 @@ public void dictionaryPopulators()
}
//inverted dictionary is dictionary with values and keys swapped places

counter = 257;
for(int i = 0; i < 257; i++)
{
char ascii = (char) i;
Invertedictionary.put(i, Character.toString(ascii));
}
for(int k = 0; k < preDictionary.size(); k++)
{
Invertedictionary.put(counter+k, preDictionary.get(k));
}

}


Expand Down Expand Up @@ -152,23 +145,52 @@ public void convertIntValuesToBinary()throws Exception
}catch(IOException e){ }
}

for(int i = 0; i < decodedFileUnicodeValues.size(); i++)
{
int temp = decodedFileUnicodeValues.get(i);
decodedFile.write(Invertedictionary.get(temp));
}
decodedFile.close();
}

// public void decode() throws Exception
// {
// // int byteRead;
// // String decoded = "";
// // while ((byteRead = fis.read()) != -1);
// // {
// // decoded += byteRead;
// // }
// // System.out.println(decoded);
// String body = IOUtils.toString(fis, StandardCharsets.UTF_8.name());

// }

// public void decode() throws Exception
// {
// int counter = 256;
// for(int i = 0; i < 256; i++)
// {
// char ascii = (char) i;
// Invertedictionary.put(i, Character.toString(ascii));
// }
// for(int k = 0; k < preDictionary.size(); k++)
// {
// Invertedictionary.put(counter+k, preDictionary.get(k));
// }

// for(int i = 0; i < decodedFileUnicodeValues.size(); i++)
// {
// int temp = decodedFileUnicodeValues.get(i);
// decodedFile.write(Invertedictionary.get(temp));
// }
// decodedFile.close();
// }

public void fileEncoder()throws Exception
{
convertFileStringToArrayDictionary();
dictionaryPopulators();
fileCompressor();
}

public static void main(String[] args)throws Exception
{

}
public static void main(String[] args)throws Exception
{
LZW thing = new LZW();
thing.fileEncoder();
}
}
Loading