You are on page 1of 15

UNIVERSIDAD TECNICA PARTICULAR DE LOJA

La Universidad Catlica de Loja


REA TCNICA
TITULACIN DE INGENIERA EN ELECTRNICA Y
TELECOMUNICACIONES

TRANSMISIN DE DATOS
CODIFICACIN Y DECODIFICACIN DE DATOS A TRAVES DE DOS
COMPUTADORES EN PYTHON

AUTORES:
Danny Curipoma
Luis Maita

DOCENTE: Ing. Pablo Toapanta

LOJA ECUADOR
2017

Objetivo Especfico:
Desarrollar un algoritmo en Python que permita la codificacin y
decodificacin a travs de dos computadores, junto con la
visualizacin de bits transmitidos.
Objetivos Generales:

Codificar una cadena de 20 caracteres en un computador


usando la herramienta Python
Recibir los datos en un segundo para proceder a decodificarlos
en Python a travs de un puerto serie

Codificacin Hoffman
Es un algoritmo que permite la compresin de datos, con la capacidad
de representarlos en una cadena de smbolos que se obtienen gracias
a un alfabeto. Hoffman usa el menor nmero de bits posible
considerando que debe mantener un orden para la posterior
decodificacin.
Justificacin:
Hoy en da nos encontramos con la necesidad de transmitir grandes
cantidades de informacin con la condicin de la confidencialidad de
la misma, por lo cual yace la propuesta de la implementacin de un
algoritmo fiable en Python que provea la transmisin de datos; en un
computador transmisor como enlace A y un computador B como
receptor el cual tiene la capacidad de decodificar la cadena de bits
enviados por el primer computador. Por lo tanto, se realizar el envo
de una cadena de caracteres hacia un segundo computador por el
puerto ethernet y el receptor debe tener la capacidad de
interpretarlos.
Implementacin:
Para la realizacin del proyecto planteado se escogi el algoritmo
Hoffman el cual sirve para la compresin de datos, codificacin y
decodificacin de una manera ptima respecto a otros algoritmos. En
primer aspecto se realiz la codificacin de una cadena de caracteres
como lo es TRANSMISION DE DATOS dentro del lenguaje de
programacin de Python. Para la utilizacin de dos computadores
conectadas mediante el cable ethernet se utiliz las libreras
siguientes:

1er PC

Fig.1 libreras utilizadas en el algoritmo de codificacin y configuracin para la


transmisin a travs de ethernet

Como se muestra en la figura uno se puede apreciar que se hace uso


de las libreras os y socket las cuales permiten la posterior
configuracin del puerto utilizado, de la direccin y del host.
Para la configuracin inicial del primer computador se hace dentro de
redes y recursos compartidos, luego en configuracin del adaptador y
finalmente en propiedades dentro de TCP/IPv4 como se puede
apreciar a continuacin:

Fig.2 Configuracin de direccin IP en el Trasmisor

Dentro de la configuracin se usa la direccin IP de clase C con su


correspondiente mascara, lo cual permite que tenga un identificador
nico y asociar el primer computador como transmisor.
Despus de configurar el primer computador se realiza la estructura
del cdigo en Python correspondiente al algoritmo de Hoffman como
se puede ver a continuacin:

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*import os
from socket import *
host = "192.168.4.1" # set to IP address of target computer
port = 13002
addr = (host, port)
UDPSock = socket(AF_INET, SOCK_DGRAM)
class Node:
# properties
probability = 0.0
symbol = ""
encoding = ""
visited = False
parent = -1
class Huffman:
Tree = None
Root = None
Nodes = []
probs = {}
dictEncoder = {}
# methods
def __init__(self, symbols):
self.initNodes(symbols)
self.buildTree()
self.buildDictionary()
def initNodes(self, probs):
for symbol in probs:
node = Node()
node.symbol = symbol
node.probability = probs[symbol]
node.visited = False
self.Nodes.append(node)
self.probs[symbol]=probs[symbol]
def showTree(self):
print "--------------------------"
for i in range(0, len(self.Nodes)):
symbol = self.Nodes[i].symbol
prob = self.Nodes[i].probability
visited = self.Nodes[i].visited
parent = self.Nodes[i].parent
encoding = self.Nodes[i].encoding
print "[%d] Symbol= %s, Prob(%s) = %0.4f, visited=%d;
parent=%d; enc=%s" % (i, symbol, symbol, prob, visited, parent,
encoding)
def buildTree(self):
indexMin1 = self.getNodeWithMinimumProb()
indexMin2 = self.getNodeWithMinimumProb()
while indexMin1 != -1 and indexMin2 != -1:
node = Node()
node.symbol = "."
node.encoding = ""
prob1 = self.Nodes[indexMin1].probability
prob2 = self.Nodes[indexMin2].probability

node.probability = prob1 + prob2


node.visited = False
node.parent = -1
self.Nodes.append(node)
self.Nodes[indexMin1].parent = len(self.Nodes) - 1
self.Nodes[indexMin2].parent = len(self.Nodes) - 1
# rule: 0 to highest probability, 1 to lowest.
if prob1 >= prob2:
self.Nodes[indexMin1].encoding = "0"
self.Nodes[indexMin2].encoding = "1"
else:
self.Nodes[indexMin1].encoding = "1"
self.Nodes[indexMin2].encoding = "0"
# self.showTree()
indexMin1 = self.getNodeWithMinimumProb()
indexMin2 = self.getNodeWithMinimumProb()
def getNodeWithMinimumProb(self):
minProb = 1.0
indexMin = -1
for index in range(0, len(self.Nodes)):
if (self.Nodes[index].probability < minProb
(not self.Nodes[index].visited)):
minProb = self.Nodes[index].probability
indexMin = index

and

if indexMin != -1:
self.Nodes[indexMin].visited = True
return indexMin
def showSymbolEncoding(self, symbol):
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:
while index != -1:
encoding = "%s%s" % (self.Nodes[index].encoding,
encoding)
index = self.Nodes[index].parent
else:
encoding = "Unknown symbol"
return encoding
def buildDictionary(self):
for symbol in self.probs:
encoding = self.showSymbolEncoding(symbol)
self.dictEncoder[symbol] = encoding

def encode(self, plain):


encoded = ""
for symbol in plain:
encoded = "%s%s" % (encoded, self.dictEncoder[symbol])
return encoded

if __name__=="__main__":
# symbols,probabilities table
symbols = {"T":0.1, "R": 0.05, "A": 0.1, "N": 0.1, " ": 0.1, "S":
0.15, "M": 0.05, "I":0.1, "O": 0.1, "D": 0.1, "E": 0.05}
# instantiate encoder
huffman = Huffman(symbols)
print "Simbolos"
for symbol in symbols:
print "Simbolo: %s; Codificacion: %s" % (symbol,
huffman.showSymbolEncoding(symbol))
test = "CAAASAAAS"
encoded = huffman.encode(test)
print "Mensaje: %s; Codificacion: %s" % (test, encoded)
data = encoded
UDPSock.sendto(data, addr)
UDPSock.close()
os._exit(0)

Como se puede apreciar en el cdigo de Python al utilizar la


codificacin Hoffman, lo primero que realiz en el cdigo es la
asignacin de la probabilidad en este caso correspondiente a la
palabra TRANSMISION DE DATOS en este caso se debe tomar en
cuenta que los espacio tambin ocupan bits, en tanto se estableci
las probabilidades de la siguiente manera:
"T":0.1, "R": 0.05, "A": 0.1, "N": 0.1, " ": 0.1, "S": 0.15, "M":
0.05, "I":0.1, "O": 0.1, "D": 0.1, "E": 0.05}

Posteriormente se estableci que para cada una de las probabilidades


es el establecimiento de una agrupacin nica en pareja consignando
una agrupacin de mayor a menor a fin de formar un rbol en el cual
la suma de todas las probabilidades sea igual a 1. Finalmente se
asign que si el ramal se desprende a la derecha se le asigna un bit
de 1 y si es para la izquierda un bit 0; establecido ya el cdigo se
corri el modulo mostrando los siguientes resultados:

Fig.3 Resultado de la codificacin en el primer PC

Como se puede apreciar en la figura 3 muestra la codificacin


Hoffman de cada smbolo y finalmente de toda la cadena de
caracteres para posteriormente ser enviado por el puerto ethernet.
Ya para enviar al segundo pc se establece un algoritmo en Python el cual
ordena que se envi toda la cadena codificada al computador receptor de la
siguiente manera:

Fig.4 Algoritmo de envi del mensaje codificado

En la figura 4 se aprecia que los caracteres codificados sean enviados a una


direccin especifica que se configuro en el segundo computador y que luego
de haber realizado la orden cierre el puerto UDP y no envi ms datos.

2do PC
Como en la configuracin del primer computador se hace la
asignacin de una direccin IP especfica para que este computador2
sea considerado como el receptor as:

Fig.5 Configuracin de direccin IP en el Receptor

Ya configurado la direccin IP y la mscara subred en el computador


receptor se realiza una configuracin en Python para la recepcin
mediante el cable ethernet:

Fig.6 Configuracin en Python del pc receptor mediante cable ethernet

Como se puede visualizar dentro de la figura 6 se asigna el mismo


puerto para la comunicacin, utilizando un buffer de 1024 y
destacando que los datos para recibir van a ser correspondientes
desde el host de destino y el puerto del transmisor con las mismas
libreras establecidas en el primer ordenador.
Ingresando ya las libreras para la recepcin de la cadena de
caracteres es necesario establecer el cdigo de decodificacin que se
muestra a continuacin:
#DECODIFICADOR HUFFMAN

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*import os
from socket import *
host = ""
port = 13001
buf = 1024
addr = (host, port)
UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.bind(addr)
class Node:
# propiedades
probability = 0.0
symbol = ""
encoding = ""
visited = False
parent = -1
class Huffman:
Tree = None
Root = None
Nodes = []
probs = {}
dictEncoder = {}
# methods
def __init__(self, symbols):
self.initNodes(symbols)
self.buildTree()
self.buildDictionary()
def initNodes(self, probs):
for symbol in probs:
node = Node()
node.symbol = symbol
node.probability = probs[symbol]
node.visited = False
self.Nodes.append(node)
self.probs[symbol]=probs[symbol]
def showTree(self):
print "--------------------------"
for i in range(0, len(self.Nodes)):
symbol = self.Nodes[i].symbol
prob = self.Nodes[i].probability
visited = self.Nodes[i].visited
parent = self.Nodes[i].parent
encoding = self.Nodes[i].encoding
print "[%d] Symbol= %s, Prob(%s) = %0.4f, visited=%d;
parent=%d; enc=%s" % (i, symbol, symbol, prob, visited, parent,
encoding)
def buildTree(self):
indexMin1 = self.getNodeWithMinimumProb()
indexMin2 = self.getNodeWithMinimumProb()
while indexMin1 != -1 and indexMin2 != -1:
node = Node()
node.symbol = "."

node.encoding = ""
prob1 = self.Nodes[indexMin1].probability
prob2 = self.Nodes[indexMin2].probability
node.probability = prob1 + prob2
node.visited = False
node.parent = -1
self.Nodes.append(node)
self.Nodes[indexMin1].parent = len(self.Nodes) - 1
self.Nodes[indexMin2].parent = len(self.Nodes) - 1
# rule: 0 to highest probability, 1 to lowest.
if prob1 >= prob2:
self.Nodes[indexMin1].encoding = "0"
self.Nodes[indexMin2].encoding = "1"
else:
self.Nodes[indexMin1].encoding = "1"
self.Nodes[indexMin2].encoding = "0"
# self.showTree()
indexMin1 = self.getNodeWithMinimumProb()
indexMin2 = self.getNodeWithMinimumProb()
def getNodeWithMinimumProb(self):
minProb = 1.0
indexMin = -1
for index in range(0, len(self.Nodes)):
if (self.Nodes[index].probability < minProb
(not self.Nodes[index].visited)):
minProb = self.Nodes[index].probability
indexMin = index

and

if indexMin != -1:
self.Nodes[indexMin].visited = True
return indexMin
def showSymbolEncoding(self, symbol):
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:
while index != -1:
encoding = "%s%s" % (self.Nodes[index].encoding,
encoding)
index = self.Nodes[index].parent
else:
encoding = "Unknown symbol"
return encoding
def buildDictionary(self):
for symbol in self.probs:

encoding = self.showSymbolEncoding(symbol)
self.dictEncoder[symbol] = encoding
def encode(self, plain):
encoded = ""
for symbol in plain:
encoded = "%s%s" % (encoded, self.dictEncoder[symbol])
return encoded
def decode(self, encoded):
index = 0
decoded = ""
while index < len(encoded):
founf = False
aux = encoded[index:]
for symbol in self.probs:
if aux.startswith(self.dictEncoder[symbol]):
decoded = "%s%s" % (decoded, symbol)
index = index + len(self.dictEncoder[symbol])
break
return decoded

if __name__=="__main__":
# Tabla de probabilidades de smbolo
symbols = {"T":0.1, "R": 0.05, "A": 0.1, "N": 0.1, " ": 0.1, "S":
0.15, "M": 0.05, "I":0.1, "O": 0.1, "D": 0.1, "E": 0.05}
# instantiate encoder
huffman = Huffman(symbols)

print "Esperando Mensaje..."


(data, addr) = UDPSock.recvfrom(buf)
decoded = huffman.decode(data)
print "Mensaje recibido: %s; Decodificacion: %s" % (data, decoded)
UDPSock.close()
os._exit(0)

En el cdigo de decodificacin, en primer lugar, se realiza la recepcin


de datos del mensaje codificado del primer computador para procesar
los de comparacin utilizando los mismos pasos para la codificacin,
es decir hacer una agrupacin de datos e ir construyendo el rbol de
Hoffman. Luego que en el cdigo se realiza este paso, se crea un
algoritmo de comparacin que hace nfasis en la determinacin del
mensaje codificado, recibido con el nuevo mensaje codificado a
compararse del segundo computador.
Para la comprobacin en el segundo ordenador se verifica los
resultados en Python IDLE as:

Fig.7 Decodificacin de la cadena de caracteres codificada en Python

Como se puede visualizar en la figura 7 el mensaje fue recibido de


manera exitosa y posteriormente decodificado obteniendo la cadena
de caracteres DATOS DE TRANSMISION.
Para la comprobacin de bits enviados a travs del puerto ethernet se
hace uso del programa wireshark el cual determina con precisin los
datos enviados en bits a travs de UDP:

Fig.8 Comprobacin de los datos enviados a travs del puerto ethernet entre dos
computadores

Comparando los datos del programa de wireshark con los datos


decodificados en el segundo ordenador se puede observar una
cadena de bits igual, por lo cual se puede afirmar que la transmisin
por el puerto es efectiva.

CONCLUSIONES:

Se pudo comprobar que los datos transmitidos codificados en el


primer pc son correctamente decodificados por el segundo
ordenador, cumpliendo con la codificacin y decodificacin
mnima de 20 caracteres.
Se analiz que utilizando el algoritmo de Hoffman nos arroja
una codificacin corta y precisa por lo cual es empleada para la
compresin de datos, en tanto fue para nosotros el mejor
algoritmo
Utilizando el software wireshark permiti ver que los bits
transmitidos desde el primer ordenador al segundo coinciden
con los encontrados en UDP.
Para la dulcificacin de Hoffman se estableci un algoritmo
alterno utilizando los principios de codificacin para realizar las
tablas comparativas e ir arrojando la cadena de caracteres.

ANEXOS
IMPLEMENTACION PARA LA CODIFICACION Y DECODIFICACION

You might also like