Login con sesiones en PHP 7.1

12/12/2017
Artículo original

Espero y este post sea de tu agrado, no olvides compartirlo en su redes sociales y sobre todo.. Gracias por seguirnos!

El día de hoy aprenderemos a crear un login con sesiones en PHP de la mano de Gabriel Chavez, autor invitado del blog, mediante un ejemplo práctico en código donde aprenderemos fácilmente a implementarlas. Además también veremos como implementar mecanismo antispam con Google reCaptcha, ¿listo? Te dejo con Gabriel! El uso de las sesiones generadas por PHP se ha puesto muy de moda cuando trabajamos paginas dinámicas con este maravilloso lenguaje, si nos remontamos unos años atrás, se trabajaban con Cookies, lo que representaba un grave agujero de seguridad para el usuario ya que las Cookies se almacenan en la

Compartir en Facebook

Comparte en Google Plus

Compartir en Twitter

El post Login con sesiones en PHP 7.1 aparece en el Blog de Jonathan Melgoza

[Java] Utilizar un ArrayList en un JFrame

07/12/2017
Artículo original

/*
 *  -----------------------------------
 *  java mexico
 *  -----------------------------------
 *  Descripcion :
 *  Hola, estoy realizando un pequeño programa, el cual consiste en que, al hacer clic en un panel se dibuje un circulo,
 *  y cuando se vuelva hacer clic, se dibuje otro círculos de otro color, pero sin que se borre el primer circulo,
 *  y así hasta tapizar el panel de círculos de diferentes colores.
 *  Mi pregunta es, ¿como almacenar los círculos en la memoria, para que no se borren?, ya tengo el evento del clic y que
 *  los círculos cambien de color,
 *  he estado investigando como hacer esto, tengo entendido que se puede hacer con un ArrayList o con un Vector.
 *  -----------------------------------
 *  Actualizacion: 2017_12_06
 *  -----------------------------------
 *  Descripcion :
 *  Para el siguiente ejercicio utilizo Vectores. de poscion dinamica...
 *  el vector va aumentando en tamaño o posiciones cada vez que hago clic en el JFrame. v.add()
 *  -----------------------------------
 *  1. import java.util.Vector;                  importar clase

leer más

INSERTAR FECHA EN MySQL DESDE JAVA

07/12/2017
Artículo original

*  te envio el codigo completo con las nuevas modificaciones compilado en Netbeans 8.2
 *  -----------------------------------
 *  Creo el proyecto con el nombre PruebaFecha
 *  elimino la clase que me crea por defecto. PruebaFecha.java
 *  -----------------------------------
 *  Agrego dos objetos nuevos al proyecto:
 *  ConexionMySQL.java                           conexion base de datos Mysql. test  Tabla. prueba
 *  PruebaFechas.java                             Jframe
 *
 *  ----------------------------------- Jframe
 *  0. mysql-connector-java-5.1.18-bin.jar      copiar la libreria en la carpeta lib de mi projecto ...\lib\
 *  0. jcalendar-1.4.jar                             copiar la libreria en la carpeta lib de mi projecto ...\lib\
 *  0. Agregar las librerias a mi projecto         package Libraries
 *
 *  1. import com.mysql...                               al copiar el metodo PruebaFecha me importa las librerias
 *                                                                    para la conexion a la base de datos Mysql
 *     import javax.swing.JOptionpane            libreria para cuadro de mensajes en pantalla

leer más

Cómo leer y escribir archivos CSV con Java

07/12/2017
Artículo original

Imagen ornamental

Una situación muy habitual en cualquier aplicación consiste en la necesidad de leer y escribir archivos con valores separados por comas (CSV, de su nombre en inglés: Comma Separated Values).

Esto se puede hacer nativamente en Java usando las API de lectura y escritura de archivos y procesando cada línea con código específico para separar los valores o para crear las líneas correspondientes. Pero hacerlo así, "a pelo" es un trabajo muy ingrato, propenso a errores y que tiene poco sentido si podemos hacerlo de una manera mejor y más directa. Y esto precisamente es lo que nos proporciona la conocida biblioteca Open Source llamada opencsv.

Además su licencia es de tipo Apache 2.0, lo que nos permite usarla para cualquier propósito, incluso para crear aplicaciones comerciales.

Aunque opencsv tiene infinidad de posibilidades, vamos a ver los métodos más sencillos para poder usarla en nuestras aplicaciones, sean estas de escritorio, Web, etc...

Cómo es un archivo CSV

Como su propio nombre indica, un archivo CSV consiste en una serie de valores separados por comas, que es el caso más habitual, aunque en realidad las comas muchas veces pueden ser otros caracteres, como puntos y coma, tabuladores, etc...

Por regla general estos archivos comienzan con una línea que lleva los nombres de cada uno de los campos de datos que se están almacenando.

Por ejemplo, el siguiente es un fragmento de un archivo CSV que representaría información sobre los códigos estándar para representar a los diferentes países del mundo. Incluye el nombre del país, su código de 2 caracteres, de 3 caracteres, su código numérico y si es considerado un estado soberano o no (sacada de aquí):

English-Short-Name,Alpha-2-code,Alpha-3-code,Numeric-code,Independent
Afghanistan,AF,AFG,4,Yes
Åland Islands,AX,ALA,248,No
Albania,AL,ALB,8,Yes
....
Spain,ES,ESP,724,Yes

La primera fila contiene el nombre de los diferentes campos, y cada una de las siguientes lleva los valores de esos campos de cada registro.

Puedes descargar el archivo entero desde aquí (ZIP, 3.5KB).

Procesar este tipo de archivos es muy sencillo pues es leer las líneas una a una y separarlas por las comas para obtener los campos correspondientes, así que se puede hacer con las capacidades básicas de cualquier lenguaje de programación o plataforma. Ahora bien, se pueden dar muchos casos especiales que hay que tener en cuenta, como campos vacíos por el medio, campos vacíos al final, valores que lleven comas como parte de su contenido... Y entonces la cosa empieza a complicarse.

Cómo leer archivos CSV con Java y opencsv

Lo primero es hacerse con el JAR de opencsv, que puedes descargar desde su página de SourceForge. Una vez descargado y añadido a tu proyecto el código necesario es muy directo:

String archCSV = "D:\\ISO-Codes.csv";
CSVReader csvReader = new CSVReader(new FileReader(archCSV));
String[] fila = null;
while((fila = csvReader.readNext()) != null) {
    System.out.println(fila[0]
              + " | " + fila[1]
              + " |  " + fila[2]);
}

csvReader.close();

Este código tan sencillo lo que hace es crear una instancia de la clase CSVReader expuesta por opencsv a la que le pasa en su constructor el FileReader de Java necesario para leer el archivo que nos interesa. Luego en un bucle indefinido de tipo while se recorren todas las filas una a una para leerlas y mostrar los valores de cada campo por la consola.

Fíjate en que, una vez leída una fila con readNext(), se obtiene un array que en cada una de sus posiciones tiene el valor correspondiente, y ya se tiene en cuenta cosas como las mencionadas (que falte un campo, etc...).

Usar un separador distinto a la coma

Si el separador utilizado fuera otro diferente (por ejemplo un ; en vez de una coma, cosa que hace Excel en Español cuando exportas una hoja de cálculo a CSV), simplemente deberías indicar dicho separador como segundo parámetro del constructor, así:

CSVReader csvReader = new CSVReader(new FileReader(archCSV), ';');

Fíjate que en este caso se usan comillas simples y no dobles ya que se trata de un literal de tipo char, no de una cadena. Si necesitamos usar caracteres especiales podemos "escapearlos" de la manera habitual. Por ejemplo, para usar un tabulador podríamos escribir:

CSVReader csvReader = new CSVReader(new FileReader(archCSV), '\t');

Datos con el separador dentro y "escapeados"

En los archivos CSV si necesitas incluir una coma dentro de un dato lo habitual es "escapear" ese valor utilizando un carácter delimitador que se pone al principio y al final del campo.

Por ejemplo, imagínate que tu dato contiene un valor decimal en español, que utiliza la coma, algo así:

Producto,Precio Kg,Disponible
Queso, "6,57",Sí
Pan, "1,32",No

En este tipo de casos lo más normal sería que cambiásemos el carácter delimitador, pero quizá no podemos. Por ello, lo que se hace es usar comillas dobles para envolver el valor del campo, como hemos hecho en este caso. Así, el precio del Queso, que son 6,57€/Kg, queda perfectamente delimitado y la coma que lleva dentro no se confunde con las comas que se utilizan como separadores de los valores.

Por defecto opencsv considera que las comillas dobles son el delimitador que se usa para este tipo de casos. Por ello no tendremos que hacer nada si es el que utiliza nuestro archivo. Pero si no es este el caso y se ha utilizado otro delimitador cualquiera (por ejemplo, unos "pipes", |, algo también muy habitual), se puede indicar como tercer parámetro del constructor:

CSVReader csvReader = new CSVReader(new FileReader(archCSV), '\t', '\|');

En este caso estaríamos indicando que el separador de valores es el tabulador y el delimitador de éstos es el "pipe".

Leer todas las filas de golpe

Si quisieras leer y obtener todas las líneas de golpe en lugar de ir una a una podrías usar el método readAll():

CSVReader csvReader = new CSVReader(new FileReader(archCSV));
List<String[]> datos = csvReader.readAll();

que ya nos entregaría una lista de matrices de cadenas que podemos procesar del mismo modo pero en un bucle determinado de tipo for.

Cómo generar archivos CSV con Java y opencsv

Ahora que ya sabemos cómo escribir los archivos, vamos a realizar el proceso inverso: partiendo de unos datos que tenemos en memoria (quizá en una matriz o una lista de objetos), vamos a crear en disco un archivo .csv con esa información delimitada por comas.

Suponiendo que queremos ir escribiendo línea por línea, el proceso se parece mucho al de lectura, usando un CSVWriter en lugar de la clase que usábamos para leer:

String [] pais = {"Spain", "ES", "ESP", "724", "Yes"};

String archCSV = "D:\\ISO-Codes.csv";
CSVWriter writer = new CSVWriter(new FileWriter(archCSV));

writer.writeNext(pais);

writer.close();

En este caso, por sencillez, estamos simulando que tenemos un dato metido en un array, pero en la práctica obtendríamos esta información de una base de datos, de la entrada de un usuario, etc... Eso ya es cosa tuya. Pero el proceso sería el mismo.

Si tenemos más de un dato al mismo tiempo (por ejemplo un conjunto de registros sacados de una base de datos) y queremos escribirlos todos de golpe, podemos usar writeAll() para ello:

//Creo mi lista de países (los sacaría de algún lado, aquí los creamos a mano para el ejemplo)
List<String[]> paises = new ArrayList<String[]>;
paises.add({"Afghanistan", "AF", "AFG", "4", "Yes"});
paises.add({"Spain", "ES", "ESP", "724", "Yes"});
//Etc...

String archCSV = "D:\\ISO-Codes.csv";
CSVWriter writer = new CSVWriter(new FileWriter(archCSV));

writer.writeAll(paises);

writer.close();

Con esto se escribirían todos de golpe.

Del mismo modo que antes podíamos especificar el separador y el delimitador como segundo y tercer parámetro del constructor respectivamente, en el caso del CSVWriter pasa exactamente lo mismo, por lo que podríamos indicar otros distintos a la coma y las comillas dobles por defecto, para que se usasen en la generación del archivo si así fuese necesario.

Técnicas más avanzadas

Lo que acabamos de ver es la manera más simple y directa de leer y escribir CSV desde Java. Si queremos tener más potencia podemos usar otras características avanzadas de opencsv para lograrlo. Pero esto ya se sale del ámbito y del espacio disponible para un artículo como este.

Por ejemplo, en archivos cuya primera línea contiene los nombres de los campos de los registros (como en el ejemplo de los países que vimos al principio), es posible obtener directamente objetos Java Bean mapeados cuyas propiedades son dichos campos, de modo que no tengamos que manejar elementos de un array por orden usando su índice. Y lo mismo para escribirlos a disco desde objetos. Para ello te remitimos a la documentación de opencsv (lectura y escritura), así como para aprender otras características más específicas de esta biblioteca (anotaciones, filtrado de datos, saltar registros...).

Cambiar el color de selección con CSS

05/12/2017
Artículo original

Espero y este post sea de tu agrado, no olvides compartirlo en su redes sociales y sobre todo.. Gracias por seguirnos!

¿Tienes un sitio web? ¿Deseas personalizarlo al máximo con los colores de tu marca? Hoy vamos a hablar sobre un efecto CSS para darle un toque más personalizado a nuestro sitio web, te mostraré como cambiar el color de selección con CSS para utilizar los colores de tu marca o negocio. Siempre queremos diferenciarnos de los demás, hablando de nuestra presencia en Internet no es la excepción. Ya hemos hablado sobre como añadir un icono font awesome en todos nuestros encabezados automaticamente, el efecto CSS de hoy es también muy significativo para darle un toque de personalización más a tu

Compartir en Facebook

Comparte en Google Plus

Compartir en Twitter

El post Cambiar el color de selección con CSS aparece en el Blog de Jonathan Melgoza

Criptografía 101 - Fundamentos Matemáticos (II) - Cálculo de Potencias

04/12/2017
Artículo original

Este artículo es parte del curso de Introducción a la Criptografía, el código está disponible en elbaulp/cripto, también hay una tabla de contenidos.

Cálculo de potencias

Queremos ahora, dados a, m y n calcular \(a^m\bmod n\), pero de forma eficiente, para ello definiremos el teorema de Fermat:

Sean \(a,n \in \mathbb N\), si \(mcd(a,n) = 1\), \(a^{\phi(n)} \equiv 1\pmod n\)

Veamos algunos ejemplos. En \(\mathbb Z_5,\ \phi(5) = 4\), luego, por el teorema de Fermat, tenemos que \(1^{4} = 2^{4} = 3^{4} = 4^{4} = 1\). En \(\mathbb Z_{53}, \phi(53) = 52\), para calcular \(7^{111}\), como \(mcd(7, 53) = 1\) entonces \( 7^{52} = 1\), luego \(7^{52\cdot 2} = 7^{104} = 1\) y por tanto \(7^{111} = 7^7 = 29\).

Un caso particular del teorema de Fermat, es el teorema Pequeño de Fermat:

Sea p primo, \(a \in \mathbb N:\ 1 \leq a \leq p-1\) entonces \(a^{p-1} \equiv 1\pmod p\)

Como consecuencia a esto se tiene que \(a^{p} \equiv a\pmod p\). Veamos algunos ejemplos:

Calculemos las unidades de \(\mathbb Z_4\), que son \(\mathcal U(\mathbb Z_4) = \{1,3\}\), sabemos que únicamente tiene dos unidades, porque \(\phi(4) = \phi(2^2) = 2\), y particularmente son el 1 y el 3, porque cumplen que \(1^2 = 3^2 = 1\). Más arriba vimos que en \(\mathbb Z_5,\ \phi(5) = 4\) y por tanto todos sus elementos tienen inverso, comprobemos que también se cumple una de las variantes del teorema Pequeño de Fermat en \(\mathbb Z_5\). El teorema dice \(a^{p} \equiv a\pmod p\), como vemos, en \(Z_5, 0^5 = 0, 1^5 = 1, 2^5 = 2, 3^5 = 3, 4^5 = 4\).

Algoritmo para el cálculo de potencias

Uno de los algoritmos usados para el cálculo de potencias modulares es el siguiente:

  • Entrada: \(a\in\mathbb Z_n\), un entero \(0 \leq k < n\) cuya representación binaria es \(\sum_{i=0}^t k_i 2^i\).
  • Salida: \(a^k \pmod n\)

  1. Fijar b = 1, Si k = 0 devolver b.
  2. A = a
  3. Si k_0 = 1 entonces b = a
  4. Para cada i desde 1 a t repetir:
     1. A = A * A modulo n.
     2. Si k_i = 1 entonces b = A * b modulo n
  5. Devolver b

Este algoritmo se basa en el hecho de que se puede representar el exponente en representación binaria. La representación binaria de k viene dada por \(\sum_{i=0}^t k_i 2^i\), donde cada \(k_i\in \{0, 1\}\). Quizá con esta notación no te resulte familiar, pero no es más que la forma abreviada de la más conocida, por ejemplo, 5 en binario es \(1\cdot 2^0 + 0\cdot 2^1 + 1\cdot 2^2\). Sabiendo esto, entonces

$$a^k = \prod_{i=0}^t a^{k_i 2^i} = (a^{2^0})^{k_0}(a^{2^1})^{k_1}\cdots(a^{2^t})^{k_t}$$

Si analizas un poco la expresión de arriba, cuando \(k_i = 0\) todo el término \((a^{2^i})^{k_i} = 1\), lo cual implica que ese cálculo no va a cambiar el resultado, porque estás multiplicando por 1.

Con este apunte, leer el algoritmo es sencillo. Recibe un número entero y otros dos números, k,n > 0 y calcula \(a^{k} \pmod n\). Si k==0 no es necesario hacer ningún cálculo y simplemente devolvemos 1, ya que cualquier cosa elevada a cero es 1. En el paso 3, si \(k_0\) (el bit menos significativo de la representación binaria) es 1, luego \((a^{2^0})^{k_0} = a\), de lo contrario b = 1, ya que estás elevando a 0, y cualquier número elevado a 0 es 1. El siguiente paso es iterar sobre los bits restantes de k, es decir, desde \(k_1 \dots k_t\). Básicamente se repite el mismo proceso, se eleva al cuadrado A (corresponde con esta parte de la expresión \((a^2\)), y si el bit \(k_i = 1\) multiplicas \((a^{2^i})^{1}\) por b, si \(k_i = 0\) no hace falta hacer nada, ya que toda la expresión \((a^{2^i})^{0} = 1\). Una vez recorrida la representación binaria de k, devolvemos b.

Para entenderlo mejor, imagina que quieres calcular \(2^5\pmod 5\). El primer paso es representar el exponente en binario, \(5 = 101_b\), sigue los pasos del algoritmo, donde a = 2, k = 5 y n = 5:


b = 1
A = 2
es k_0 == 1? sí -> b = 2
Desde k_1 hasta k_t:
   A = A * A mod n -> 2 * 2 mod 5 = 4
   es k_1 == 1? no
   A = A * A mod n -> 4 * 4 mod 5 = 1
   es k_2 == 1? sí -> b = A * b mod n -> b = 1 * 2 mod 5 = 2
devuelve b, que es 2

He intentado hacer dos representaciones visuales de cómo funciona, supón que quieres calcular \(2^7 \pmod 5\) y \(2^{11} \pmod 5\):

Calcular potencias modulares criptografía
Calcular potencias modulares criptografía

Calcular potencias modulares criptografía

Espero que con este ejemplo te haya quedado claro cómo funciona el algoritmo. Lo he implementado en python, el código fuente está disponible en github:

def powerModInt(a,k,n):
  """
      @input a in $Z_n$ and integers 0 <= k <= n
      @output a to the power of k mod n ($a^k mod n$)
  """
  b = 1
  if k == 0:
      return b
  A = a
  # If the least significant bit is 1, $a^1 = a$
  if 1 & k:
      b = a
  k = k >> 1
  while k:
      A = (A**2) % n
      if 1 & k:
          b = (b * A) % n
      k = k >> 1
  return b

Orden

Definiremos el orden de un número como \[ord(a) = min(k\ \in \mathbb N\backslash 0\:a^k=1)\] es decir, el número mínimo al que hay que elevar a para que sea igual a 1. Así, por ejemplo, en \(\mathbb Z_5\), tenemos los siguientes órdenes para sus elementos:

  • \(1^1 = 1; ord(1) = 1\), ya que el número mínimo al que hay que elevar 1 para que de 1, es 1.
  • \(2^4 = 1; ord(2) = 4\)
  • \(3^4 = 1; ord(3) = 4\)
  • \(4^2 = 1; ord(4) = 2\), ya que el número mínimo al que hay que elevar 4 para que de 1, es 2.

Subgrupos y primitivos

Sea a un elemento de \(\mathbb Z_p\), por ejemplo, \(\lt a> = \{ a^k:\ k\in N \}\) es un subgrupo generado por a.

Por ejemplo, los subgrupos de las unidades de \(\mathbb Z_5\) son:

  • \(<1> = \{ 1 \}\), ya que \(\forall k \in\mathbb Z, 1^k = 1\)
  • \(<2> = \{ 2^0 = 1, 2^1 = 2, 2^2 = 4, 2^3 = 3\} = \{ 1, 2, 3, 4 \}\)
  • \(<3> = \{ 3^0, 3^1, 3^2, 3^3\} = \{ 1, 2, 3, 4 \}\)
  • \(<4> = \{ 4^0, 4^1, 4^2, 4^3 \} = \{ 1, 4 \}\)

Si nos fijamos, tanto <2> como <3> generan por completo \(\mathbb Z_5\), estos elementos se llaman primitivos. Particularmente, <a> será primitivo si su orden es máximo, en el caso que nos ocupa, vemos que es cierto, puesto que \(\phi(5)=4, ord(2) = ord(3) = 4\), que es el máximo. Además, el orden de un número establece número de elementos que genera el subgrupo, como ord(2) = ord(3) = 4, sabemos que éstos subgrupos generan 4 elementos, que son el número de unidades de \(\mathbb Z_5\), y por tanto, lo generan completamente. De igual manera, vimos un poco más arriba que ord(4) = 2, y podemos comprobar 4 genera únicamente dos elementos.

Referencias

Todo el código mostrado en los artículos está disponible en github

Criptografía 101: Fundamentos matemáticos (I) - Aritmética modular

04/12/2017
Artículo original

Aritmética modular

Antes de profundizar en los temas sobre criptografía, es necesario tener una base matemática, ya que al fin y al cabo, la criptografía se basa en ellas.

Nos centraremos en la aritmética modular, y cómo operar con ella. La aritmética modular se define del siguiente modo:

\[a \equiv b\pmod n,\]

si \(b - a\) es múltiplo de \(n\) o, dicho de otro modo, \(a\) y \(b\) tienen el mismo resto cuando se dividen por \(n\).

Así, por ejemplo, \(3 \equiv 8 \pmod 5\), ya que \(8 - 3 = 5\), que es un multiplo de 5. También podemos comprobarlo sabiendo que el resto de dividir 3 entre 5 es 3 y el resto de 8 entre 5, también. A partir de ahora expresaremos el resto de dividir un número entre otro como sigue:

\[a\bmod n = r,\]

donde \(r\) es el resto de dividir \(a\) entre \(n\).

Modular Arithmetics

Cálculo de inversos

Sea \(a \in \mathbb Z_n\), se dice que \(a\) tiene inverso, o que es una unidad, si \(\exists b \in \mathbb Z_n\ :\ ba = 1\), y se denota por \(a^{-1}\).

Al conjunto de todas las unidades de \(\mathbb Z_n\) lo llamaremos \(\mathcal{U}(\mathbb Z_n)\) y se define como:

\[\mathcal{U}(\mathbb Z_n) = \{ a \in \mathbb Z_n : \exists a^{-1}\} = \{ a \in \mathbb Z_n : mcd(a, n) = 1\},\]

donde mcd es el máximo común divisor.

Particularmente, si \(p\) es un número primo, todo elemento de \(\mathbb Z_p\), salvo el cero, tiene inverso, y por tanto \(\mathbb Z_p\) es un cuerpo. En criptografía, trabajaremos en cuerpos \(\mathbb Z_p\) con un \(p\) primo.

El número de unidades de \(\mathbb Z_n\), se puede calcular con la función de Euler \(\phi(n)\), y vale lo siguiente:

  • Si \(p\) es un número primo, \(\phi(p) = p - 1\), ya que todos los elementos salvo el 0, son unidades.
  • Sean a, b, dos números enteros \( \phi(ab) = \phi(a)\phi(b)\ sii\ mcd(a, b) = 1\).
  • Sea \(p\) un primo, \(\phi(p^n) = p^n - p^{n-1}\).

Por ejemplo, \(\#\mathcal{U}(\mathbb Z_5) = 4\), ya que todos sus elementos tienen inverso (el 1,2,3,4), y \(\phi(5) = 4\), y por tanto, \(\mathbb Z_5\) es un cuerpo. Sin embargo, \(\#\mathcal{U}(\mathbb Z_{15}) = 8\), ya que \(\phi(15) = \phi(3)\phi(5) = 2\cdot 4 = 8\). Las unidades de \(\mathbb Z_{15}\) son 1,2,4,7,8,11,13,14.

Un ejemplo práctico

Veamos ahora cómo calcular el inverso de un número en \(\mathbb Z_n\) mediante el algoritmo Extendido de Euclides implementado en python, el código fuente está disponible en github:

def extMcd(a,b):
    """
    Compute the Greatest Common Divisor d of a and b, and integers x and
    y satisfying ax + by = d.

    :returns: a tuple (d,x,y)
    """

    if b == 0:
        return a,1,0
    x2 = 1
    x1 = 0
    y2 = 0
    y1 = 1

    while b != 0:
        q = a//b
        r = a - q * b
        x = x2 - q * x1
        y = y2 - q * y1
        a = b
        b = r
        x2 = x1
        x1 = x
        y2 = y1
        y1 = y

    if a < 0:
        return map(int, (-a, -x2, -y2))
    return map(int, (a, x2, y2))

Este algoritmo, devuelve una tupla (d, x, y), donde d es el máximo común divisor de los números a,b y x es el inverso de a mod b. Por ejemplo, si ejecutamos mcd(2, 5), nos devolverá [1, -2, 1], donde 1 es el mcd(2, 5), y \(-2\) su inverso, si lo queremos en positivo, basta con sumar 5 a \(-2\), que es 3, luego el inverso de 2 mod 5 es 3, ya que \(2 \cdot 3 = 6\), y 6 mod 5 = 1.

Para facilitar la tarea de calcular el inverso de un número, definiremos el siguiente método, el código fuente está disponible en github:

def moduloInverse(a,n):
    """:returns: the inverse of a modulo b, if it exists"""
    d,x,y = extMcd(a,n)

    if d > 1:
        return u' a inverse does not exist'
    else:
        return x % n

Si lo ejecutamos con los mismos números de antes, 2 y 5, nos devolverá \(2^{-1}\), es decir, 3.

Agradecimientos

Gracias a josealberto4444 por ayudarme con correcciones.

Referencias

Todo el código mostrado en los artículos está disponible en github

Más información

Construyendo aplicaciones distribuidas con Erlang/OTP

04/12/2017
Artículo original

2671066786_4cd860edeb_o.jpg

Cualquiera que se haya enfrentado a la construcción de un sistema distribuido, se habrá dado cuenta que no es tarea fácil. Ya sea porque estamos construyendo un sistema a base de microservicios, porque estamos repartiendo un problema en partes para solucionarlas de forma paralela, o porque nuestro sistema tiene una concurrencia muy alta, nos enfrentaremos a una serie de problemas que son de sobra conocidos. Y es que hay muchos factores a tener en cuenta, como el control de la concurrencia, la sincronización de los datos o la tolerancia a fallos. La buena noticia es que si somos programadores de Elixir o Erlang, lo tendremos mucho más fácil gracias a OTP.

OTP

OTP (Open Telecom Platform), es un conjunto de librerías, herramientas y patrones que nos permiten gestionar procesos y concurrencia con mucha más facilidad. OTP fue creado pensando en centralitas telefónicas, que por aquella época (hablamos de mediados de los 90), eran de los pocos sistemas altamente concurrentes que existían. Con el paso del tiempo, fueron apareciendo más problemas que OTP podía resolver y es que sus creadores consiguieron crear un modelo capaz de lidiar con conceptos como distribuido, tolerante a fallos, escalable, que funciona en tiempo real y altamente disponible. ¿Qué significan estos términos?

  • Escalable: cuando un sistema puede adaptarse a cambios de carga o recursos disponibles.
  • Distribuido: se refiere a cuando podemos agrupar sistemas y como interactúan unos con otros. Podemos crear grupos de sistemas de forma horizontal, por ejemplo añadiendo más máquinas hardware, para tener más recursos o añadir capacidad de proceso de forma vertical haciendo más potentes nuestras máquinas hardware virtualizadas.
  • Tolerante a fallos: todo el sistema se comportará de forma previsible cuando se produzcan fallos. Si el sistema es tolerante a fallos, la latencia y la capacidad de respuesta no se verán mermadas en exceso y el sistema podrá continuar funcionando de forma normal.
  • Funcionamiento en tiempo real: el tiempo de respuesta y la latencia serán constantes, y seremos capaces de devolver una respuesta en un tiempo razonable y normalmente bajo. Independientemente de las peticiones concurrentes que recibamos, deberemos ser capaces de responder a todas ellas.
  • Alta disponibilidad: da igual que tengamos un bug en nuestro código, el sistema debe seguir funcionando. Es decir, que las actualizaciones del código, los parches u otras operaciones típicas de mantenimiento, no deben parar el sistema, que debe seguir funcionando de forma continua.

Los creadores de Erlang/OTP consiguieron crear un modelo capaz de lidiar con conceptos como distribuido, tolerante a fallos, escalable, que funciona en tiempo real y altamente disponible

Con OTP, y utilizando tanto Erlang, como Elixir, podemos conseguir controlar todas estas características de los sistemas distribuidos de forma robusta. ¿Y cómo consigue OTP hacer sencillo (o abordable) lo que es complejo? Pues con una mezcla de las siguientes características.

Erlang/Elixir

Un lenguaje funcional es de ayuda a la hora de conseguir cierta seguridad a la hora de crear software distribuido, pero más importante es la inmutabilidad del mismo. En otros lenguajes mutables, debemos recurrir a sistemas de sincronización de datos para evitar problemas acceso concurrente. Semáforos, monitores, bloqueos etc. son palabras conocidas entre todos aquellos que nos hemos visto en la necesidad de programar alguna aplicación basada en hilos o procesos.

Con Erlang y Elixir es algo que tenemos solucionado desde la base, ya que al ser los datos inmutables, nos evitamos de un plumazo todos estos problemas. Si las estructuras de datos de nuestros programas no pueden modificarse, no existirán problemas de concurrencia.

Además, estos dos lenguajes también están diseñados para lanzar procesos de forma sencilla y su forma de gestionarlos nos ayuda mucho a la hora de generar aplicaciones diseñadas para trabajar de forma distribuida.

La máquina virtual BEAM

Otra de las patas importantes en OTP es la máquinva virtual. Erlang y Elixir corren sobre una máquina virtual conocida como BEAM, que curiosamente son las siglas de Bogdan/Björn's Erlang Abstract Machine, nombres de dos programadores que trabajaban en Ericsson por la época.

En palabras de Joe Armstrong, uno de los coautores de Erlang "Puedes emular la lógica de Erlang, pero si no corre sobre la máquina virtual de Erlang no puedes emular su semántica". Así que, por muy bonitos que sean los lenguajes de programación, sin una máquina virtual bien diseñada, no tendríamos muchas de las funcionalidades cubiertas.

"Puedes emular la lógica de Erlang, pero si no corre sobre la máquina virtual de Erlang no puedes emular su semántica". Joe Armstrong

El código que generamos con Erlan o Elixir (y algún lenguaje más) hay que compilarlo, para crear un archivo con extensión .beam. Ese archivo es al final el que se ejecuta sobre BEAM.

BEAM está optimizada para gestionar concurrencia, tiene un recolector de basura por cada proceso (haciendo que la recolección sea más sencilla y rápida) y que funciona de forma muy predecible y consistente en todos los casos.

Herramientas y librerías

Además de Erlang y Elixir como lenguajes, y además de BEAM como máquina virtual, OTP incluye otra serie de añadidos que hacen toda la magia posible. Algunas de estas características son el Erlang runtime system (ERS), algunas librerías estándar (stdlib), bases de datos distribuidas como MNESIA, una colección de protocolos e interfaces para comunicarse con otros lenguajes de programación, como C o Java, herramientas de seguridad como SSL, sistemas de acceso a LDAP y un largo etc. así como un debugger gráfico y Observer para monitorizar procesos.

Nodos

Los nodos son un conjunto de las herramientas anteriormente descritas, así como de herramientas de terceros, que funcionan sobre el sistema operativo. Cada nodo, puede funcionar de forma independiente, pero se comunica con el resto de nodos de la red, permitiendo hacer nuestro sistema escalable de forma horizontal.

Cada nodo puede conectarse a uno o varios nodos, de forma transitiva. Es decir, que si tenemos un nodo A, conectado a B, y conectamos B a C, C también estará conectado con A. Para gestionar la seguridad de los nodos se utiliza lo que se conoce como una magic cookie. Cuando se intenta una conexión entre nodos, se comprueba esta cookie y si coincide los nodos pueden conectarse. En otro caso se rechaza la conexión.

Procesos

Actor

Aunque OTP está compuesta de muchas partes diferentes, podríamos decir que la parte principal son los procesos. Al final son los procesos los encargados de realizar las operaciones demandadas, y la gestión que hace OTP de ellos es parte fundamental en todo el sistema.

No debemos pensar en los procesos como si estuviéramos hablando de procesos del Sistema Operativo. En este caso los procesos son mucho más livianos, lo que nos permite ejecutar muchísimos de forma concurrente sin que nuestro sistema se resienta. De hecho un nodo puede ejecutar cientos de miles de procesos (incluso millones dependiendo de la potencia del hardware), sin afectar al rendimiento.

Un proceso en Erlang/Elixir está compuesto por su buzón de mensajes, su propio recolector de basura, un stack con la información necesaria y una zona para gestionar los enlaces a otros procesos. En conjunto, es probable que el tamaño no sea más que de 1Kb (2Kb en sistemas de 64 bits). Como veis los procesos son muy pequeños, lo cual hace que el cambio de contexto que tiene que realizar el procesador sea rapidísimo.

Proceso

Pero la parte más importante es sin duda la comunicación entre procesos. Los procesos se comunican en base a un modelo de actores, o lo que es lo mismo, los procesos no comparten memoria, y solo se comunican unos con otros a través del buzón de mensajes. Una vez más esto nos evita muchos problemas de concurrencia.

Si un proceso quiere comunicarse con otro, dejará un mensaje en el buzón del proceso destinatario, que el proceso receptor procesará cuando le sea posible. Gracias a este modelo de actores, nos evitamos los problemas relacionados con compartir memoria y hacemos mucho más sencillo el trabajo del recolector de basura.

Al tener la posibilidad de gestionar los procesos de forma independiente, se nos presentan interesantes opciones para crear estructuras jerárquicas de procesos de forma que sea mucho más sencillo gestionar los procesos. Es aquí donde entran en juego los conceptos de aplicación, supervisor o los más básicos como los GenServer.

Supervisores

Los supervisores son procesos que tienen el único objetivo de lanzar y monitorizar procesos hijos. Son capaces de detectar cuando un proceso que depende de él se ha detenido (por un fallo o por una ejecución normal), y dependiendo de su configuración, utilizar diferentes estrategias para su reinicio. Son las siguientes:

  • One for one: si un proceso falla, se vuelve a reiniciar ese y sólo ese proceso. One For One

  • One for all: si un proceso falla, se detienen todos los procesos de ese supervisor y se vuelven a iniciar.

One For All

  • Rest for one: si un proceso falla, además de él, se detienen todos los procesos que se hayan iniciado después y se vuelven a iniciar. Rest For One

Por tanto la clave a la hora de usar supervisores, es asegurarse de que el orden de inicio está correctamente designado y la estrategia de reinicio elegida es la correcta.

Con todo esto podemos crear estructuras de supervisión más o menos complejas. Los fallos se pueden ir propagando hacia arriba en la jerarquía de supervisión. Si un proceso falla, su supervisor decidirá reiniciarlo. Si el problema se soluciona con ese reinicio, la ejecución continuará de forma normal. Pero si el proceso reiniciado vuelve a fallar, se seguirá intentando, hasta que se alcance un límite de intentos preconfigurado. Es ahí cuando el supervisor se detendrá y pasará el error a su propio supervisor. Si ningún reinicio soluciona el problema, es posible que se tomen medidas drásticas como reiniciar la máquina virtual, o incluso reiniciar la máquina.

Aplicaciones

Las aplicaciones no tienen una definición fácil, pero son algo así como conjuntos de módulos, supervisores, configuraciones y otros recursos. Estos conjuntos son independientes unos de otros y es una forma de agrupar código para poder desplegarlo en cualquier parte. Por ejemplo podemos desplegar una aplicación en un nodo de Erlang y dicha aplicación podrá ser arrancada y detenida como un todo. Las aplicaciones pueden ser de tipo normal o de tipo librería. Las primeras arrancan un supervisor para poder gestionar los procesos dependientes, mientras que las de tipo librería no lo hacen, ya que no lo necesitan.

GenServer

Un GenServer, implementa la típica estructura cliente servidor. Aunque con Erlang y Elixir pueden lanzarse procesos de forma manual, es mucho más sencillo crearlos a través de un GenServer. Los GenServer se basan en comportamientos (behaviours en inglés), que definen una interface común para la comunicación entre procesos. Esta interface utiliza llamadas handle_call (síncronas) y handle_cast (asíncronas), para realizar todas las operaciones requeridas. Los GenServer se pueden iniciar desde una función start_link, que suele ser utilizada, entre otras cosas, por los supervisores a la hora de arrancar el proceso.

Como hemos comentado antes, con OTP utilizamos un modelo de actores, y solo podemos comunicarnos con un proceso a través de su buzón de mensajes. Si utilizamos los call, nuestro proceso quedará a la espera de una respuesta del proceso remoto, mientras que si utilizamos cast, continuaremos la aplicación sin esperar ninguna respuesta.

Actualización en caliente

Como decíamos, si un sistema que tiene que tener alta disponibilidad no puede detenerse para ser actualizado. Debemos asegurar que el sistema es capaz de funcionar incluso cuando tenemos que aplicar parches para corregir bugs o para añadir nueva funcionalidad.

Por suerte, con OTP, tenemos la posibilidad de utilizar la actualización de código en caliente. Para ello los módulos tienen que cargarse previamente, de lo que se encarga un componente de OTP conocido como servidor de código.

En el sistema puede haber hasta dos versiones de un mismo módulo, aunque inicialmente solo habrá una versión. Si realizamos algún cambio en el código, la versión existente pasará a ser la versión antigua, y la versión nueva pasará a ser la actual. Ambas versiones pueden seguir funcionando, ya que puede haber módulos que estén siendo utilizados por algún proceso en ejecución. Cuando sea posible, OTP irá actualizando los módulos de todos los procesos en ejecución. Si tenemos dos versiones y añadimos una tercera, la versión inicial será eliminada y los procesos que aun estén funcionando con ella serán detenidos.

Tolerancia a fallos

Los nodos de Erlang/OTP entran en juego cuando queremos hacer que nuestra aplicación sea tolerante a fallos. Aunque al tener más de un nodo, nos encontramos con otros problemas típicos de la programación distribuida.

Problemas en el paso de mensajes

Tenemos multitud de procesos en ejecución, que pueden ejecutarse en distintos nodos. Si hay fallos de red, sobrecarga de procesos o cualquier otro problema, cabe la posibilidad de que algún mensaje se pierda. En este caso podemos seguir tres estrategias distintas:

  • Al menos uno: imagina que tenemos un servidor web en el que queremos iniciar sesión. Si la primera petición falla, podemos intentarlo en otro nodo. Si el segundo nodo funciona, nos quedamos con la sesión de este. Es posible que la primera petición acabe funcionando (aunque con retraso), pero nosotros la ignoraremos.
  • Como mucho uno: imaginemos que un sistema que envía SMS. Si nuestro sistema envía millones de mensajes al día, es posible que la pérdida de algunos mensajes sea asumible y no nos preocupe. En ese caso realizamos la petición de envío de SMS y nos olvidamos.
  • Exactamente uno: en este caso tenemos que asegurar que la petición se ejecuta una vez (y solo una). Si solo tenemos un nodo, no habrá problemas, pero la cosa se complica si hay varios. Si un nodo falla, podemos solicitar a otro que resuelva la petición. ¿Pero por qué ha fallado el primero? Puede ser porque nunca le llegó la petición, porque sufrió un error o incluso recibió la petición, pero lo que se ha perdido ha sido la respuesta. En cualquier caso, deberemos pensar en estos problemas a la hora de utilizar esta estrategia.

Problemas con los datos compartidos

Si tenemos varios nodos funcionando, nos encontraremos con el problema de los datos compartidos entre ellos. En este caso podemos seguir varias estrategias:

  • No compartir nada: los procesos de un nodo tienen cada uno su versión de los datos y de su estado actual y no lo comparten con ningún otro nodo. Esto hace que la escalabilidad del sistema sea predecible y lineal. El problema de esta estrategia, es que si perdemos el nodo, también perdemos los datos y el estado actual de los procesos.
  • Compartir una parte: si queremos asegurar de que aunque un nodo falle, podamos conservar los datos más críticos, utilizamos esta estrategia. Los datos y el estado se irán copiando entre nodos, para asegurarnos de tener una copia en cada uno. Esto reduce algo el rendimiento, y nos crea el problema de que si un nodo se reinicia, tiene que volver a adquirir los datos de todos los procesos.
  • Compartir todo: en este caso no nos podemos permitir que se pierda un solo dato, y debemos asegurarnos de que una transacción se ejecuta una sola vez. Esta técnica es la más segura, pero también nos obliga a sacrificar escalabilidad.

Consistencia vs disponibilidad

Aunque las soluciones reales no son tan simples, el teorema de CAP ya nos indica que todo sistema distribuido tiene que elegir entre consistencia, disponibilidad y tolerancia a particiones. Y cuando diseñamos nuestra aplicación distribuida, es algo que debemos tener en cuenta.

Por ejemplo en las estrategias para gestionar el paso de mensajes, podemos ver que dependiendo de la que elijamos tendremos que sacrificar o bien la consistencia o bien la disponibilidad. La estrategia al menos uno es muy escalable, pero no muy consistente, mientras que la estrategia exactamente uno es muy consistente, pero mucho menos escalable, por lo que la disponibilidad se resiente.

Lo mismo nos pasa con el tema de compartir datos. Compartir todo hace que seamos mucho más fiables, pero que nuestra disponibilidad sea menor. Si no compartimos nada, pasa justamente lo contrario, somos menos fiables, pero nos aseguramos una alta disponibilidad.

Conclusión

Erlang/Elixir y OTP nos proporcionan muchas herramientas para que construir sistemas distribuidos sea mucho menos doloroso que con otras plataformas y lenguajes de programación. Aun así, no es tarea fácil y hay muchos aspectos que deberemos tener en cuenta para asegurar que nuestra aplicación sea escalable, tolerante a fallos, altamente disponible etc.

En definitiva, construir sistemas distribuidos es difícil, pero muy divertido.

Imagen | Mathias.Pastwa

También te recomendamos

Vivir para ver: los negocios que no creerás que existen

Elixir, lenguaje de propósito general concurrente

Pliegues, una forma de encapsular las iteraciones en listas

-
La noticia Construyendo aplicaciones distribuidas con Erlang/OTP fue publicada originalmente en Genbeta Dev por rubenfa .

Qué son las arquitecturas sin servidor (Serverless Computing) en la nube y por qué deberían interesarte

04/12/2017
Artículo original

Quizás ya hayas oído hablar de la nueva palabra de moda en la industria del software y la programación: la computación sin servidor o serverless computing.

¿Cómo funciona? ¿Por qué es importante? ¿Es una nueva moda pasajera o una tendencia real?

Los pilares de la informática sin servidor

Aunque no significa verdaderamente que no haya servidores por debajo (que los hay), el nombre de esta tecnología hace referencia al hecho de que, desde el punto de vista del desarrollo y mantenimiento de la aplicación, es como si no los hubiese. Enseguida lo veremos...

1.- Olvídate de servidores, sistema operativo, instancias...

La informática serverless está totalmente gestionada. Es decir, nunca tienes que reservar explícitamente instancias de servidor como sí pasa en IaaS (plataforma como servicio, como por ejemplo Azure Web Apps, Google App Engine o AWS Elastic Beanstalk) o por supuesto en PaaS (máquinas virtuales). Esto se gestiona de manera automática desde la plataforma. Cada ejecución de una función podría ejecutarse en una instancia de computación diferente, siendo completamente transparente para tu código.

La evolución ha sido pasar de los servidores físicos en un Data Center, a servidores virtuales en ese mismo Data Center, a servidores virtuales en la nube, a contenedores dentro de servidores virtuales, y ahora serverless computing.

Gracias a la informática sin servidor nos podemos olvidar de:

  • Aprovisionar servidores
  • Mantenerlos y gestionarlos
  • Escalar la aplicación (va en automático: ver punto siguiente)
  • Preocuparnos de la disponibilidad y la tolerancia a fallos

2.- Escalabilidad impulsada por eventos

La informática sin servidor encaja muy bien para cargas de trabajo que responden a eventos entrantes. Los eventos incluyen:

  • Temporizadores, por ejemplo ejecutar esta función todos los días a las 10 de la mañana
  • Llamadas HTTP para escenarios API y WebHook
  • Colas: por ejemplo, procesamiento de pedidos
  • Y mucho más...

La idea con funciones serverlesss es que, en lugar de programar una aplicación completa, escribes una "función", que contiene tanto código (lo que va a hacer) como metadatos (sus desencadenadores o triggers y los enlaces con otros sistemas). La plataforma programa automáticamente la ejecución de tu función y escala el número de instancias de cálculo en función de la tasa de eventos entrantes. Los desencadenadores definen cómo se invoca una función.

Los enlaces de entrada y salida proporcionan una forma declarativa de conectarse a los servicios desde tu código.

Por ejemplo (y este es un ejemplo sacado de la documentación de Microsoft), supón que quieres crear un archivo nuevo en el servicio de almacenamiento Azure Blob Storage cada cinco minutos. Para ello en Azure Functions utilizarías un desencadenador de tipo temporizador y un enlace de salida blob:

Ejemplo de función desencadenada por un temporizador

3.- Micro facturación.

Con la arquitectura sin servidor pagas únicamente cuando se está ejecutando tu código. Si no hay ejecuciones de funciones activas, no se te cobra. Por ejemplo, si tu código se ejecuta una vez al día durante 2 minutos, se te facturará 1 unidad de ejecución y 2 minutos de cómputo.

¿Por qué es importante la arquitectura sin servidor?

Los desarrolladores hace ya años que están incorporando a sus desarrollos la arquitectura de microservicios, una forma de arquitectura SOA (Service Oriented Architecture). Las aplicaciones basadas en microservicios dividen la funcionalidad en servicios especializados, muy desacoplados, que se comunican entre ellos y colaboran a través de APIs. Cada microservicio se ejecuta independientemente de los demás en su propio proceso, máquina virtual o contenedor. La ventaja principal de esto es la separación de responsabilidades, que hace que las aplicaciones sean más fácil de desarrollar, mantener y escalar.

La contrapartida de los microservicios es que aumenta el trabajo de gestión y mantenimiento de infraestructura, así como la orquestación del conjunto, la integración y el versionamiento. Normalmente solo compensan a empresas grandes con aplicaciones grandes. De hecho empresas influyentes como Basecamp hablan de las ventajas de las aplicaciones monolíticas en las empresas pequeñas debido precisamente a la complejidad de la gestión entre otros factores.

Sin embargo la computación sin servidor va un paso más allá de los microservicios, llevándolos al extremo: como desarrolladores lo único que nos importa es definir cada funcionalidad y cada lógica de negocio, dejando que del resto se encargue el proveedor Cloud.

En conjunto, estas funciones te permiten centrarte en tus aplicaciones, y no en los servidores. Esto significa que habrás reducido la necesidad de gestionar servidores y sistemas y tendrás un entorno informático más productivo. Con ella algunos proyectos se pueden completar en días o semanas, en lugar de meses, reduciendo además el coste.

¿Moda o tendencia de futuro?

La informática sin servidor no es un nuevo concepto de moda pasajero, representa un cambio dramático en la forma en que los desarrolladores piensan en las aplicaciones en la nube, ya que sólo necesitan preocuparse por el código y cómo se desencadena su funcionamiento. La plataforma se encarga del resto.

Aunque lo serverless todavía está en su infancia, todos los grandes operadores de Cloud Computing ofrecen también servicios de funciones "sin servidor":

Como ves no se trata de una tecnología "rara" de un proveedor especializado, sino que están en todas partes y han venido para quedarse, así que deberías empezar a investigarlas ya.

Para evitar estar atado a un proveedor una vez que crees una solución serverless, existen bibliotecas intermedias que se encargan de unificar los diferentes modelos de distintos proveedores de modo que puedas crear funciones que luego puedan ejecutarse en las nubes más populares. La más conocida de estas bibliotecas es, probablemente, Serverless, que además es Open Souce.

14 de los proyectos open source más activos en GitHub

29/11/2017
Artículo original

Trending

En GitHub hay miles, incluso decenas de miles de proyectos de software open source (y otras muchas cosas, que abogados, periodistas o escritores están apuntándose cada vez más al versionado). Tantos que uno puede no saber por donde empezar. Una manera muy interesante es el propio ranking de tendencias de GitHub, una especie de Los 40 Principales del software libre, ideal para encontrar proyectos en los que colaborar, forkearlos o simplemente inspirarse. Estos son actualmente los más calientes a fecha de noviembre de 2017. Sí, la mayoría son Javascript.

Disclaimer #1: nos hemos centrado en proyectos de desarrollo, dejando de lado tutoriales, best practices o recopilatorios de links, aunque haya algunos tan virales y útiles como Awesome o Flight rules for Git

Disclaimer 2: y dentro de los proyectos de desarrollo hemos dejado de lados aquellos muy populares y de largo recorrido como React o Visual Studio Code

The Front-End Checklist

Front End Checklist

Casi 12.000 estrellas en el último mes para este proyecto de verificador del front (HTML, CSS, Javascript, SEO, rendimiento...) de webs creado por David Dias en Pug (el motor de plantillas anteriormente conocido como Jade). Más de 1.500 forks y 500 commits para uno de los proyectos más relevantes actualmente en GitHub.

Repositorio en GitHub | Sitio web

Ant Design Pro

Ant Design Pro

Interfaz de administración para aplicaciones basado en React recién salido del horno que cuenta con más de 4.300 estrellas en el último mes de la empresa china Ant Design. Responsive, con tests unitarios, temas customizables, soporte de internacionalización... muy completo.

Repositorio en GitHub | Sitio web

nba-go

Nba Go

Como esas aplicaciones que te ofrecen las estadísticas del fútbol pero de la NBA y en formato línea de comandos. Proyecto de reciente factura, muy llamativo y divertido (ojo a los gifs en el repositorio) y ya con más de 2.600 estrellas y cerca de 100 commits en GitHub.

Repositorio en GitHub

Frappe Charts

Frappe

Una novel librería de gráficas Javascript con más de 9.000 estrellas en GitHub en los últimos días. Realizada por los indios de Frappé destaca por su sencillez, por ser responsive y por no tener dependencias (algo que, personalmente, cada vez valoro más).

Repositorio en GitHub | Sitio web

TensorFlow

Tensor Flow

Proyectazo de computación con gráficos de flujo para machine learning que en menos de dos años tiene ya más de 38.000 forks, 25.000 commits y 1.100 contribuyentes y es usado por grandes empresas como Airbnb, Snapchat o Twitter. Además sigue en plena forma y en el último mes han recibido más de 5.000 estrellas en GitHub.

Repositorio en GitHub | Sitio web

Bottery

Google tiene centenares de repositorios en GitHub. Uno de los más recientes es este Bottery que, según su propia definición, es "una sintaxis, editor y simulador para prototipado de conversaciones contextuales generativas modeladas como máquinas de estado finito". No es un producto oficial de Google, ya lleva más de 3.000 estrellas.

Repositorio en GitHub

Vue.js

Vuejs

Vue.js es un framework de Javascript. Sí, otro más. Este destaca (según ellos mismos, claro) en ser progresivo, versátil, tener un gran rendimiento y una nula curva de aprendizaje. Está todavía en fase de financiación vía Patreon y en GitHub ya tiene más de 2.300 commits y recibe unas 3.500 nuevas estrellas cada mes.

Repositorio en GitHub | Sitio web

Luxon

Luxon

Trabajar con fechas y horas, uno de los grandes quebraderos de cabeza del desarrollador, prácticamente sea cual sea el lenguaje que emplee cotidianamente. Luxon es una librería que intenta solucionar esto para los programadores Javascript. Casi 4.000 estrellas en un sólo mes hablan a las claras de que el resultado es satisfactorio.

Repositorio en GitHub | Sitio web

js2flowchart

Una librería Javascript que da lo que promete: convierte código Javascript en diagramas de flujo. Ni más ni menos. Mejor hacer una cosa bien que muchas regular. Más de 3.600 estrellas en las pocas semanas que el repositorio lleva en GitHub.

Repositorio en GitHub

HEML

Heml

Otro proyecto reciente y que soluciona un problema concreto: HEML es un lenguaje de marcado para crear emails responsive. Por el éxito, más de 3.300 estrellas en apenas un mes, lo consigue.

Repositorio en GitHub | Sitio web

riot

Repositorio de un novedoso motor de búsqueda para Go, el lenguaje de Google. Distribuido, simple y eficiente son su principales características (siempre según sus desarrolladores, claro). Otro proyecto que lleva más de 3.000 estrellas en el último mes.

Repositorio en GitHub

Puppeteer

Puppetter

Puppeteer es un curioso proyecto de Google Chrome que permite acceso a la API de Chrome en un entorno headless y realizar multitud de tareas desde las DevTools de Chrome, desde sacar una simple captura de pantalla o realizar una búsqueda a automatizar formularios o testeos. El repositorio lleva ya unos meses arriba pero aún así sigue teniendo unas 2.500 estrellas cada mes y más de 1.000 forks.

Repositorio en GitHub | Sitio web

Graphcool

Graphcool

GraphQL está empezando a sonar muy mucho (aquí nosotros ya te lo adelantamos). Graphcool no es ni más ni menos que un framework open source para desarrollar backends de GraphQL sin necesidad de servidor. Repositorio bastante reciente que ya acumula más de 3.500 estrellas y mucho buzz en la comunidad.

Repositorio en GitHub | Sitio web

Tailwind CSS

Windmill

Repositorio de un reciente framework CSS que sigue el paradigma utility-first y que permite, supuestamente, un desarrollo UI mucho más rápido. Más de 2.700 estrellas en menos de un mes de vida. Entrada fulgurante para este proyecto.

Repositorio en GitHub | Sitio web

Y lo dejamos aquí, que ya hay bastante material en el que inspirarse o para colaborar. Ahora, a remangarse y ponerse a programar.

También te recomendamos

Classroom for Github, ayudando a los profesores a gestionar los ejercicios de sus clases

Evaluación del rendimiento de los desarrolladores: ¿Por qué, qué y cómo?

Un sueño de cristal y oro para decorar tu piso esta Navidad

-
La noticia 14 de los proyectos open source más activos en GitHub fue publicada originalmente en Genbeta Dev por Fernando Siles .

Página Anterior Página Siguiente