コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }