domingo, 19 de noviembre de 2017

Sockets en Python - Chat local


La comunicación entre distintas entidades en una red se basa en Python en el clásico concepto de sockets. Los programas utilizan sockets para comunicarse con otros programas, que pueden estar situados en computadoras distintas. Los tipos y funciones necesarios para trabajar con sockets se encuentran en Python en el módulo socket , como no podría ser de otra forma.

Un socket queda definido por la dirección IP de la máquina, el puerto en el que escucha, y el protocolo que utiliza. Para el ejemplo de hoy he realizado un pequeño programa en Python para intercambiar mensajes al cual he llamado PyChatLocal en el cual podremos "mensajear" con otro ordenador que este en red local.

Creando un Socket [Servidor]

Para realizar nuestro ejemplo primero debemos crear un socket para lo que sera el servidor, que estara a la escucha de las conexiones.

Creamos un objeto socket:

escucha = socket.socket()

Con el metodo bind(()) indicaremos el puerto por la cual estará en la escucha, en este caso será el 1234 y el host podemos poner localhost o dejarlo vacío:

escucha.bind(('',1234))

Luego le indicaremos el numero de conexiones que pueden estar a la espera en nuestro socket servidor:

escucha.listen(3)

Para este ejemplo, la conexión se realizara entre 2 clientes, por lo cual lo he realizado así. Nuestro socket servidor acepta las conexiones de los 2 clientes que se comunicaran:

conn, addr = escucha.accept()

La funcion accept() nos retorna 2 variables, una es la conexion y otro es una tupla que contiene (direccion,puerto) del cliente que se ha conectado.


Por ultimo, se encarga de enviar los mensajes entre el cliente 1 y 2:

while True:
#Intercambio de mensajes entre clientes
recibido = conn.recv(1024)
conn2.send(addr[0]+">"+recibido)
recibido2 = conn2.recv(1024)
conn.send(addr2[0]+">"+recibido2)

Con la función send() enviara el mensaje al cliente que ha realizado esa conexión con nuestro socket servidor. Por ultimo cierras las conexiones con close() para liberarlas.

Creando un Socket [Cliente]

Una vez creado nuestro socket servidor, ahora crearemos nuestro socket cliente. He realizado 2 puesto que para realizar la prueba en uno tenia Python 2.7 y en la otra maquina tenia Python 3.5 ambos archivos estan el repositorio PyChatLocal.

El programa recibe como parámetro la direccion IP en el cual esta ejecutándose nuestro socket servidor. Con la función connect(()) le pasamos como parámetro la dirección IP y el puerto por el cual esta escuchando, en este caso 1234, veamos:

host = sys.argv[1]
try:
#Conectar
sock = socket.socket()
sock.connect((host,1234))

Luego enviamos el contenido del mensaje que obtenemos de entrada y leemos los datos si es que existe alguna entrada con sock.recv(1024) el cual recibe como parámetro la cantidad de bytes a leer:

while True:
#Intercambio de mensajes
mensaje = raw_input()
sock.send(mensaje+"\n")
data = sock.recv(1024)
print data

Por ultimo cerramos la conexion para liberarla y ya tenemos un sencillo programa para intercambiar mensajes, probablemente mas adelante lo mejore para una próxima publicación.

Para las pruebas lo hice desde una maquina Ubuntu como servidor, ademas un cliente y una maquina Windows como el otro cliente:


Enlaces:


domingo, 12 de noviembre de 2017

Web Scraping con Python - Buscando letra de canciones Lyrics.py

Web scraping es una técnica utilizada mediante algún programa de software para extraer informacion de sitios web. Para el ejemplo de hoy veremos un pequeño proyecto hecho en python el cual he nombrado Lyrics_py y el como podemos "analizar" y extraer contenido de una pagina web para obtener la letra de alguna canción pasada como parámetro.

Hace un tiempo mencione en una de mis publicaciones un programa realizado en Java y en como este analizaba el contenido del HTML de Instagram para visualizar la foto de un perfil el cual el algoritmo para analizar el HTML lo habia hecho yo mismo, para este ejemplo de hoy realizado en Python he utilizado una librería llamada BeautifulSoup del paquete bs4 el cual nos da mucha facilidad para extraer contenido especifico.


Extrayendo datos con BeautifulSoup:

En primer lugar debemos tener el codigo HTML de donde vamos a extraer datos, en este caso sera el HTML de una búsqueda realizada en Google. Entonces primero hacemos una petición GET con los parámetros de busqueda para esto utilizaremos la librería requests, por ejemplo:

response = requests.get("https://www.google.com.pe/search?q=lyrics+shape+of+you")

Luego una vez realizada la petición, ya tenemos el HTML de respuesta con:

response.content

Ahora para extraer contenido con BeautifulSoup, existen diferentes formas, para el programa realizado utilizaremos 2:

#Utilizamos para extraer el contenido después de realizar una petición con requests

soup = BeautifulSoup(contenido,"lxml")


#Utilizamos para extraer el contenido de una porción de html

soup = BeautifulSoup(cadena,"html.parser")

Ahora para buscar algún contenido especifico o etiquetas en general, podemos hacerlo de la siguiente manera:

resultados = soup.find_all("div",{"class":"nombre_clase"})


resultados2 = soup.find_all("nav",{"id":"nombre_id"})
Como resultado nos devuelve una lista donde cada elemento es un resultado de nuestra búsqueda, si no queremos especificar alguno de los 2 parámetros ponemos True. Ademas esta libreria nos permite acceder al contenido de alguno de sus atributos como si fuera un diccionario, por ejemplo si queremos acceder al atributo href lo hacemos así:

elemento['href']

Esto son algunos ejemplos en especifico de como he utilizado BeautifulSoup para lo que va en el ejemplo realizado, para mas información sobre esta librería y como utilizar, pueden ver en este enlace.

Buscando la letra de una canción:

En general para buscar una letra de una canción, voy a Google y le ingresamos lyrics nombre_cancion, pues para el ejemplo realizado haremos lo mismo pero mediante python a travez de una petición get como mencionamos anteriormente. Ahora una vez obtenido los resultados de la búsqueda, que manualmente seria algo así:


En caso de que Google play music tenga resultados de tu búsqueda, Google te la mostrará primero y luego estarán otros 10 resultados en donde puede visualizar la letra de la canción. Para una primera version (0.1) nos basamos en que todas las letras las tiene Google play music (aunque sabemos que no es asi), pero primero debemos extraer los enlaces a los cuales nos redireccionaria para visualizar la letra completa y los enlaces de los otros 10 resultados de búsqueda:



Extrayendo datos de resultados de búsqueda:

Para obtener los resultados,existen 2 posibles opciones, cuando solo están los 10 resultados de búsqueda y cuando ademas también existe resultado en Google play music. Luego de eso necesitamos obtener el enlace a donde nos redireccionaria si hiciéramos click, es decir, si lo hiciéramos de forma manual.

Veamos como extraer los datos:


Almacenamos en un diccionario "nombre_pagina": "enlace" , para tener las posibles paginas en donde debe buscar nuestro programa y mejorar sus opciones de búsqueda mas adelante.

Una vez obtenido todos los enlaces de redireccionamiento, podemos analizar estos resultados, para ello debemos realizar otra petición get si es posible. Para la búsqueda en Google play music acceder a los datos que buscamos seria así:

#Obtenemos el contenedor de los datos en general

datos = soup.find_all("div", {"class": "content-container lyrics"})



#Obtenemos el titulo y nombre del artista

titulo = soup.find_all("div", {"class": "title fade-out"})

artista = soup.find_all("div", {"class": "album-artist fade-out"})



Por ultimo para extraer la letra de la canción seria así:

encode('utf-8') para los contenidos con caracteres especiales.
Donde la variable datos es una lista que tenia el contenido de la letra de la canción por párrafos para este ejemplo en especifico.

Para ver el proyecto pueden ver en el GitHub del proyecto.

Lyrics.py

Bueno el programa es facil de usar, lo indica en el mismo README.md del proyecto. Dependencias:
  • BeautifulSoup
  • requests
  • lxml
Para instalar dependencias con pip:

pip install -r requirements.txt

Luego ejecutan:

python lyrics.py "nombre_cancion"

Les dejo un ejemplo para buscar la letra de la canción "Shadow of the day": 



Enlaces:

domingo, 5 de noviembre de 2017

Tu Facebook tiene 3 contraseñas y probablemente no sabias


Hace un tiempo leí una publicación de Chema Alonso sobre las 3 contraseñas que una cuenta de Facebook puede tener, lo cual muchas personas no sabían al respecto.


Facebook admite hasta otras 2 contraseñas ademas de la que tu ingresaste como contraseña, ¿como es posible esto? , pues para superar los problemas mas comunes por las que se rechazan los inicios de sesión validos, Facebook admite otras 2 contraseñas:

  • Si el usuario tiene activado el Bloq+Mays activado. Es decir, si un usuario no se ha percatado que tiene activado o no el bloqueo de mayúsculas, Facebook acepta tu contraseña invertida (las minúsculas a mayúsculas y las mayúsculas a minúsculas), por ejemplo si tu contraseña es abCDfg12 entonces también tu contraseña es ABcdFG12.
  • Si el dispositivo móvil activa automáticamente el primer carácter de la contraseña. En este caso nos hace referencia a nuestros dispositivos móviles donde muchos de ellos, el primer carácter que ingresamos es mayúscula, del ejemplo anterior siendo la contraseña abCDfg12 entonces también tu contraseña es AbCDfg12.

Entonces teniendo en cuenta esto, al momento de loguearte a Facebook, lo que hace es comparar con estas 3 posibles contraseñas, por lo tanto de tener 1 contraseña puedes pasar a tener 3. Todo esto es indicado por la misma compañía de Facebook, donde lo mencionan como uno de los falsos positivos enviados comúnmente, en el punto numero 5.  Donde nos mencionan que aceptan tres formas de la contraseña del usuario para ayudar a superar las razones más comunes por las que se rechazan los inicios de sesión auténticos e indican que esto no afecta significativamente la seguridad de la contraseña del usuario o su cuenta.


Una vez mas las opciones de usabilidad ha ganado frente a la seguridad, de esta forma reducen problemas de soporte frente a usuarios que tienen problemas con el bloqueo de mayúsculas o el primer carácter en mayúscula por defecto. A todo esto Chema nos deja una imagen para reflexionar: 

http://www.elladodelmal.com/2014/05/tu-cuenta-de-facebook-tiene-3-passwords.html

Adicionalmente uno se puede preguntar que tanto afecta esto a la seguridad, pues tratándose de Facebook no es algo a tomar en cuenta, pero si lo vemos desde el punto de vista por ejemplo de un ataque de fuerza bruta, el numero de contraseñas en un diccionario se puede reducir a la mitad. Es decir, si como ejemplo tenemos contraseñas con caracteres del alfabeto [a-zA-Z] siendo una clave de 
longitud 4 caracteres, tendremos un diccionario de:

 52^4 = 7311616

Ahora tomando en cuenta que el primer carácter acepta en solo mayúsculas, esto reduce para este caso el numero de contraseñas a la mitad:
26 * 52^3 = 3655808

Enlaces: