Skip to main content

El mercado de bitcoins en directo

Esta semana se pudo ver un fenómeno muy curioso, el valor de las Bitcoins se disparó, pasando de valer cada una 12.12$ hace un mes a 20.94$ 7 días atras, y a los ~29$ actuales, es un mercado que puede resultar interesante analizar, incluso para alguien con escasos conocimientos de economía como el que escribe, aunque solo sea por cambiar de tema un rato.

Pues bien, resulta que en bitcoincharts.com recopilan datos sobre las transacciones ( valor, divisa, mercado, volumen, momento en que se realiza ), y lo que es mejor, se puede acceder a esos datos a través de un API, en principio puede parecer poco cómoda ( una petición, un paquete de datos, así que para mantenerse actualizado se derrocharía mucho ancho de banda ), pero existe otra que apenas está documentada más que en el pie de página.
Please don't use this for realtime streaming! Use the telnet
interface (TCP port 27007) instead.

Eso es todo lo necesario, si conectamos con bitcoincharts.com en el puerto 27007 conoceremos en tiempo real los cambios en los mercados ( servidos en formato JSON ), se puede combinar con un script, notify-send y demás para tener esos datos siempre a la vista:

!/usr/bin/env python

import socket, os, json, string

def getPack(s):

p = ""

while True:

   c = s.recv(1)

   if not c in string.printable:

       continue

   elif(c == "\n"):

       break

   else:

       p += c

return p

s = socket.socket()

s.connect(('bitcoincharts.com', 27007))

while True:

data = getPack(s ).encode('ascii').strip()

if len(data) < 1:

   continue

h = json.loads(data)

hop = "Mercado: %s\nPrecio: %s\nDivisa: %s\nVolumen: %s\n" %(h['symbol'], h ['price'], h['currency'], h['volume'])

cmd = "notify-send --urgency=low 'Bt-Market' '"+str(hop)+"'"

os.system(cmd)

f = open('market.log', 'a')

print >>f, data

f.close()

s.close()

Los datos guardados en market.log se podrían aprovechar para un análisis posterior, por ejemplo, haciendo uso del_módulo_de Gnuplot ( hay que instalarlo ): Volumen_de_las_transferencias_en_un_momento_dado

Volumen_total_hasta_el_momento

Variación_de_precios_en_un_mercado_dado

[caption id="attachment_521" align="aligncenter" width="640" caption="Variación de precios en mtgoxUSD"][/caption]

Creo que queda clara la idea, hay bastantes datos para trastear :)

Saludos

[Referencias] Bitcoin.org WeUseCoins Como_iniciarse_con_los_Bitcoins

Introducción a NetKit( III ): switches y enrutado

Introducción_a_Netkit(I):Instalación
Introducción_a_NetKit(_II
):creando_redes
Introducción_a_NetKit
(IV):_Un_puente_a_Internet

Bueno, pues seguimos con esto, como dijimos la última vez, ahora lo que queremos es crear una red de 4 máquinas, dos switches conectados entre sí y cada uno a otra máquina, y que se puedan comunicar entre ellos sin problemas, el esquema en general sería este: 

No es tanto un problema con NetKit ya que se puede hacer con lo que ya sabemos, como un ejercicio sobre como hacer tablas de enrutado.

Lo primero es asignar decidir el número de conexiones que requiere cada máquina, así vemos que cada switch tiene dos conexiones, una con el otro switch y otra con la hoja, y cada hoja solo tiene una, con su switch correspondiente, podríamos entonces dividir la red en 3 dominios de colisión:

El archivo "lab.conf" quedaría entonces así:

===============================================================================

hoja_1[0]=rama1 hoja_2[0]=rama2 switch_1[0]=rama1 switch_2[0]=rama2

switch_1[1]=tronco switch_2[1]=tronco

===============================================================================

Nota: las '_' no están permitidas en el nombre de los dominios de colisión.

Y se crearían 4 directorios, hoja_1, hoja_2, switch_1 y switch_2, si ejecutamos el laboratorio( lstart . )

Ahora hay que decidir las IP para establecer las tablas de enrutado, por ejemplo estas:

Hoja 1: En Rama 1: 10.0.1.2

Switch 1: En Rama 1: 10.0.1.1 En Tronco: 10.0.0.1

Hoja 2: En Rama 2: 10.0.2.2

Switch 2: En Rama 2: 10.0.2.1 En Tronco: 10.0.0.2

En este caso, como hay redes que por defecto se consideran /8 es necesario especificar la máscara de red. Por comodidad hacemos que las IP se asignen al iniciar con archivos .startup : hoja_1.startup:

===============================================================================

!/bin/sh

ifconfig eth0 10.0.1.2 netmask 255.255.255.0

===============================================================================

hoja_2.startup:

===============================================================================

!/bin/sh

ifconfig eth0 10.0.2.2 netmask 255.255.255.0

===============================================================================

switch_1.startup:

===============================================================================

!/bin/sh

ifconfig eth0 10.0.1.1 netmask 255.255.255.0 ifconfig eth1 10.0.0.1 netmask 255.255.255.0

===============================================================================

switch_2.startup:

===============================================================================

!/bin/sh

ifconfig eth0 10.0.2.1 netmask 255.255.255.0 ifconfig eth1 10.0.0.2 netmask 255.255.255.0

===============================================================================

Si probamos el laboratorio comprobaremos que solo se pueden comunicar con las máquinas con las que están conectadas directamente, ahora hay que hacer que los switches enruten los paquetes, para esto tenemos que diseñar la tabla de enrutado.

De forma sencilla, los paquetes que salen de hoja_1 por defecto irán hacia switch_1 ( igual si hubiera otras máquinas en la misma red ) , y los de hoja_2 hacia switch_2. Con los que quedan es cuando se pone interesante, tomemos el caso de switch_1.

* Si los paquetes van hacia una de sus IP, los responde automáticamente
( esto lo hace siempre a menos que le digamos lo contrario )

* Si los paquetes van hacia otra dirección del segmento 10.0.0. , se
envían por la interfaz eth1.

* Si los paquetes van hacia el segmento 10.0.1. , se envían por la
interfaz eth0.

* Si van hacia el segmento 10.0.2.* , se le envían a 10.0.0.2, por la
interfaz eth1 .
*

En caso de switch_2, igual:

* Si los paquetes van hacia una de sus IP, los responde automáticamente.

* Si los paquetes van hacia otra dirección del segmento 10.0.0. , se
envían por la interfaz eth1.

* Si los paquetes van hacia el segmento 10.0.2. , se envían por la
interfaz eth0.

* Si van hacia el segmento 10.0.1.* , se le envían a 10.0.0.1, por la
interfaz eth1 .
*

Las tablas se podrían aplicar de esta forma:

hoja_1:

===============================================================================

route add default gw 10.0.1.1

===============================================================================

hoja_2:

===============================================================================

route add default gw 10.0.2.1

===============================================================================

switch_1:

===============================================================================

route add -net 10.0.0.0/24 dev eth1route add -net 10.0.2.0/24 gw 10.0.0.2 dev eth1 route add -net 10.0.1.0/24 dev eth0

===============================================================================

switch_2:

===============================================================================

route add -net 10.0.0.0/24 dev eth1route add -net 10.0.1.0/24 gw 10.0.0.1 dev eth1 route add -net 10.0.2.0/24 dev eth0

===============================================================================

Una vez añadidas a los archivos  *.startup , ya está todo listo:

Y eso es todo, solo queda explicar como hacer una "salida" a Internet, nos vemos.

ps: el laboratorio ya preparado [ labo.tar.gz.b64 ], se puede descomprimir con

===============================================================================

base64 -d labo.tar.gz.b64 |gunzip |tar -x

===============================================================================

Historias desde los confines de random()

Pues eso, hoy toca un script al estilo de cierto juego analógico, ese en el que hay que escribir una frase en un trozo de papel sabiendo sólo con que palabra empezar (última palabra que escribió la persona anterior) y pasarsela a la siguiente hasta que vuelva a la primera.

Lo que hace el script [ randomstories.zip ] es tomar un número cualquiera de palabras de una página de wikipedia, y repetir el proceso haciendo que la primera palabra encaje con la última hasta alcanzar el tamaño máximo del mensaje. El archivo que hay que ejecutar es randomstories.py .

El código es bastante lento... unos 10 min para 140 caracteres ( jeje, las probabilidades de encontrar una cierta palabra entre el océano de Wikimedia son bastante remotas, así que se detiene si no encuentra la palabra en 100 páginas ) y los parámetros hay que cambiarlos en el código fuente en las primeras líneas de "randomstories.py", pero se ve claramente (los otros solo se encargan de manejar las web).

Y poco más, saca por stderr cosas como " % " , para el número del intento actual y cosas así, para ver como va la cosa.

Y no se me ocurre nada más, algunas muestras:

===============================================================================

Buses nuevo entierro se convierte en la agencia de viajes de los funcionarios nos asistieron a nosotros ,los ee.uu., seguimos dando ===============================================================================

Políticos una de la edificación de la democracia en dos concentraciones

Presidente emérito de asuntos exteriores de agosto que no sé que muchos de la segunda menor, tras ===============================================================================

En el país, china le sigue con algunos de 2007 las autoridades han sido de la revolución democrática (prd, izquierda), por ===============================================================================

Con root...

One liners( 11 ): "desescapando" caracteres html tipo {

dst = re.sub(r'&#([0-9]+);', lambda x:unichr(int(x.group(1))), src)

  • re.sub() hace sustituciones guiada por una expresión regular.
  • r'&#([0-9]+);' es una expresión regular que captura lo que buscamos
    y expone lo que nos interesa, el número
  • lambda x:unichr(int(x.group(1))) es la función (anónima en este caso)
    que decide por que se reemplaza, por el caracter UTF con el código en
    cuestión.
  • src la cadena original
    *

ps: corregido para evitar capturar &#; , perdón :(

Navegar por TOR y I2P con Firefox de forma transparente

Veamos como navegar por los Eepsites de I2P y los servicios_ocultos de TOR ( dos redes descentralizadas y anónimas ) como si fueran sitios normales con Firefox, para esto usaremos el plugin FoxyProxy.

Nota: este proceso está probado en la distro Trisquel GNU/Linux ( derivada de Ubuntu, y esta de Debian ), pero excepto el proceso de instalación ( que por otra parte es la mayoría :P ) que es el habitual para cualquier programa, lo demás se hace igual.

TOR

Comencemos instalando TOR, en la página_del_proyecto hay una_lista_de repositorios_de_TOR_para_la_mayoría_de_las_distros, sería recomendable instalarlo desde este repositorio para asegurarnos de tener la última versión disponible, pero en todo caso varias distros proveen el software en sus propios repositorios, así que usar los "oficiales" es opcional.

Dicho esto, para añadir los del proyecto abrimos un terminal y escribimos "sudo nano /etc/apt/sources.list" pedirá la contraseña y después abrirá un editor, al final añadiremos una línea como esta:

deb http://deb.torproject.org/torproject.org <VERSIÓN> main

La versión es, lógicamente, la versión de la distro, en la web del proyecto proporcionan una lista_de_lo_más_comunes:

* Debian unstable (sid) es "sid"

* Debian testing es "wheezy"

* Debian 6.0 (squeeze) es "squeeze"

* Debian 5.0 (lenny) es "lenny"

* Ubuntu 11.04 es "natty"

* Ubuntu 10.10 o Trisquel 4.5 ( Slaine ) es "maverick"

* Ubuntu 10.04 o Trisquel 4.0 ( Taranis ) es "lucid"

* Ubuntu 9.10 o Trisquel 3.5 ( Awen ) es "karmic"
*
* Ubuntu 8.04 es "hardy"
*

Recordar que las cadenas están separadas por solo un espacio, para acabar pulsamos Control-O seguido de Enter para guardar el archivo y Control-X para salir.

Después, para instalarlo lanzaremos estos comandos desde el terminal ( de nuevo, los que incluyen "sudo" pedirán la clave ) :
gpg --keyserver keys.gnupg.net --recv 886DDD89
gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key
add -
sudo apt-get update
sudo apt-get install tor tor-geoipdb

Vistos de forma individual, el comando"gpg --keyserver keys.gnupg.net --recv 886DDD89"  pide la clave 886DDD89 al servidor keys.gnupg.net  .

"gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add - " añade la clave como válida para APT ( el gestor de paquetes ).

"sudo apt-get update" actualiza la lista de paquetes

"sudo apt-get install tor tor-geoipdb" instala los paquetes

Y ya hemos acabado con TOR, si todo ha ido bien, ya estará funcionando.

Nota: también está disponible un paquete que integra lo necesario para la navegación, en https://www.torproject.org/projects/torbrowser.html.en y instrucciones para instalación en otros entornos en https:// www.torproject.org/docs/installguide.html.en .

I2P

Ahora a por I2P, vamos a la página_de_descarga del_proyecto, ahí se proveen paquetes para Ubuntu/Debian o instrucciones para instalarlo en otras distros o SO, de nuevo optaremos por el_paquete_para_derivadas_de_Debian, en la misma página están las instrucciones para añadir el repositorio, así que me ahorraré la parrafada.

Nota: es posible que si usas una versión derivada de ubuntu, no esté soportada con su versión, sino con la de Ubuntu, es decir, si al hacer "sudo apt-get update" muestra un error de "Failed to fetch 404", es posible que tengas que editar el archivo con "sudo nano /etc/apt/sources.list.d/i2p- maintainers-i2p*.list", y acabar Control-O seguido de Enter para guardar y Control-X para salir.

Siguiendo con las derivadas de Debian, podemos usar "i2prouter start" para iniciar el servidor ( e "i2prouter stop" para detenerlo ), por defecto cuando se inicie abrirá una pestaña en el navegador, el panel de control del nodo, sería recomendable pasarse por la configuración ( configuration_page ) y hecharle un vistazo, además se puede evitar que el panel se abra cada vez que el nodo se inicie en la sección service, en "Launch browser on router startup?".

Por último, podemos acceder a la configuración del servicio con "sudo dpkg-reconfigure i2p" y decidir si se iniciará o no al iniciar el sistema y el usuario que lo ejecutará ( sería recomendable dejarlo como está por defecto, con un usuario propio para el servicio ).

Configurando FoxyProxy

Este es el meollo de la cuestión, FoxyProxy permite definir servidores proxy diferentes según la URL de destino ( la versión Standard servirá ) , así que es el candidato perfecto para esto, ya que permitiría que las URL con .onion pasasen por el proxy de TOR y las .i2p por el de I2P, vamos a ello.

Asumo que el lector puede instalar el plugin_FoxyProxy por si mismo ( de nuevo, la versión Basic no servirá, la Standard sí ) Lo primero es acceder a la configuración, por ejemplo desde el icono que hay en la barra de navegación o en la de estado: 

Añadiremos un nuevo proxy , comenzaremos por I2P, rellenamos los detalles del proxy así, y después pasamos a la pestaña de Patrones de direcciones:

Después, añadimos un nuevo patrón , donde indicaremos que afectará a las direcciones que tengan .i2p, por ejemplo así:

Y listo, solo queda pasar por la pestaña General y darle un nombre. Para TOR repetimos el proceso, con esta configuración del proxy, y patrón:

Solo queda indicarle que use los proxys dependiendo del patrón de URL.

Un par de direcciones para probar: El foro de la comunidad de I2P: forum.i2p The Hidden Wiki: http://kpvz7ki2v5agwt35.onion/wiki/index.php/Main_Page

Saludos

Primera semana programando BLK

Como este es un tipo de proyecto al que no estoy acostumbrado, que requiere hacer las cosas con cuidado y de forma constante, en vez de tirar codigo según vengan las ideas durante un rato y acabar, me he decidido a ir "documentando" la experiencia, a ver si de paso consigo interesar a alguien en el proyecto :P

El plan original (el roadmap_del_proyecto esta en su wiki) era aprovechar la semana anterior para preparar el parser de C y la definición del bytecode, pero las cosas se torcieron:

* Dejé la definición del formato para lo más tarde posible, ya que no
encontraba un motivo lo suficiente fuerte para hacerlo de una forma. Al
final el formato estará "basado" en bencode, lo que le da bastante
flexibilidad y lo mantiene fácil de parsear (aunque cuando haya que
pasarlo a C ya veremos los líos que habrá con punteros :/ ), pero mejor
que la primera idea, de hacerlo como un conjunto de bytes sin una
estructura obvia, creo que al menos es un punto de partida.

* El preprocesador de C es la mitad de la batalla, sí, parece poca cosa
pero da para ratos preguntandose que @#$%! pasa, lo acabé el viernes,
cuando la idea era hacerlo días antes... y ni siquiera está completo,
le falta manejar chars y strings en los #if, pero creo que eso lo dejaré
para cuando se pase a C.
*

Por otro lado es una satisfacción cuando por fin consigue funcionar como preprocesador del gcc :) * Estado actual ***

Ahora mismo el preprocesador funciona moderadamente bien con los headers de gcc, y me las voy arreglando con el parser, y aunque en estos momentos aún no esté en el repositorio, mete 'typedef's, y firmas de funciones en el bytecode, y la definición general del bytecode está media lista, maneja tipos, variables y funciones quedando por acabar de definir los condicionales/bucles, la asignación, el 'return' y alguna operación más.

El plan para esta semana es acabar el prototipo de parser de C de una vez y dedicar el resto y la siguiente al compilador a ensambador x86, pasar el código de Python a C/C++, y documentar, documentar y documentar.

Enfin, eso es todo lo que se me ocurre, pronto más y mejor.

A un día de la 'Ley Sinde'

Mañana, día 9  de febrero se vuelve a votar la "Ley Sinde" en el Senado, después de no pocas protestas por parte de los cuidadanos. Aunque la ley fue rechazada en el congreso volvió al Senado después de un pacto entre el PSOE, PP y CiU. No tiene sentido otro post aquí cuando gente que sabe más del tema ya ha escrito sobre ello, en cualquier lugar que se dedique a las noticias se encontrará mucho material relacionado con el tema, pero ahí van links que me parecen recomendables:

http://xmailer.hacktivistas.net/ http://red-sostenible.net/

Solo me pregunto esto ¿ quién después de descargarse una canción dijo que es obra suya ?, ¿ no estarán confundiendo ( ¿ a propósito ? ) derechos de autor y derechos de explotación ?, ¿ no se estarán utilizando a los artistas como escudo ?

Saludos y suerte...

Traducción automática de programas

Esto lleva un rato parado, pero ya toca presentar una prueba recién terminado, la idea básica es muy sencilla: un programa ( o gran parte de el ) es relativamente sencillo de traducir, dado que muchas cadenas se repiten y como 'Help' y 'Download', la mayoría de las cosas no tienen un contexto o necesitan considerarlo.

Así, el proyecto es simple, una página web a la que se le envía un archivo de traducción ( por ahora solo soporta .po y .mo ), y devuelve el archivo formateado como .po, y con las cadenas que pudo traducir añadidas, además se da la opción de contribuir con traducciones ( desde archivos ya traducidos ), ya sea desde el mismo formulario o de una API.

Dicho esto, aquí está el código [  https://github.com/kenkeiras/Raw- translator ] ( para ponerlo en marcha hay que editar el config.php y después se ir a install.php, que crea las tablas ), aquí una prueba [ http:// codigoparallevar.co.cc/rtrans/ ] sin pasarse, que luego el host se la pasa dando errores 500 ;) ( el hosting ya tuvo problemas con DDOS, así que es bastante lógico que tengan cuidado ). La documentación de la pequeña ( ínfima ) API en [ http://codigoparallevar.co.cc/rtrans/api_doc.html ].

ps: trabaja mejor si se le permite añadir los strings, así rellena los duplicados ;)

ps2: tabla de ejemplo [ http://codigoparallevar.co.cc/files/trans.gz ] ( tarda en cargar las cosas ( 2 querys por cadena :/ ), así  que mejor empezar con cuanto más mejor  :P )

Nos vemos

[Haskell] cantidad de entropía en un archivo

Estos días un usuario ha estado posteando código haskell en HackXCrack, lo que renovó el poco interés que tenía en dicho lenguaje ( muy recomendable Learn_You_a_Haskell_for_Greater_Good! para empezar, btw ), así que aquí está un ejemplo, muestra la cantidad de entropía en un archivo, de 0 a 8 [ entropy.hs ] . El plugin para mostrar código no tira de haskell, así que está coloreado con pyments dentro del post... ===============================================================================

!/usr/bin/runhaskell

-- Written by kenkeiras under the WTFPLv2

-- Para getArgs() import System.Environment

-- Para ord() import Data.Char

-- Cuenta las ocurrencias de cada tipo de caracteres countChars s = [ sum[ if ord(c) == code then 1 else 0|c<-s] | code <- [0 .. 255]]

-- Calcula la entropía a través del número de ocurrencias y el número total entropy arr l = sum[ if n /= 0 then (n / l) * logBase 2 (l / n) else 0 | n <- arr ]

showEntropy fname = do     f <- readFile fname -- Lee el contenido del archivo

let l = length f    -- determina el tamaño del archivo     let lf = fromIntegral l  -- convierte la longitud a Float ( necesario para el logaritmo )

let h = fname ++ "[" ++ show(l) ++ " bytes]: "     putStr h

let count = countChars f -- Prepara el mapa de caracteres     let e = entropy count lf -- Calcula la entropía     let h = show(e)

putStrLn h

-- Comprueba los argumentos main = do     args <- getArgs     let l = length args     if l /= 1       then error "./entropy.hs "       else showEntropy (args!!0) ===============================================================================