public byte[] Compression(char[] textToEncrypt, string originalName) { //Calculamos la tabla: List <NodeTable> table = GenerateTable(textToEncrypt); //Incicializamos una cola e insertamos los valores: HuffQueue <NodeTable> queue = new HuffQueue <NodeTable>(); AddToQueue(table, queue); //Agregamos al árbol de Huffman: HuffTree tree = new HuffTree(); tree.Insert(queue, tree); //Agregar al árbol, las codificaciones: tree.AddBinary(tree.rootOriginal, 0, ""); //Añadimos a la tabla las codificaciones de cada caracter en su lugar correspondiente: //Para eso debemos llenar una lista con los caracteres y codificaciones del árbol: List <NodeTable> auxiliar = new List <NodeTable>(); tree.BinarysIncludes(tree.rootOriginal, auxiliar); //Ya con la lista, se lo agregamos a la "table": for (int i = 0; i < auxiliar.Count; i++) { for (int j = 0; j < table.Count; j++) { if (auxiliar[i].character == table[j].character) { table[j].binary = auxiliar[i].binary; } } } //Escribimos la codificación en lugar del texto original: string result = ""; StringBuilder concatenar = new StringBuilder(); for (int i = 0; i < textToEncrypt.Length; i++) { for (int j = 0; j < table.Count; j++) { if (textToEncrypt[i].ToString() == table[j].character) { //result += table[j].binary; concatenar.Append(table[j].binary); } } } result = concatenar.ToString(); //Separaramos por 8 bits y si no completa, agregar ceros: List <string> bytes = SeparateBytes(result); //Convertimos los bytes a decimales y los agregamos a otra lista: List <int> decimals = new List <int>(); for (int i = 0; i < bytes.Count; i++) { decimals.Add(ConvertBinaryToDecimal(bytes[i])); } // // // List <byte> oName = BytesToOriginalName(originalName); // // // //Mandamos a escribir todo el texto (incluyendo su metadata): byte[] response = ReturnBytesToWrite(table, decimals, oName); return(response); }
public List <char> Decompression(List <byte> bytes) { int startOfCompressedText = 0; //La primera posición del arreglo nos dirá cuántos carateres diferentes tiene: int diferentsCharacters = bytes[0]; //La segunda posición del arreglo nos dirá cuántos bytes ocupan las frecuencias: int bytesOfFrequencies = bytes[1]; //Se valida cuántos son: List <NodeTable> table = new List <NodeTable>(); //Si solo ocupan 1 byte, entonces... if (bytesOfFrequencies == 1) { int numberToReadMetadata = (diferentsCharacters * 2) + 1; startOfCompressedText = numberToReadMetadata; for (int i = 2; i <= numberToReadMetadata; i++) { //Leemos primero los caracteres: char character = (char)bytes[i]; i++; int frequency = bytes[i]; //Agregamos a la "table": NodeTable aux = new NodeTable { character = character.ToString(), frequency = frequency }; table.Add(aux); } } //Si ocupan 2 bytes, entonces... else if (bytesOfFrequencies == 2) { int numberToReadMetadata = (diferentsCharacters * 3) + 1; startOfCompressedText = numberToReadMetadata; for (int i = 2; i < numberToReadMetadata; i++) { //Leemos primero los caracteres: char character = (char)bytes[i]; i++; //Ya que las frecuencias ocupan dos bytes, debemos: //Primero: Convertir la 2da. y 3ra. posición a bytes int frequency1 = bytes[i]; i++; int frequency2 = bytes[i]; //Segundo: Ya convertidos a bytes, ambos se deben convertir a binarios string binary1 = ConvertDecimalToBinary(frequency1); if (binary1 == "") { binary1 = "0"; } string binary2 = ConvertDecimalToBinary(frequency2); if (binary2.Length < 8) { string copy = binary2; binary2 = ""; int restant = 8 - copy.Length; for (int j = 0; j < restant; j++) { binary2 += "0"; } binary2 += copy; } //Tercero: Concatenamos los dos binarios, para formar uno solo string resultantBinary = binary1 + binary2; //Cuarto: Convertimos el binario en decimal para obtener la frecuencia total int frequencyTotal = ConvertBinaryToDecimal(resultantBinary); //Agregamos a la "table": NodeTable aux = new NodeTable { character = character.ToString(), frequency = frequencyTotal }; table.Add(aux); } } //Se llena la tablita con sus probabilidades y se vuelve a hacer todo el proceso de la cola y el árbol, etc... //Se calcula la probabilidad de cada caracter: double totalFrequency = 0; for (int i = 0; i < table.Count; i++) { totalFrequency += table[i].frequency; } for (int i = 0; i < table.Count; i++) { table[i].probability = table[i].frequency / totalFrequency; } //Incicializamos una cola e insertamos los valores: HuffQueue <NodeTable> queue = new HuffQueue <NodeTable>(); AddToQueue(table, queue); //Agregamos al árbol de Huffman: HuffTree tree = new HuffTree(); tree.Insert(queue, tree); //Agregar al árbol, las codificaciones: tree.AddBinary(tree.rootOriginal, 0, ""); //Añadimos a la tabla las codificaciones de cada caracter en su lugar correspondiente: //Para eso debemos llenar una lista con los caracteres y codificaciones del árbol: List <NodeTable> auxiliar = new List <NodeTable>(); tree.BinarysIncludes(tree.rootOriginal, auxiliar); //Ya con la lista, se lo agregamos a la "table": for (int i = 0; i < auxiliar.Count; i++) { for (int j = 0; j < table.Count; j++) { if (auxiliar[i].character == table[j].character) { table[j].binary = auxiliar[i].binary; } } } //Ya con toda la table hecha, procedemos a leer el texto compreso para su descompresión: string largeBinary = ""; StringBuilder aux2 = new StringBuilder(); for (int i = startOfCompressedText + 1; i < bytes.Count; i++) { //Se convierte cada decimal a binario y se agrega a un solo string con el binario largo original: string binaryIndividual = ConvertDecimalToBinary(bytes[i]); //Si el tamaño, es menor a 8, entonces se agregan 0´s al inicio: if (binaryIndividual.Length < 8) { int restants = 8 - binaryIndividual.Length; string others = ""; for (int j = 0; j < restants; j++) { others += "0"; } string ok = others + binaryIndividual; aux2.Append(ok); } else { aux2.Append(binaryIndividual); } } largeBinary = aux2.ToString(); StringBuilder aux4 = new StringBuilder(); aux4.Append(largeBinary); //Ya con la cadena larga de binario... se van haciendo comparaciones en la "table" para obtener el texto original: bool empty = false; List <char> respuesta = new List <char>(); while (!empty) { bool match = false; int counter = 0; int posMatch = 0; while (!match) { counter++; for (int i = 0; i < table.Count; i++) { if (aux4.ToString(0, counter) == table[i].binary) { char[] aux = table[i].character.ToCharArray(); respuesta.Add(aux[0]); posMatch = counter; match = true; } } } //Se elimina lo que ya se encontró: if (match) { aux4.Remove(0, posMatch); } //Se comprueba si ya se debe dejar de leer: if (respuesta.Count == totalFrequency) { empty = true; } } return(respuesta); }