import os from time import time class Node: # declaracion de variables para crear los nodos # properties probability = 0.0 # inicializamos symbol = "" encoding = "" visited = False parent = -1 # longitud de 0 a -1 class Huffman: # declaracion de variables para la creacion del arbol de Huffman Tree = None # retornar arbol Root = None # retornar raiz Nodes = [] #Lista probs = {} #bloque dictEncoder = {} # methods def __init__(self, symbols): self.initNodes(symbols) self.buildTree() self.buildDictionary() def initNodes(self, probs): # creamos los nodos con sus respectivas probabiliddes for symbol in probs: node = Node() # inicializamos el node node.symbol = symbol node.probability = probs[symbol] # asignamos una probabilidad a cada simbolo o letra node.visited = False # variable q no es fija que va ir cambiando self.Nodes.append(node) # creamos una lista por cada nodo creado self.probs[symbol]=probs[symbol] # establece para cada probabilidad un simbolo def buildTree(self): # Realizamos las operaciones de acuerdo al regamente para la construccion del arbol de Huffman indexMin1 = self.getNodeWithMinimumProb() # Buscamos el menor numero de la primera probabilidad indexMin2 = self.getNodeWithMinimumProb() # Buscamos el menor numero de la segunda probabilidad while indexMin1 != -1 and indexMin2 != -1: # != evalĂșa como verdadero si 2 variables son diferentes node = Node() # inicializamos node.symbol = "." node.encoding = "" # llamamos a las dos probabilidades minimas prob1 = self.Nodes[indexMin1].probability prob2 = self.Nodes[indexMin2].probability node.probability = prob1 + prob2 # sumamos las probabilidades node.visited = False # false = 1 node.parent = -1 # restamos la probabilidad a -1 self.Nodes.append(node) self.Nodes[indexMin1].parent = len(self.Nodes) - 1 # lista o cadena que queremos medir self.Nodes[indexMin2].parent = len(self.Nodes) - 1 # Regla: 0 a mayor probabilidad, 1 a menor probabilidad. if prob1 >= prob2: self.Nodes[indexMin1].encoding = "0" self.Nodes[indexMin2].encoding = "1" else: self.Nodes[indexMin1].encoding = "1" self.Nodes[indexMin2].encoding = "0" indexMin1 = self.getNodeWithMinimumProb() indexMin2 = self.getNodeWithMinimumProb() def getNodeWithMinimumProb(self): # realizamos una comparacion para obteener el nodo de menor probabilidad minProb = 1.0 # La minima probabilidad no puede ser mayor de 1 indexMin = -1 # indice para restar a la probalidad for index in range(0, len(self.Nodes)): # index es el numero de probabilidad if (self.Nodes[index].probability < minProb and (not self.Nodes[index].visited)): minProb = self.Nodes[index].probability indexMin = index if indexMin != -1: self.Nodes[indexMin].visited = True return indexMin def showSymbolEncoding(self, symbol): # designamos un codigo binario a cada simbolo resuelto por el arbol de Huffman found = False index = 0 encoding = "" for i in range(0, len(self.Nodes)): if self.Nodes[i].symbol == symbol: found = True index = i break if found: # encontro while index != -1: # si son diferentes encoding = "%s%s" % (self.Nodes[index].encoding, encoding) index = self.Nodes[index].parent else: encoding = "simbolo desconocido" return encoding def buildDictionary(self): # creamos un diccionario, guardamos todos los simbolos con sus respectivos codigos binarios # resueltos por el arbol de Huffman for symbol in self.probs: encoding = self.showSymbolEncoding(symbol) self.dictEncoder[symbol] = encoding def encode(self, plain): # agrupa los codigos binarios codificados de acuerdo al mensaje escrito en consola encoded = "" for symbol in plain: encoded = "%s%s" % (encoded, self.dictEncoder[symbol]) return encoded # INICIO DE LA DECODIFICACION .................................................................................................................................................... def decode(self, encoded): # recibe la cadena del codigo binario enviado desde el emisor para decodificar index = 0 decoded = "" while index < len(encoded): # mientras buscamos en la longitud de la parte codificada founf = False # establesemos una variable aux = encoded[index:] # va a buscar a cada parte codificada un simbolo # no va ser fija va ir buscando cual es compatible con cada una for symbol in self.probs: if aux.startswith(self.dictEncoder[symbol]): # se comprueba si la cadena es verdadera o falsa. si la parte axuliar inicia dentro del diccionario encodificado nos va a dar decoded = "%s%s" % (decoded, symbol) # parte decodificada index = index + len(self.dictEncoder[symbol]) # busqueda para cada simbolo a cada probabilidad break return decoded #FIN DE LA DECODIFICACION .......................................................................................................................................................... if __name__=="__main__": print ("INGRESAR LOS SIMBOLOS O UN MENSAJE QUE DESEA COMPRIMIR:") print (" " ) mensaje=input() print (" ") print ("NUMERO TOTAL DE SIMBILOS O BITS INTRODUCIDOS PARA SER ENVIADOS: %s" % (len(mensaje))) print (" ") print ("[ 1 PASO]: NUMERO DE SIMBOLOS O BITS, ERRADOS O REPETIDOS ") print (" ") simbolos='' probabilidad=[] msm=mensaje d=0 for i in mensaje: if i in msm: print (i,"=",int ( msm.count(i))) simbolos+=i probabilidad.append(float(float ( msm.count(i))/float(len(mensaje)))) msm=msm.replace(i,'') d+= 1 symbols=dict(zip(simbolos, probabilidad)) print (" ") print ("NUMERO DE SIMBOLOS COMPRIMIDOS=",d) print (" ") print ("[ 2 PASO]:PROBABILIDAD DE CADA SIMBOLO P(S)= (numero de bit errados) / (numero total de bit enviados)") print (" ") print (symbols) print (" ") print ("[ 3-4 PASO]: LA FUNCION [buildTree] DEL CODIGO. ORDENA LAS PROBABILIDADES DE MENOR A MAYOR PROBABILIDAD") print (" Y REALIZA LAS OPERACIONES YA EXPLICADAS QUE SE REQUIEREN PARA IR ARMANDO EL ARBOL DE HUFFMAN") print (" ") tiempo_inicial= time() # codificar instancia huffman = Huffman(symbols) print ("...........................................................................") print ("...........................CODIFICACION....................................") print ("...........................................................................") print (" ") print (" ") print ("[ 5 PASO]:CODIFICACION BINARIA USANDO EL ARBOL DE HUFFMAN:") print ( " ") for symbol in symbols: print ("Simbolo: %s; Codificacion: %s" % (symbol, huffman.showSymbolEncoding(symbol))) encoded = huffman.encode(mensaje) print (" ") print ("Mensaje que se esta codificando: %s;" % (mensaje)) print (" ") print ("Codificacion en bits : %s" % (encoded)) print (" ") print ("La longitud de codigo binario es: %s" % (len(encoded))) data = encoded print (" ") print ("Codigo codificado que esta siento enviado al receptor: %s" % (data)) # DECODIFICACION print (" ") print (" ") print (" ") print (" ") print ("...........................................................................") print ("...........................DECODIFICACION..................................") print ("...........................................................................") print (" ") print (" ") print ("Esperando el mensaje del emisor para su decodificacion......") decoded = huffman.decode(data) print (" ") print ("CODIGO BINARIO RECIBIDO ES :", data ) print (" ") print ("DECODIFICANDO EL CODIGO....................................") print (" ") print ("Mensaje decodificado : %s " % (decoded)) # FIN tiempo_final= time() tiempo_ejecucion= tiempo_final - tiempo_inicial print (" ") print ('El tiempo de transmisiOn es:',tiempo_ejecucion) #En segundos) os._exit(0)