Saltar ó contido principal

Sobre la libertad de las Creative Commons

La familia de licencias Creative Commons son las más conocidas cuando se trata de licenciar obras ( que no sean de software, dado que no contemplan la diferencia entre el código fuente y los binarios ) de una forma libre, y generalmente se acepta que todas sus variantes son libres, algunas más permisivas y otras menos, pero libres al fin y al cabo... tengo ligeras dudas de que esto sea completamente cierto.

Me explico, las licencias Creative Commos por defecto son muy libres, permitiendo distribuir el contendido donde sea, sin costes adicionales, cobrando por ello o por obras derivadas, pero se le pueden añadir una o varias condiciones, estas son:

BY ( Atribución ) - Permite la copia, modificación, distribución, representación o emisión siempre que se de crédito al autor de la forma especificada.

SA ( Compartir igual ) - Permite la copia, modificación, distribución, representación o emisión siempre que se utilice la misma licencia.

ND ( Sin derivados ) - Permite la copia, distribución, representación o emisión, pero no en forma de una obra derivada.

NC ( No comercial ) - Permite la copia, modificación, distribución, representación o emisión, siempre que sea sin ánimo de lucro.

BY no afecta a la libertad de la licencia (y al parecer se incluye siempre) y SA convierte la licencia en una de tipo Copyleft, al permitir su uso siempre que el resultado también sea libre, el problema viene cuando se trata de ND y NC. * Según Debian ***

Comenzando con el contrato social de Debian [ http://www.debian.org/ social_contract#guidelines ], NC cae con la primera directriz:
La licencia de un componente de debian no debe restringir la
posibilidad de vender o regalar el software como un componente de un
conjunto de software que contenga programas de distintas fuentes.

Y ND choca frontalmente con la tercera... y eso que la segunda solo se puede aplicar al software
La licencia debe permitir modificaciones y trabajos derivados, y debe
permitir que sean distribuidos bajo los mismos términos que el
software original.

De hecho el proyecto Debian no considera CreativeCommons libre si incluye ND o NC [ http://wiki.debian.org/DFSGLicenses ] * Según la FSF ***

Las cuatro libertades del software son:

* Libertad 0: La libertad de usar el programa para cualquier propósito.

* Libertad 1: La libertad de estudiar como funciona el programa y cambiarlo
para hacer lo que quieras.

* Libertad 2: La libertad de redistribuir las copias, para poder ayudar a
tu vecino.

* Libertad 3: La libertad para mejorar el programa y liberar tus mejoras
( y versiones modificadas en general ) para el público, para que toda la
comunidad se pueda beneficiar.
*

Realmente no se encuentra nada sobre que tenga que poder venderse ( así que según esto no debería haber problema con la NC ), pero la incapacidad de modificarlo ND, se enfrenta con la libertad 1 y la 3.

Curiosamente, con licencias para usos distintos del software y la documentación, dentro de las Creative Commos sólo menciona BY y BY con SA, mientras que habla de BY con ND cuando se trata de artículos de opinión [ http://www.gnu.org/licenses/license-list.html#OpinionLicenses ] . * Conclusión ***

Las licencias Creative Commons tienen mucha importancia en el terreno de liberar arte, aunque haya que darse cuenta de que no es oro todo lo que reluce es perfectamente comprensible el motivo del NC "si tu vas a ganar dinero con mi trabajo, al menos dame una parte", en fin, que no creo que sea necesario dejar de escuchar música con licenciada bajo CC-NC o ND (yo no pienso hacerlo), todo esto es simplemente una puntualización.

ps: Sí, se que he estado aplicando definiciones de libertad del software a trabajos creativos, que no debe hacerse tan directamente por que una cosa es una "herramienta" ( grrrr... ) y otra es arte ( ¿ cultura / entretenimiento ? )... lo dicho, es una puntualización, hay que cojerlo con pinzas.

One liners ( 2 ): alguien dijo...

curl -sL bit.ly/gfnoRX|grep '

  • "'|sed "s/<[^>]*>//g"|head -1

    Muestra la primera cita de una página aleatoria de Wikiquote.

    Y si nos ponemos filosóficos permite apreciar una idea individualmente, no a través de quien la expresó.

  • Probando Shed Skin, un compilador de Python

    ( Los comentarios están cerrados por que los spammers se ceban con esta entrada. )

    Shed Skin [ https://code.google.com/p/shedskin/ ] es un compilador de Python a C++, que puede incrementar mucho el rendimiento de un programa ( hablan de 2 a 20 veces más que Psyco y 2 a 200 veces más que CPython, la implementación base ), muy fácil de usar y que aunque aún se encuentra en desarrollo es bastante usable (no están todas las librerías implementadas y cosas así).

    Una vez descargado [ https://code.google.com/p/shedskin/downloads/list ] e instalado, para usarlo solo hay que lanzar shedskin sobre el script y generará un Makefile.

    Para probar la eficiencia compararemos una implementación algoritmo de fibonacci ( en forma puramente recursiva ) con Python, compilada con ShedSkin y en C puro.

    La implementación en Python def fibo(i):

    if (i < 2):

       return i
    

    else:

       return fibo(i-1) + fibo(i-2)
    

    fibo(35)

    La implementación en C int fibo(int i){

    if (i < 2){

       return i;
    

    }

    else{

       return (fibo(i-1) + fibo(i-2));
    

    }

    }

    int main(int argc, char**argv){

    fibo(35);

    return 0;

    }

    Ambas son equivalentes, si comparamos la velocidad usando únicamente python con la que tiene la versión nativa en C, la diferencia es clara:

    [caption id="attachment_407" align="aligncenter" width="300" caption="Le saca mucha ventaja"][/caption]

    (Y se mantiene si se repiten las pruebas) Ahora compilamos el script en python con shed skin shedskin fibo.py # Genera fibo.cpp y fibo.hpp y Makefile

    make

    Si lo ejecutamos veremos que obtiene tiempos incluso ligeramente menores que la versión en puro C ¡!

    [caption id="attachment_408" align="aligncenter" width="300" caption="Ligera diferencia a favor de ShedSkin"][/caption]

    Una ganancia de velocidad nada despreciable para el poco esfuerzo ( 2 comandos :P )

    Y eso es todo, ShedSkin es un proyecto muy interesante y una forma muy sencilla y eficaz de exprimir los scripts en python.

    [Referencias] https://code.google.com/p/shedskin/

    Cambiar el motor de búsqueda de Firefox [tip]

    La interfaz de firefox tiene dos cajas de entrada, una para la dirección y otra para consultar a un buscador, cuando se introduce una url inválida en el campo de dirección este consulta al buscador. Hasta aquí todo bien, pero si cambiamos el buscador por defecto (a DuckDuckGo, por ejemplo) seguirá buscando en el motor anterior, Google, para cambiar esto tenemos que acceder a la configuración avanzada introduciendo la dirección about:config y cambiar el parámetro browser.search.defaultenginename al que queramos, en este caso DuckDuckGo (SSL)

    Generador de contraseñas fáciles de recordar [ Bash ]

    Este código lee una página aleatoria de la Wikipedia y monta una contraseña a partir de las iniciales de las primeras palabras (aún soy muy torpe con bash, así que si encuentras algo que no se debería hacer así no dudes en avisar):

    !/usr/bin/env bash

    Escrito por kenkeiras bajo la WTFPL

    chars=13 # Número de caracteres en la contraseña

    Aquí va la url que te redirige a una página aleatoria

    url="http://es.wikipedia.org/wiki/Especial:Aleatoria"

    Se pide la página

    text=wget "$url" -O -

    lines=""

    Se toman las líneas con

    , elinimando las etiquetas

    sustituyendo los espacios por "<" para que no los separe

    for i in echo "$text"|grep "<p>"|sed "s/<[^>]*>//g"|sed "s/\ /</g";do

    # Se reincorporan los espacios y se eliminan los corchetes

    lines=echo $lines;echo "$i"|sed "s/\[[^\]]\]//g"|sed "s/</\ /g"

    done

    Se leen solo el número de palabras seleccionado

    x=0

    words=""

    for i in $lines;do

    if [ $x -ge $chars ];then
    
        break
    
    fi
    
    words=`echo $words;echo $i`
    
    x=$(( $x + 1 ))
    

    done

    Se muestran las iniciales coloreadas

    echo $words|sed "s/^./\0\o033[0m/g"|sed "s/^/\o033[0;31m/g"|sed "s/\ ./\0\o033 [0m/g"|sed "s/\ /\ \o033[0;31m/g"

    Se muestra la contraseña obtenida

    echo $words|grep -o '\ .|^.'|tr '\n ' ' '|sed "s/\ //g"

    Y se deja el espacio

    echo ""

    El funcionamiento es el siguiente:

    Se toma una página aleatoria (para eso la url adecuada se tuvo que introducir en $url) text=wget "$url" -O -

    Se filtra para obtener las líneas con

    , es decir, las que tienen texto: echo "$text"|grep "

    "

    Se elimina todo las etiquetas, todo lo que haya entre cada par < y >, ambos incluidos sed "s/<[^>]*>//g"

    Y se sustituyen los espacios por < (ya que sabemos que no quedan y algo hace falta para que el grep no los corte) sed "s/\ /</g"

    Una vez tenemos los párrafos listos, eliminamos las referencias (entre [ y ]) y se restauran los espacios echo "$i"|sed "s/\[[^\]]\]//g"|sed "s/</\ /g"

    El for que sigue va leyendo el resultado cortado por los espacios y se detiene cuando el contador $x llega al valor definido $chars.

    Después se toma lo que se convertirá en contraseña y se encierran las primeras letras entre códigos de color (en_el_wiki_de_Arch_Linux_hay_una lista) echo $words|sed "s/^./\0\o033[0m/g"|sed "s/^/\o033[0;31m/g"|sed "s/\ ./\0\o033 [0m/g"|sed "s/\ /\ \o033[0;31m/g"

    Y por último, para mostrar la contraseña, se elimina todo excepto la primera letra de cada palabra: echo $words|grep -o '\ .|^.'

    Se sustituyen los saltos de línea por espacios ( si, el espacio en el primer conjunto está de más :S ) tr '\n ' ' '

    Y se eliminan los espacios sed "s/\ //g"

    Y eso es todo, por la sombra

    Algoritmo de factorización casero

    Hay veces que uno empieza a programar sin rumbo y acaba con algo medianamente útil, este es uno de esos casos. Resulta que en el tren se me ocurrió "diseñar" un algoritmo de factorización para números grandes ( muuuuy grandes :P ) que funcionara como los test de primalidad de Fermat y Rabin- Miller es decir, confiando en que /dev/random guíe al programa por la senda adecuada.

    Pero como el que escribe sabe poco ( o menos ! ) de matemáticas y no había ganas de documentarse sobre los otros test, pues todo acabó con un algoritmo chorra sin ninguna base real, así que:
    1.
    2. Puede encontrar los factores... o no
    3.
    4. No siempre encuentra a la primera los factores primos, de hecho no
    encuentra siempre los mismos factores, alguna vez unos otra vez otros
    ( eso sí, todos correctos ), se puede descomponer del todo aplicandolo
    de forma recursiva hasta que sean lo suficientemente pequeños para
    aplicar una factorización lineal.
    5.
    6. La posibilidad de encontrar o fallar depende del número de iteraciones,
    con Python unas 10,000 ( suficiente para casi cualquier número ) se
    hacen en 5 segundos
    7.

    El algoritmo es el siguiente:

    1. Se guarda el número a factorizar como N
    2. Se le aplica la raíz cuadrada a N, obteniendo L
    3. Se obtiene X a partir de L, restándole 1 si es par
    4. Se inicia un contador I a 0 y una lista vacía D
    5. Se añade X a la lista D
    6. Se asigna a Q,  N % X
    7. Si Q es 0, X es un factor, fin.
    8. Sinó, se le suma 1 a Q si es impar
    9. Se le resta Q a X, módulo L
    10. Se incrementa I
    11. Si X es mayor que 1 y no está en D,  si I es menor que el número de
      iteraciones se salta a 5, en caso contrario no se encontraron factores,
      fin.
    12. Se toma un número X aleatorio impar entre 3 y L
    13. Si X está en D, volver a 12
    14. Sinó, salta a 5
      29.

    Aquí hay que hacer notar algo muy importante, el número de iteraciones debe ser mayor o igual que L-2, sinó puede quedarse atascado en el bucle 12 - 13.

    Y esta es la implementación en python:

    !/usr/bin/env python

    -- encoding: utf-8 --

    Dumb factoring algorithm

    Written by kenkeiras kenkeiras@gmail.com

    Released under the WTFPL license

    from sys import argv, stderr,stdout

    from math import sqrt, pow

    import random

    Parity check

    def mkpar(n, f=1):

    if (n & 1) == 0:

       n += f
    

    return n

    Factoring

    def facto(maxchk, l, n, iospeed = None):

    result = None
    
    x = l # Starting point
    
    if not(x &amp; 1):
    
        x -= 1
    
    for i in xrange(maxchk):
    
        if (iospeed != None) and not(i % iospeed):
    
            stdout.write("%s / %s: %s%%" % (i,maxchk, (i*100)/maxchk))
    
            stdout.flush()
    
            stdout.write("\r")
    
    
    
         # Algorithm itself
    
        q = n % x
    
        chkd.append(x)
    
        if ( q == 0 ):
    
            result = x
    
            print "\n"
    
            break
    
    
    
        p = mkpar(q)
    
        x = ((x - (p)) + l) % l
    
    
    
        if x in chkd or x < 2:
    
            x = random.randint(3, l)|1
    
    
    
        while x in chkd:
    
             x = random.randint(3, l)
    
    return result
    

    Stub

    if name == "main":

    if len(argv) < 2:

       print >>stderr, argv[0], "<number> [<iterations>]"
    
       exit(0)
    

    # Iteration number

    defcheck = 10000

    if len(argv) > 2:

        defcheck = int(argv[2])
    

    n = int(argv[1]) # Target

    print len(bin(n))-2, "bits"

    l = int(pow(n, .5))

    maxchk = min(defcheck, l-2)

    print maxchk,"iteraciones"

    chkd = [] # Already checked

    iospeed = 0xFF

    r = facto(maxchk, l, n, iospeed)

    if (r == None):

       print (" "*20)+"\rNo hubo suerte :("
    

    else:

       print (" "*20)+"\rResultado: %s, %s" % (r, (n / r))
    

    Por ejemplo, con 12345678901234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 123456789

    [caption id="attachment_331" align="alignnone" width="300" caption="Captura del factorizador"][/caption]

    Sé que realmente no es un número tan grande (492 bits), pero se puede lanzar contra uno de 1024 bits y sigue funcionando.

    [caption id="attachment_332" align="alignnone" width="300" caption="A por los 1024 bits"][/caption]

    Y eso es todo, no es gran cosa pero... brilla ! :P

    Monitoreando la IP pública

    Esta es una de esas ideas que surgen en un momento simplemente por ver una captura de algo que casi cumple una necesidad que no te habías dado cuenta de que tenías ( y que no tendrías de no haberlo visto xD ), pero que necesita algo de pulido. La base es esta [ http://blog.joaomoreno.com/ip-growl/ ], pero en mi opinión sería más útil que la IP mostrada fuera la IP pública ( la que te localiza en todo Internet ) y que de paso pudiera funcionar continuamente, mostrando la IP solo cuando cambiara.

    La primera parte, mostrar la IP pública se puede hacer fácilmente con este script: curl http://checkip.dyndns.org/|sed "s/[\<>\/A-Za-z\:\ ]//g"

    Para más variedad, en Freesoftwareando recopilaron_unos_cuantos.

    Para mostrarlo como notificación solo hay que pasarselo a notify-send: ip=curl http://checkip.dyndns.org/|sed "s/[\<\>\/A-Za-z\:\ ]//g"

    notify-send "IP monitor" "$ip"

    [caption id="attachment_320" align="alignnone" width="259" caption="Captura de la notificación"][Captura_de_la_notificación_de_IP_monitor][/caption]

    Como último paso lo meteremos en un bucle infinito, haremos que muestre la IP solo si cambió ( y lógicamente esperamos unos segundos antes de volver a comprobar ): lastip=""

    tiem=60 # Tiempo en segundos a esperar

    while [ 1 ];do

    ip=curl http://checkip.dyndns.org/|sed "s/[\<\>\/A-Za-z\:\ ]//g"

    if [ "$ip" != "$lastip" ];then

       notify-send "IP monitor" "$ip"
    

    fi

    lastip=$ip

    sleep $tiem

    done

    Y con eso ya podemos utilizarlo, a mano, incluyéndolo entre los programas a incluir en el inicio o como prefiramos.

    Lo que nadie dice sobre la generación de números aleatorios

    Cuando uno aprende a programar, algo que se suele mostrar es como generar números aleatorios, y a veces (muchas) se muestra como forma generar un número y despues "recortarlo", por ejemplo en C: int r = random() % 100;

    Esto tiene un problema grave, y es que se pierde aleatoriedad en el proceso, por ejemplo, si tomamos los datos de urandom y luego le aplicamos el "recorte" quedaría esta distribución de datos:

    Código: http://pastebin.com/sXtAe7nK

    Los dos colores se refieren a los mismos datos, en rojo como son originalmente (de 0 a 255, uniformemente distribuidos) y en verde después de aplicarles el módulo (entre 55 y 56 se rompe la uniformidad), la causa es obvia: Para 0 hay 3 posibilidades: 0, 100, 200

    Para 1 también: 1, 101, 201 ... Para 55: 55, 155, 255 Pero a partir de 56 solo 2: 56, 156 (no hay 256)

    Una solucion es forzar a que el "rango de entrada" sea multiplo del "rango de salida" por ejemplo, ignorando los valores mayores que 199Código: http:// pastebin.com/H9cK3ezg

    Eso es todo, hasta otra.

    Librería para Liberateca [python]

    En Freesoftwareando han publicado un script_que_usa_el_API_de_liberateca, y ya sabeis como son estas cosas, "culo veo..."

    No, ahora en serio, el hecho de que tal compendio de cultura disponga de un_API accesible para cualquiera da mucho juego para trastear con los datos ( estadísticas sobre los géneros de series, número de temporadas o lo que sea ), cuando se lanzó el proyecto solo se podía acceder vía web y no fué hasta leer el post que me enteré de que ya habían desarrollado un API, así que ahí va una pequeña librería para manejarlo ( necesita una cuenta, en la web se pueden pedir invitaciones o si dejais el mail, os mando una ).

    La "librería" es esta [ http://pastebin.com/caTNLsGS ]

    Nota: La conversión (en unroll) confía en que el servidor no es malintencionado, en caso contrario podría inyectar código, a ver si después escribo algo que parsee eso como root manda...

    Para usarla hay que importarlo y crear una variable de tipo liberateca, pasándole el user y password. l = liberateca("user", "password")

    Después se pueden usar estas funciones:     getSerieList(): Devuelve una lista de diccionarios, cada uno con los elementos name (nombre de la serie)  y url (donde se puede encontrar)

    getId( url ): Toma la url de una serie y retorna su Id

    getSerie( id ): Muestra la información de una serie a partir de su Id, como un  diccionario con listas y diccionarios dentro

    getSerieT( id ): Devuelve un diccionario con un elemento seasons que contiene una lista de las url de las temporadas ( se puede extraer el número de temporada con getId.

    getSerieT( id, número de temporada ): Muestra los capítulos de la temporada en cuestión de una serie, como una lista de diccionarios conn los elementos url, air_date (cuando se estrenó), episode (número de episodio), y title.

    getSerieEp( id, número de temporada, número de capítulo ): Extrae los datos de un capítulo de una temporada de una serie, como un diccionario con diccionarios:

    season: Temporada.         air_date: Fecha de estreno         episode: Número de episodio         links: Array de Enlaces, cada uno como un diccionario, así:

    url: Dirección             audio: Idioma de audio             subtitle: Idioma de los subtítulos

    title: Título

    Se usan esos tipos porque es la estructura que provee el servidor, un print de todo el arbol, de ahí que la función que interpreta los datos, unroll, realmente lo que hace es asignar todo eso a una variable controlada, el problema de poder inyectar código viene por ahí :S.

    Nos vemos