//Builds a DAABitArray with the Huffman tree from the entered text. private bool buildStream(DAABitArray binaryStream, string input, List <HuffLeafNode> leafNodePtrs) { bool found, noSymbol, outputOnce; found = noSymbol = outputOnce = false; foreach (char ch in input) //Iterate through each symbol in entered text. { for (int i = 0; i < leafNodePtrs.Count; i++) { if (leafNodePtrs[i].getSymbol() == ch) //Find the symbol that matches the char. { for (int ii = 0; ii < leafNodePtrs[i].huffCode.NumBits; ii++) //Add the huffman code to the binary stream one bit at a time. { binaryStream.Append(leafNodePtrs[i].huffCode.GetBitAsBool(ii)); } found = true; } } if (found == false && outputOnce == false && ch != '\r') //Test if symbol rxidtd in the frequency table. { MessageBox.Show("Symbol '" + ch + "' does not exist. Please check data input."); noSymbol = true; outputOnce = true; //Used to only output the above error message once. } found = false; } return(noSymbol); }
/// Converts the scrambled alphanumeric values provided into a bitset /// which will be used to parse through the Huffman Tree. private DAABitArray ConvertTextToBits(char[] charArray) { DAABitArray bitArray = new DAABitArray(); int temp; String binary = ""; String bitString = ""; foreach (char c in charArray) { temp = CharToDecimal(c); bitString = Convert.ToString(temp, 2); /// Append leading 0's, removed from the ToString() function while (bitString.Length < 6) { bitString = "0" + bitString; } binary += bitString; } foreach (char d in binary.ToCharArray()) { if (d == '0') bitArray.Append(false); else bitArray.Append(true); } return bitArray; }
/// <summary> /// Append another bit array to the end of this bit array. /// </summary> /// <param name="bitSet">The bit array to append.</param> public void Append(DAABitArray bitSet) { for (int ii = 0; ii < bitSet.NumBits; ii++) { m_bits.Add(bitSet.GetBitAsBool(ii)); } }
//Converts alphanumeric cipher to binary to original text. private string decompress(String compressedText, List <HuffLeafNode> leafNodePtrs) { CompressDepress deCompressor = new CompressDepress(); //Object to manage depression/compression. DAABitArray deCompStream = deCompressor.decompressCipher(compressedText); //Convert alphanumeric compressed text to binary stream. string deCompString = deCompressor.decompressStream(deCompStream, leafNodePtrs); //Convert binary stream to text through Huffman tree. return(deCompString); }
/// <summary> /// Append another bit array to the end of this bit array. /// Amended to return the array for simpler recursion. /// </summary> /// <param name="bitSet">The bit array to append.</param> /// <returns>Itself</returns> public DAABitArray Append(DAABitArray bitSet) { for (int ii = 0; ii < bitSet.NumBits; ii++) { m_bits.Add(bitSet.GetBitAsBool(ii)); } return(this); }
}; //Array containing the cipher values. //Converts binary stream to alphanumeric cipher. public string compress(DAABitArray binaryStream) { string compressedStream = ""; for (int i = 5; i < binaryStream.NumBits; i = i + 6) //Iterate through every six bits. { compressedStream = compressedStream + alphanumerics[binaryStream.GetBitRange(i - 5, i)]; //Add alphanumeric to output stream. } return(compressedStream); }
//Converts DAABitArray object to string. Used for debugging. private String outputBitArray(DAABitArray input) { string tempBitString = ""; for (int i = 0; i < input.NumBits; i++) { tempBitString = tempBitString + input.GetBitAsLong(i); } return(tempBitString); }
/// <summary> /// A function for encoding a BitArray given a node (which is retrieved from a dictionary of characters). /// Returns the array vertibam if this node is the root. /// </summary> /// <param name="bits">The array you're appending your bit to</param> /// <returns>The array with the bits of all parents nodes and this node appended</returns> public override DAABitArray encode(DAABitArray bits) { DAABitArray returnbits; if (parent == null) { returnbits = bits; } else { returnbits = parent.encode(bits).Append(bit); } return(returnbits); }
//Determine if two DAABitArray objects are equal. private bool bitArraysEqual(DAABitArray input1, DAABitArray input2) { string tempBitString1 = ""; string tempBitString2 = ""; for (int i = 0; i < input1.NumBits; i++) //Convert both DAABitArray objects to strings. { tempBitString1 = tempBitString1 + input1.GetBitAsLong(i); } for (int j = 0; j < input2.NumBits; j++) { tempBitString2 = tempBitString2 + input2.GetBitAsLong(j); } return(tempBitString1 == tempBitString2); //Test if strings are equal. }
//Converts binary stream to alphanumeric cipher. private string compress(DAABitArray binaryStream) { int mod; CompressDepress compressor = new CompressDepress(); //Object to manage depression/compression. mod = binaryStream.NumBits % 6; //Test if divisible by 6. if (mod != 0) //Pad bit stream with 0's until a multiple of 6. { for (int i = 0; i < 6 - mod; i++) { binaryStream.Append(0); } } return(compressor.compress(binaryStream)); }
//Converts alphanumeric cipher to binary stream. public DAABitArray decompressCipher(String compressedText) { DAABitArray decompStream = new DAABitArray(); foreach (char ch in compressedText) //Iterate through each character of the alphanumeric code. { for (int i = 0; i < alphanumerics.Length; i++) //Find the character in the alphanumeric array. { if (alphanumerics[i] == ch.ToString()) { decompStream.Append(i, 6); //Add equivalent six bit code to bit stream. } } } return(decompStream); }
private void btnCompress_Click(object sender, RoutedEventArgs e) { List <SymbolFreq> freqTbl = new List <SymbolFreq>(); //Contains the symbol frequency table. List <HuffLeafNode> leafNodePtrs = new List <HuffLeafNode>(); //Contains references to the leaf objects. DAABitArray binaryStream = new DAABitArray(); bool noSymbol; if (String.IsNullOrEmpty(txtPlain.Text)) //Check if text to compress. { MessageBox.Show("No text to compress."); } else { if (String.IsNullOrEmpty(txtFreqTbl.Text)) //Check if a frequency table loaded. { if (MessageBox.Show("No Frequency table loaded, Generate?", "Frequency Table", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK) //Ask user if they want a frequency table generated. { txtCompressed.Text = ""; txtDecompressed.Text = ""; createFreqTbl(txtPlain.Text, freqTbl); //Create freq table. outFreqTbl(freqTbl); //Output table to form. buildHuff(freqTbl, leafNodePtrs); //Create Huffman tree. noSymbol = buildStream(binaryStream, txtPlain.Text, leafNodePtrs); //Build the full binary stream. if (noSymbol == false) //If a symbol(s) are found that don't exist, don't continue. { txtCompressed.Text = compress(binaryStream); //Compress. } } } else { txtCompressed.Text = ""; txtDecompressed.Text = ""; loadFreqTbl(txtFreqTbl.Text, freqTbl); //Create freq table. Updates it if it has been modified. outFreqTbl(freqTbl); //Output table to form. buildHuff(freqTbl, leafNodePtrs); //Create Huffman tree. noSymbol = buildStream(binaryStream, txtPlain.Text, leafNodePtrs); //Build the full binary stream. if (noSymbol == false) //If a symbol(s) are found that doesn't exist, don't continue. { txtCompressed.Text = compress(binaryStream); //Compress. } } } }
//Converts binary stream to uncompressed text. public string decompressStream(DAABitArray decompStream, List <HuffLeafNode> leafNodePtrs) { DAABitArray tempBitArray = new DAABitArray(); string decompString = ""; for (int i = 0; i < decompStream.NumBits; i++) //Iterate through each bit of bit stream. { tempBitArray.Append(decompStream.GetBitAsBool(i)); //Add one bit to temp bit stream. for (int j = 0; j < leafNodePtrs.Count; j++) //Compare temp bit stream to each leaf node of huffman tree. { if (bitArraysEqual(tempBitArray, leafNodePtrs[j].getHashCode()) == true) //If symbol found, add character to output string. { tempBitArray = new DAABitArray(); decompString = decompString + leafNodePtrs[j].getSymbol(); } } } return(decompString); }
/// <summary> /// A recursive function for decoding a BitArray. /// It pops off the top bit and passes to it's child, returning it's value. /// </summary> /// <param name="bits">The array you are decoding.</param> /// <returns>The symbol of the array.</returns> public override char decode(DAABitArray bits) { HuffmanTreeNode node; char returnsymbol; if (bits.NumBits == 0) { returnsymbol = (char)(0); } else if (bits.pop()) { returnsymbol = left.decode(bits); } else { returnsymbol = right.decode(bits); } return(returnsymbol); }
public string Interpertation(DAABitArray inDAABitArray) { string output = ""; /*how many bits are from the DAABitArray*/ int numBit = inDAABitArray.NumBits; /*for every 6 bits from the DAABitArray need to be converted*/ long bitRange; for (int i = 0; i < numBit - 5; i += 6) { bitRange = inDAABitArray.GetBitRange(i, i + 5); output += Selection(bitRange); } /*add the bits if the number of bit is not multiple of 6*/ int shiftNum, startPoint; long addBit = 0; if (numBit % 6 != 0) { /*check how many bits we need fill in*/ startPoint = numBit - numBit % 6; /*check where it need start fill in*/ shiftNum = 6 - numBit % 6; /*call the function form the DAABitarray to fill in*/ addBit = inDAABitArray.GetBitRange(startPoint, numBit - 1); output += Selection(addBit << shiftNum); } return(output); }
/// Parses the Huffman tree to retrieve symbol values of the /// provided bitset. private String ParseTree(Node n, DAABitArray bitArray) { String finalString = ""; Node temp = n; while (bitArray.GetCount() > 0) { while (temp.IsBranch()) { if (bitArray.GetBitAsBool(0)) { temp = temp.GetRight(); bitArray.RemoveFirstBit(); } else { temp = temp.GetLeft(); bitArray.RemoveFirstBit(); } } finalString += temp.GetSymbol(); temp = n; } return finalString; }
/// <summary> /// Event handler for when the Compress button is clicked. /// Uses the frequency table to build a HuffmanTree and a Dictionary of nodes /// then converts the symbols to DAABitArrays using the Dictionary to find the node. /// Also appends 0 bits to make the entire bit sequence divisable by 6. /// The frequency table must be the same as the one to encode it or bad things happen. /// </summary> /// <param name="sender">Event Stuff (Don't ask me, I didn't put it there?</param> /// <param name="e">State information</param> private void btnCompress_Click(object sender, RoutedEventArgs e) { //try { string[] freqStringList = txtFreqTbl.Text.Split('\n'); List<Frequency> frequencies = new List<Frequency>(); foreach (string s in freqStringList) { frequencies.Add(new Frequency(s)); } Dictionary<char, HuffmanTreeNodeLeaf> dict = new Dictionary<char, HuffmanTreeNodeLeaf>(); HuffmanTreeNodeComposite root = HuffmanTreeNode.HuffmanTreeFactory(frequencies, dict); DAABitArray bits = new DAABitArray(); string converted = ""; foreach (char character in txtPlain.Text) { DAABitArray append = new DAABitArray(); bits.Append(dict[character].encode(append)); } while (bits.NumBits % 6 != 0) { bits.Append(false); } int index = 0; while (index <= bits.NumBits - 6) { converted = converted + bits.SixToChar(index); index = index + 6; } txtCompressed.Text = converted; } //catch (Exception ex) { // MessageBox.Show(ex.Message); } }
/// <summary> /// Event handler for when the Compress button is clicked. /// Uses the frequency table to build a HuffmanTree and a Dictionary of nodes /// then converts the symbols to DAABitArrays using the Dictionary to find the node. /// Also appends 0 bits to make the entire bit sequence divisable by 6. /// The frequency table must be the same as the one to encode it or bad things happen. /// </summary> /// <param name="sender">Event Stuff (Don't ask me, I didn't put it there?</param> /// <param name="e">State information</param> private void btnCompress_Click(object sender, RoutedEventArgs e) { //try { string[] freqStringList = txtFreqTbl.Text.Split('\n'); List <Frequency> frequencies = new List <Frequency>(); foreach (string s in freqStringList) { frequencies.Add(new Frequency(s)); } Dictionary <char, HuffmanTreeNodeLeaf> dict = new Dictionary <char, HuffmanTreeNodeLeaf>(); HuffmanTreeNodeComposite root = HuffmanTreeNode.HuffmanTreeFactory(frequencies, dict); DAABitArray bits = new DAABitArray(); string converted = ""; foreach (char character in txtPlain.Text) { DAABitArray append = new DAABitArray(); bits.Append(dict[character].encode(append)); } while (bits.NumBits % 6 != 0) { bits.Append(false); } int index = 0; while (index <= bits.NumBits - 6) { converted = converted + bits.SixToChar(index); index = index + 6; } txtCompressed.Text = converted; } //catch (Exception ex) { // MessageBox.Show(ex.Message); } }
/// <summary> /// Event handler for when the Decompress button is clicked. /// Uses the frequency table to build a HuffmanTree then uses that tree to decode the data. /// The frequency table must be the same as the one to encode it or bad things happen. /// </summary> /// <param name="sender">Event Stuff (Don't ask me, I didn't put it there?</param> /// <param name="e">State information</param> private void btnDecompress_Click(object sender, RoutedEventArgs e) { try { string[] freqStringList = txtFreqTbl.Text.Split('\n'); List <Frequency> frequencies = new List <Frequency>(); foreach (string s in freqStringList) { frequencies.Add(new Frequency(s)); } HuffmanTreeNodeComposite root = HuffmanTreeNode.HuffmanTreeFactory(frequencies, new Dictionary <char, HuffmanTreeNodeLeaf>()); Dictionary <char, DAABitArray> dict = new Dictionary <char, DAABitArray>(); for (int ii = 0; ii < 64; ii++) { long x = (long)ii; DAABitArray bits = new DAABitArray(); bits.Append(x, 6); dict.Add(DAABitArray.encoding[ii], bits); } DAABitArray encodedBits = new DAABitArray(); foreach (char character in txtCompressed.Text) { encodedBits.Append(dict[character]); } string decoded = ""; while (encodedBits.NumBits > 0) { decoded = decoded + root.decode(encodedBits).ToString(); } txtPlain.Text = decoded; } catch (Exception ex) { MessageBox.Show(ex.Message); } }
/// <summary> /// Append another bit array to the end of this bit array. /// Amended to return the array for simpler recursion. /// </summary> /// <param name="bitSet">The bit array to append.</param> /// <returns>Itself</returns> public DAABitArray Append(DAABitArray bitSet) { for (int ii = 0; ii < bitSet.NumBits; ii++) { m_bits.Add(bitSet.GetBitAsBool(ii)); } return this; }
/// <summary> /// A function for decoding a BitArray. /// When this function is called the symbol of the leaf is return and the recursion unwinds /// </summary> /// <param name="bits">The array you are decoding.</param> /// <returns>The symbol of this leafnode.</returns> public override char decode(DAABitArray bits) { return(symbol); }
/// <summary> /// A function for encoding a BitArray given a node (which is retrieved from a dictionary of characters) /// </summary> /// <param name="bits">The array you're appending your bit to</param> /// <returns>The array with the bits of all parents nodes and this node appended</returns> public override DAABitArray encode(DAABitArray bits) { return(parent.encode(bits).Append(bit)); }
/// <summary> /// Event handler for when the Decompress button is clicked. /// Uses the frequency table to build a HuffmanTree then uses that tree to decode the data. /// The frequency table must be the same as the one to encode it or bad things happen. /// </summary> /// <param name="sender">Event Stuff (Don't ask me, I didn't put it there?</param> /// <param name="e">State information</param> private void btnDecompress_Click(object sender, RoutedEventArgs e) { try { string[] freqStringList = txtFreqTbl.Text.Split('\n'); List<Frequency> frequencies = new List<Frequency>(); foreach (string s in freqStringList) { frequencies.Add(new Frequency(s)); } HuffmanTreeNodeComposite root = HuffmanTreeNode.HuffmanTreeFactory(frequencies, new Dictionary<char, HuffmanTreeNodeLeaf>()); Dictionary<char, DAABitArray> dict = new Dictionary<char, DAABitArray>(); for (int ii = 0; ii < 64; ii++) { long x = (long)ii; DAABitArray bits = new DAABitArray(); bits.Append(x, 6); dict.Add(DAABitArray.encoding[ii], bits); } DAABitArray encodedBits = new DAABitArray(); foreach (char character in txtCompressed.Text) { encodedBits.Append(dict[character]); } string decoded = ""; while (encodedBits.NumBits > 0) { decoded = decoded + root.decode(encodedBits).ToString(); } txtPlain.Text = decoded; } catch (Exception ex) { MessageBox.Show(ex.Message); } }
private void btnCompress_Click(object sender, RoutedEventArgs e) { /*the user should type sth in the plain text*/ if (txtPlain.Text == "" && txtFreqTbl.Text == "" || txtPlain.Text == "") { MessageBox.Show("Please type something in the plain text "); } else if (txtFreqTbl.Text == "") { MessageBox.Show("Please click the Freq calc button first "); } else /*start parse the input*/ { int value; /*get the input if the user input sth form the symbol table*/ string inFreqTbl = txtFreqTbl.Text; var inDict = new Dictionary <char, int>(); /*remove the whitesaper at the start or end*/ string theFreqTbl = inFreqTbl.Trim(); bool formatError = false; /*Loops for each new line in the symbol table box*/ foreach (string aLine in theFreqTbl.Split('\n')) { /*use the ":" to spilt every string*/ string[] a = aLine.Split(':'); char[] key = a[0].ToCharArray(); /*when some incorrect type in the symbol table then show the message to user */ try { if (key[0] == '\\') { key[0] = '\n'; } int.TryParse(a[1], out value); /*when the use type something in the symbol table should type a positive number and the format like a:5*/ double sqrt = Math.Sqrt(value); if (sqrt.Equals(Double.NaN) || !int.TryParse(a[1], out value)) { throw (new Exception("Negative frequency ")); } /*can not input duplicate key */ inDict.Add(key[0], value); } catch { MessageBox.Show("Incorrect input,can not type negative frequency or duplicate character, the format should like 'char:int'"); formatError = true; } } if (!formatError) { HuffmanTree tree = new HuffmanTree(inDict); IDictionary <char, string> encodings = tree.CreateEncodings(); /* converts the characters in plain text to an array*/ char[] txtplain = txtPlain.Text.ToCharArray(); string huffstring = ""; string wrongSymbol = ""; bool error = false; /*loop all the char in plaintext convert into its huffman code*/ foreach (char pChar in txtplain) { /* Check the char in plaintext as a key in the huffman dictionary*/ bool correctkey = false; if (encodings.ContainsKey(pChar)) { correctkey = true; } else /*// the character does not have huffman code*/ { error = true; wrongSymbol += pChar + " "; } if (correctkey) { huffstring += encodings[pChar]; } } if (error) { MessageBox.Show(wrongSymbol + " can not compress this character, please try another one"); } DAABitArray newBitArray = new DAABitArray(); int huffInt; /*loops all bits in the huffstring to single ints that can add to the DAABitArray*/ foreach (char huffchar in huffstring) { huffInt = (int)Char.GetNumericValue(huffchar); newBitArray.Append(huffInt); } /* Call the textInterpretation and output the result on compressed text*/ TextInterpretation newTextInter = new TextInterpretation(); txtCompressed.Text = newTextInter.Interpertation(newBitArray); } } }
/// <summary> /// Copy constructor /// </summary> public DAABitArray(DAABitArray other) { m_bits = new List <bool>(other.m_bits); }
/// When the message is encoded, a '1' is added to the bitset, /// followed by a series of '0's to buffer the bitset into sections /// of 6 bits each (% 6). This function removes this buffer to /// provide the original bitset. private DAABitArray RemoveBuffer(DAABitArray bitArray) { while (!bitArray.GetBitAsBool(bitArray.GetCount() -1)) { bitArray.RemoveLastBit(); /// Remove '0's } bitArray.RemoveLastBit(); /// Remove '1' return bitArray; }
/// <summary> /// A function for encoding a BitArray given a node (which is retrieved from a dictionary of characters) /// </summary> /// <param name="bits">The array you're appending your bit to</param> /// <returns>The array with the bits of all parents nodes and this node appended</returns> public override DAABitArray encode(DAABitArray bits) { return parent.encode(bits).Append(bit); }
/// <summary> /// A recursive function for decoding a BitArray. /// If the node is a composite it pops off the top bit and passes to it's child, returning it's value. /// Otherwise if it is a leaf it returns it's symbol. /// </summary> /// <param name="bits">The array you are decoding.</param> /// <returns>The symbol of the array.</returns> public abstract char decode(DAABitArray bits);
/// <summary> /// A function for decoding a BitArray. /// When this function is called the symbol of the leaf is return and the recursion unwinds /// </summary> /// <param name="bits">The array you are decoding.</param> /// <returns>The symbol of this leafnode.</returns> public override char decode(DAABitArray bits) { return symbol; }
/// <summary> /// A function for encoding a BitArray given a node (which is retrieved from a dictionary of characters). /// Returns the array vertibam if this node is the root. /// </summary> /// <param name="bits">The array you're appending your bit to</param> /// <returns>The array with the bits of all parents nodes and this node appended</returns> public override DAABitArray encode(DAABitArray bits) { DAABitArray returnbits; if (parent == null) returnbits = bits; else returnbits = parent.encode(bits).Append(bit); return returnbits; }
/// <summary> /// A recursive function for decoding a BitArray. /// It pops off the top bit and passes to it's child, returning it's value. /// </summary> /// <param name="bits">The array you are decoding.</param> /// <returns>The symbol of the array.</returns> public override char decode(DAABitArray bits) { HuffmanTreeNode node; char returnsymbol; if (bits.NumBits == 0) returnsymbol = (char)(0); else if (bits.pop()) { returnsymbol = left.decode(bits); } else { returnsymbol = right.decode(bits); } return returnsymbol; }
/// <summary> /// A recursive function for encoding a BitArray given a node (which is retrieved from a dictionary of characters). /// </summary> /// <param name="bits">The array you're appending your bit to</param> /// <returns>The array with the bits of all parents nodes and this node appended</returns> public abstract DAABitArray encode(DAABitArray bits);
/// <summary> /// Copy constructor /// </summary> public DAABitArray(DAABitArray other) { m_bits = new List<bool>(other.m_bits); }