Ángel Ortega III

Un naufragio personal

A function to decode utf-8 in streaming mode

This is my C language function to decode utf-8 into wide characters, a byte at a time. It also detects encoding errors.

/**
 * mpdm_utf8_to_wc - Converts from utf8 to wchar (streaming).
 * @w: convert wide char
 * @s: temporal state
 * @c: char read from stream
 *
 * Converts a stream of utf8 characters to wide char ones. The input
 * stream is read one byte at a time from @c and composed into @w
 * until a Unicode codepoint is ready. The @s integer keeps an internal
 * state change and must be set to 0 before the stream is read. It
 * detects encoding errors; in this case, the special Unicode
 * char U+FFFD is returned.
 *
 * When 0 is returned, a new wide char is available into @w. If
 * the stream is interrupted in the middle of a multibyte character,
 * the @s state variable will not be 0.
 */
int mpdm_utf8_to_wc(wchar_t *w, int *s, char c)
{
    if (!*s && (c & 0x80) == 0) { /* 1 byte char */
        *w = c;
    }
    else
    if (!*s && (c & 0xe0) == 0xc0) { /* 2 byte char */
        *w = (c & 0x1f) << 6; *s = 1;
    }
    else
    if (!*s && (c & 0xf0) == 0xe0) { /* 3 byte char */
        *w = (c & 0x0f) << 12; *s = 2;
    }
    else
    if (!*s && (c & 0xf8) == 0xf0) { /* 4 byte char */
        *w = (c & 0x07) << 18; *s = 3;
    }
    else
    if (*s && (c & 0xc0) == 0x80) { /* continuation byte */
        switch (*s) {
        case 3: *w |= (c & 0x3f) << 12; break;
        case 2: *w |= (c & 0x3f) << 6;  break;
        case 1: *w |= (c & 0x3f);       break;
        }

        (*s)--;
    }
    else {
        *w = L'\xfffd';
        *s = 0;
    }

    return *s;
}

Sobre la creación de canales de Telegram

Hace unos días investigué para un amigo cómo crear y usar canales de Telegram y le envié este email contándole lo que he averiguado. Lo adjunto aquí para que no se pierda:

Hola. He investigado sobre los canales de Telegram y cómo automatizarlo. Como siempre todo es complicado y confuso. Te lo cuento aquí porque mañana seguro que se me ha olvidado.

Lo primero es crear un canal. Eso ya lo has hecho.

Lo segundo es crear un bot. Es una especie de usuario de Telegram que no es un usuario pero que puede postear en canales. Para crearlo hay que hablar con otro bot que se llama BotFather. Ahí hay que darle comandos tipo IRC para crear tu bot (sí, es así de confuso). Hay que mandarle el mensaje /newbot y él (como en un chat robótico) te pide el nombre del bot y el nombre del usuario del bot (no sé muy bien cuál es la diferencia ni por qué hacen falta dos nombres y por qué no puedes ponerle el mismo). Después de esto te da una cadena de texto mágica que es un identificador autenticado del bot para poder postear desde fuera.

Luego tienes que ir al canal y añadir al bot como administrador. Solo funciona si lo haces desde el móvil, desde el ordenador no lo he conseguido. Tienes que buscar el nombre del bot desde la lupa porque no te sale automáticamente tu lista de bots.

Una vez hecho esto un par de veces (a la primera no me ha funcionado), ya le puedes mandar comandos al bot por HTTP para postear en aquellos canales en los que está autorizado. Esto se hace con una query como la que sigue:

 https://api.telegram.org/botIDENTIFICADOR_DEL_BOT/sendMessage?
 chat_id=@CANAL&text=Hola%20caraculo

Esto se puede hacer directamente con el comando curl del Linux o desde algún programa, es una petición HTTP normal.

Eso publica en modo texto. Hay un modo especial HTML que es MUY limitado y solo acepta negrilla, cursiva, enlaces y poco más. Con eso hay que montárselo todo. En concreto, NO acepta <p> para separar líneas ni títulos <h1>, <h2>, etc ni nada de eso, así que hay que hacer una especie de conversión (no es que ignore los tags, es que casca y te rechaza el envío).

Leyendo por ahí he descubierto que el modo HTML sí acepta cortes de párrafo pero hay que meterlos a pelo, es decir, metiendo %0A (ascii del line feed). Para añadir imágenes hay otro truco, que es ponerlas como enlaces (NO como imágenes). Si dejas el texto del enlace vacío o con un espacio lo ignora. La gente dice que le pone un carácter Unicode especial que es el "separador que no ocupa espacio" pero a mí me lo rechaza.

Este comando funciona y genera una entrada más o menos bonita:

 curl 'https://api.telegram.org/botBLA_BLA_BLA/sendMessage?chat_id=@nutriguia
 &parse_mode=HTML&disable_web_page_preview=false&text=
 <b>Title</b>%0AThis is a <i>test</i>. <a href="https://triptico.com/img/mp.png">·</a>'

Así que se podría hacer un programita que instalado en un cron coja, por ejemplo, el feed ATOM o RSS de Nutriguía, magree un poco las entradas, las deje aceptables para el Telegram y las envíe con sendas peticiones HTTP como las que te he comentado arriba.

Quizá alguien ha hecho ya ese programa, no he investigado más allá.

Nada es lo que parece

Esto ocurrió. Un profesor dijo globo ocular. En el margen de un libro yo dibujé esto:

Se lo enseñé a un compañero y dije:

—¿Sabes qué es?

Y él me dijo:

—Pues claro. Una visión global.

The sprites of Freaks!

These are the sprites from the Freaks! 1993 game as animated GIFs for pixel-art lovers to enjoy.

Artwork by Ángel Ortega and Antonio Guerrero.

Tasso, Lamento e Trionfo

Tasso, Lamento e Trionfo es un relato sobre la pérdida, la injusticia y la belleza en el que se narra la lucha por la supervivencia de una institutriz caída en desgracia en los días anteriores al estreno del poema sinfónico que Franz Liszt compuso para conmemorar el centenario del nacimiento de Johann Wolfgang von Goethe.

Está incluido en la antología Tormenta e ímpetu, un libro de Tinta Púrpura Ediciones que toma el surgimiento del romanticismo como inspiración. Esta es la sinopsis:

"Amor y pasión. Sensaciones, sentimientos y emociones desatados. Tormenta e ímpetu. Sturm und Drang. Durante la segunda mitad del siglo XVIII, varios autores se revolvieron contra el racionalismo imperante. Su rechazo al estilo neoclásico del momento provocó el nacimiento de lo que llegaría a ser el Romanticismo. Frente a los fríos y rígidos moldes del neoclasicismo de origen francés, el Sturm und Drang alemán estableció el sentimiento y el yo, en lugar de la razón, como fuentes de inspiración. Esta antología recupera ese espíritu y la actualiza al siglo XXI. Y, ya que tanto Tinta Púrpura como el propio movimiento Sturm und Drang tienen una relación muy estrecha con la música, quisimos que esta antología también lo tenga. Cada uno de sus relatos es un particular homenaje de la palabra escrita a la música que tanto amamos; así como una interpretación personal, apasionada y desatada, de lo que el Romanticismo y, en particular, el Sturm und Drang, es para nosotros."

El libro se puede comprar en Amazon.

On selecting text in the Minimum Profit Text Editor

As this is a question I have to answer periodically here are my final words on it.

The Minimum Profit Text Editor has three selection modes: "movement", "block" and "vertical".

The "movement" one is the way of selecting text that is implemented everywhere and is somewhat of a standard: by pressing the shift key and using any of the movement actions (left, right, word left, word right, up, down, page up, page down, beginning of line, end of line, beginning of document or end of document) or by left clicking and dragging with the mouse. Additionally, you can right-click and drag to extend the selection. Once the block is marked any movement key deselects it. Typing something replaces the selection. Hitting del or backspace erases the selected text. Though this mode is what new users expect, it works weakly on non-GUI interfaces because of lacking or defective support in the underlying libraries and systems.

The "block" selection mode is an older style one (and the first one that MP had): by pressing a key (f9 by default) you mark the beginning or end of the marked text. The selection survives any movement (indeed, it's the only way block selection can be done, by moving to another place and marking the other end) and you can extend the block above or below whenever you want. Replacing and erasing works as expected. Additionally, most operations like search, replace, etc. only apply to the marked text if there is one (this is very useful). The selection only disappears when copying, erasing, replacing, mouse-clicking or unmarking (by pressing the f8 key). This is the way I copy and paste; I never use the standard way (I know you don't care).

The "vertical" selection mode also works by marking the beginning or the end of the block, but the selection forms a square shape (x, y to x', y') instead of a line-flow one. By default it's done by hitting ctrl-b. The selection can also be extended repeatedly. As in "block" mode, marked text is disabled after copying or by pressing f8. I never use this option and never did (it was implemented by a fellow programmer).

I agree that the "movement", "block" and "vertical" terms are a sloppy way to describe the operations they do.

Camino sobre cuchillas

 Camino sobre cuchillas
 y la tierra es polvorienta y cáustica
 los árboles secos delimitan
 esta senda de vacío y hambre
 y la muerte no llega
 El cielo es severo
 y es como una puerta cerrada
 sus goznes están sellados
 con un emplasto de lágrimas y cenizas
 y la muerte no llega
 Perdí mi alma en el bosque de espinas
 y ahora soy solo la muda de piel de mí mismo
 los carroñeros me ignoran
 y clamo a la espuma de las nubes
 y la muerte no llega
 Dejo atrás fantasmas perdidos
 la desidia y el abandono llenan sus cuencas
 como yo tapan sus heridas con palabras vanas
 pero la vida se perdió en lágrimas
 y la muerte no llega
 Este páramo es interminable y frío
 hay puentes rotos y ciénagas
 lo sobrevuela el arcángel distante
 que arrancó mi razón con sus zarpas
 y la muerte no llega
 Enterré el miedo en una cuneta
 y lancé los sueños a la acequia
 esa corriente enferma que rebosa
 en el mar eterno sin lluvia
 y la muerte no llega
 Hay laúdes y tambores pisoteados
 y la muerte no llega
 mis pies se deshicieron en el filo
 y la muerte no llega
 caminé sobre cuchillas
 y nada queda de mi mismo
 solo la desazón y la sed
 porque nunca llega
 Este páramo soy yo
 vencido y desolado
 yo rompí los puentes y envenené los pozos
 y quizá entregué mi razón
 al ángel abominable que oscurece la llanura
 y ya no recuerdo nada
 porque acaso me rendí hace tiempo
 y solo soy un paria
 arrastrado sobre cristales rotos
 porque solo tengo una esperanza
 un deseo, una fiebre,
 un dolor, un proyecto,
 que nunca llega.

(nov 2018)

Los números son chungos

Aunque he colaborado en desarrollar los procesos de cifrado y descifrado que hacen posible la comunicación con este monstruo tengo una idea muy socrática sobre el tema: es imposible saber nada sobre criptografía. Las matemáticas son demasiado complejas. Los números son demasiado chungos. Bueno: dejémoslo en que Bruce Schneier, los RSA y sobre todo Daniel J. Bernstein sí saben algo de criptografía, pero para el resto de los mortales es terreno vedado. Y peor que no saber es creer que sabes.


Hurley lo sabía bien.

Si eres programador puedes sucumbir a la tentación de crear tu propio algoritmo. Se dice que cualquier idiota puede inventar un algoritmo de cifrado que él mismo sea incapaz de reventar. No seas iluso. Simplemente no tienes los conocimientos necesarios. Los algoritmos «oficiales», incluso aquellos que ya han sido reventados entre risas, fueron diseñados por gente mucho más lista que tú que bien podrían ser de otro planeta.

Relacionado con lo anterior, tampoco caigas en la trampa de desarrollar tu propia implementación de los algoritmos conocidos. Así, sobre el papel, parecen fáciles; total, solo es un meneo de bits, sujétame la cerveza mientras lo hago. Además seguro que se te ocurre alguna optimización («¿Pa qué hace esto? ¡Si no hace falta!») e incluso alguna mejora («¡Ya que tengo aquí este otro número, voy a hacer un XOR con el resultado y todo será mucho más seguro!»). No estás capacitado. No entiendes lo que estás haciendo. Los números son demasiado chungos. La cagarás y luego vendrán los gritos y el rechinar de dientes.

Si tienes que almacenar passwords en una base de datos no creas que eres tan listo y te inventes algún truquillo, total, hago un hash y ya está. No, no está. Algún día habrá una fuga y toda la tropa se partirá la polla cuando vea tus ficheros y cómo guardas los datos. Es un problema resuelto. La librería de desarrollo que usas seguro que tiene una primitiva para eso y, si no la tiene, tírala a la basura y usa otra que sí la tenga.

Si solo eres usuario de la criptografía no lo tienes mucho mejor. No podrás inventar nada pero cagarla es muy fácil sobre todo con herramientas tan complejas como el PGP. Tarde o temprano reenviarás en claro el contenido de un mensaje cifrado a quien no debes y quedarás como un imbécil (o en los tribunales). Y parte del problema será que, como estás usando herramientas criptográficas, te sientes seguro y bajas la guardia.

Entonces, ¿todo está perdido? No, todo no. Si tienes que desarrollar usa los protocolos y los algoritmos que los listos recomiendan. Y no los implementes tú, cabezabolo: usa una librería que tenga lo último sin lastres de compatibilidad hacia atrás y que sea difícil usar mal. Es decir, usa libsodium.

Claro que no eres el único que se cree más listo que nadie: casi a diario se publican noticias de empresas que sacan al mercado productos milagrosos con algoritmos recién inventados y que van a cambiar la forma de percibir el mundo de la seguridad y la privacidad. Esta gente no lo hace por ingenuidad como tú: son estafadores y delincuentes. Bruce Schneier colecciona estas cosas en su web y se parte la caja llamándolas aceite de serpiente (que, como deberías saber, es un método más de «medicina» tradicional basado en cero evidencias científicas). Por cierto, su siguiente libro se va a llamar Click Here To Kill Everybody que es un título que yo había inventado primero.