🔮 Anticipándome al futuro, responderé la pregunta: “¿Por qué te pusiste eyvot?”. Contándote una historia de hace 7 años.

Verás, durante mis tiempos universitarios, ya consideraba la idea de establecer presencia en internet, aunque no de forma aspiracional a ser “un influencer”. Más bien pensaba en la importancia de tener un rincón personal en Internet, un espacio dónde compartir mis intereses y experiencias, en un mundo cada vez más conectado (te recomiendo leer mi primer post para conocer más sobre mis motivaciones).

💭 Entonces…

Solía preguntarme ¿Cómo elegiré mi seudónimo en Internet? ¿Debería inventar una palabra única o jugar con las letras de mi propio nombre? Me gustaría crear algo original, pero también me gustaría que incluyera letras de mi nombre, al menos como simbolismo a mi yo de toda la vida. ¿Cuántas letras debería tener? Los nombres cortos son más fáciles de recordar, pero también (por matemática simple) son más propensos a estar en uso, lo que hace que sea más difícil encontrar uno.

Si bien suelo reflexionar sobre mi futuro para darle dirección a mi vida, tampoco me preocupo por resolver cosas que no están a punto de suceder. “Todo a su tiempo”, incluso las preocupaciones.

Nota: Cuando hago planes, suelo tener una visión de alto nivel sobre mi camino. No me preocupo por detalles a menos que sea necesario. Solo necesito la confianza de que mi plan es viable para saber que vale la pena trabajar en él. En el camino, suelo abordar los desafíos a medida que surgen. Esta es solo una forma generalizada de mi forma de actuar; sin embargo, también considero que algunas situaciones requieren un análisis detallado desde el inicio.


👨‍💻 “Soy Programador” Y…
…Esto Es Un Problema De Búsqueda

Mis primeros intentos consistían en inventarme nicknames “sobre la marcha” en una libreta, para luego verificar su disponibilidad en redes sociales usando herramientas online. Sin embargo, pronto me di cuenta de que las combinaciones que se me ocurrían solían estar ocupadas en al menos una red social importante. Hacer esto de forma improvisada, me llevaba a repetir patrones de pensamiento y producir nombres similares o repetidos. Esta búsqueda la hacía de forma esporádica (cuando encontraba oportunidad o los días que sentía inspiración para producir nuevas ideas).

Tiempo después, en mi mente… 🤔 Supongo que el hecho de que estos nombres estén ocupados, indica que comparto algo en común con la sociedad en general en cuanto a la generación de ideas de nombres se refiere. Esto podría estar relacionado con el lenguaje y las palabras que conocemos. De alguna manera, estos elementos nos precondicionan. Tal vez las personas que crecieron hablando otro idioma generen ideas diferentes… - mi mente detecta que he comenzado a divagar.

- ¿Sabes? Fabián, te estás desviando del tema. Entender los mecanismos detrás del por qué a las personas se nos ocurren nombres similares, no es algo que necesitemos abordar en este momento.

- Tienes/tengo razón, no es el momento (quizá nunca lo sea). Sin embargo, esto nos ayuda a medir la dificultad de encontrar un nickname corto, fácil de recordar, pronunciable y que incluya letras de nuestro nombre. Y esto podría influir en la toma de una decisión.

- Concuerdo, debemos encontrar los nicknames que cumplan con estos requisitos y que, estén disponibles (si es que existen).

- Además, considerando que llego a tener audiencia en el futuro, lo más seguro es que sean personas hispanohablantes. Pero vivimos en un mundo globalizado, por lo que mi nickname debe sonar bien tanto en español como en inglés. Las letras que quiero usar (a, b, c, d, e, f, g, l, n, o, r, s, t, v, y) generan 759,375 combinaciones distintas de 5 letras (15^5). Por supuesto, no todas pueden considerarse nombre (aaaaa, aaaab, aaaac, etc).

- En efecto, es un problema de búsqueda. Debemos encontrar dentro de esas combinaciones lo que consideremos “un nombre de 5 letras fácilmente pronunciable tanto en español como en inglés”.


🧩 Mi Primer Proyecto Personal

Tomé este desafío y lo convertí en mi primer proyecto personal. La idea era llevarlo a cabo después de graduarme de la universidad, antes de sumergirme en el mundo laboral. Así nació la idea de crear un “generador de nicknames fácilmente pronunciables tanto en español como en inglés”, además de una solución para automatizar la verificación de su disponibilidad. De no ser así “suerte evaluando una larga lista de opciones de forma manual con un verificador online”, ese no era un escenario práctico.

El proyecto se dividió en tres partes fundamentales:

  • El generador de nicknames fácilmente pronunciables tanto en español como en inglés, con la capacidad de almacenar los resultados en una base de datos.
  • Un backend destinado a automatizar la verificación de disponibilidad de los nicknames en diversas redes sociales, almacenar los resultados y exponerlos a través de un API REST.
  • Un frontend que permitiría consumir el API REST y aplicar filtros y ordenamiento. Esto, por ejemplo, facilitaría la visualización de “los 50 nicknames con mayor disponibilidad”.

Luego de completar mis deberes universitarios (según lo planeado), me puse manos a la obra, incluso dejando pasar una atractiva oportunidad laboral que se presentó en ese momento. Mi razonamiento era simple: mientras más tiempo pasara, más probable sería que esos hipotéticos “golden nicknames” desaparecieran, ya que alguien más podría descubrirlos.


🛒 Mi Primer Compra Online

Parte de la compensación económica que obtuve de mis residencias profesionales, la destiné a realizar mi primer compra online:

Primer compra por internet

🪶 La primera compra online, ese paso que disipa el miedo, que te hace desmitificar los cuentos de terror sobre “por qué no debes comprar en Internet” que te cuentan tus conocidos que nunca han comprado en Internet.

Si me conoces personalmente, sabrás que ese es mi tipo de humor en ocasiones (aunque depende de nuestro nivel de confianza y de cómo nos llevemos). ¿Qué humor? Dentro de mi mente suena gracioso evidenciar la ironía que representa una persona que no compra por Internet, aconsejándote sobre lo malo de comprar por Internet.

Aunque en la práctica no siempre me sale bien, no sé de forma certera cómo hacer que parezca sarcasmo cuando intento evidenciar una ironía. Tal vez se debe a que soy una persona que le cuesta entender el sarcasmo, a menos que en el pasado se me haya explicado con una situación similar, ahí podría aprender a detectarlo en situaciones futuras a través de la memoria. Por ejemplo: cuando hay algo que a todas luces es evidente, pero aún así decides preguntar para no asumir nada y te responden con un “Nooooo, ¿cómo crees?” usando un tono exagerado.

Raspberry Pi 3 Model B

Adquirí esta Raspberry Pi para convertirla en un pequeño servidor local de experimentos. Además me serviría para ejecutar mi función para verificar la disponibilidad de los nicknames de forma periódica mediante un cron job. Le instalé Ubuntu Server como sistema operativo, y dado que comencé el proyecto a finales de 2016, estoy convencido de que usé la versión 16.04, la cual debió ser la última versión LTS en ese momento. Básicamente se convirtió en mi infraestructura como servicio (IaaS) local.


⚙️ ¿Cómo Funcionaba Mi Proyecto?

Imagen recuperada de mis archivos.

Stack Tecnológico

En términos simples, el verificador estaba compuesto por una serie de peticiones HTTP automatizadas. Sin embargo, antes de automatizar este proceso, lo abordé de forma manual en todas las redes sociales objetivo. Con ayuda de un navegador web, visitaba el perfil de un usuario existente y otro inexistente. El propósito era identificar los diferentes códigos de estado en las respuestas. Obtuve un 404 si el usuario no existía, un 302 si el perfil no era público (redireccionaba a una página de cuenta privada), y un 200 si el usuario estaba registrado.

Así que establecí un criterio simple: si el código de estado era 404, el nombre de usuario estaba disponible.

Juez - Status Code 404

El “pensar antes de actuar” del mundo del Software. Este enfoque manual sirvió para obtener datos objetivos y tomar decisiones informadas sobre cómo abordar el problema. Si no hubiera realizado estas pruebas, podría haber llegado a una conclusión incorrecta, asumiendo que cualquier código de estado diferente de 200 indicaría disponibilidad.

Además, configuré mi backend para que funcionara como un servicio systemd. Aunque confieso, esto fue por “paranoia de programador”. Imagina que se fuera la luz mientras estaba fuera de casa; ¿Quién reiniciaría mi backend para continuar la verificación de nicknames? Con esta configuración, cuando se restaurara la energía, mi Raspberry Pi se reiniciaría automáticamente y mi Ubuntu Server se encargaría de iniciar mi servicio de verificación.

En cuanto al generador de nicknames…

Este tenía un toque de “magia” que reflejaba mi juicio personal sobre lo que constituía un buen nickname (después de todo, estos eran para mí). Mi enfoque era descubrir cómo podría determinar si una combinación de caracteres era aceptable o no. ¿Cuál sería esa abstracción encargada de decir “tú si” o “tú no”?

Comencé creando una lista de nombres reales e inventados, pero que me agradaban en términos de sonido al pronunciarlos en español e inglés. Algunos ejemplos eran dante, balta, leito, entos, logos, retoz.

Luego, analicé las vocales y consonantes que formaban estos nombres. Representé las vocales con la letra “v” y las consonantes con la letra “c”. Por ejemplo, dante se convirtió en cvccv, balta en cvccv, leito en cvvcv, entos en vccvc, logos en cvcvc, etc.

Reduje esto a una lista de estructuras válidas, que no eran muchas, ya que varios nombres compartían la misma estructura. Por ejemplo, tanto dante como balta compartían la estructura cvccv.

Revisando mi antiguo código… escribí el generador en Java (que era mi lenguaje principal en la universidad, por lo que me sentía cómodo utilizándolo). Al parecer tenía una clase abstracta llamada Nickname que usaba para extender las clases de variaciones de nicknames de 3 caracteres, 4 caracteres, 5 caracteres y dejé inconclusa una parte para 6 caracteres. Esta clase abstracta permitía que cada una de las clases que la heredaban implementara sus propias estructuras válidas predeterminadas. También sobrecargaba este método para permitir una configuración personalizada si lo deseaba. Al final, me quedé con las siguientes estructuras predeterminadas para nicknames de 5 caracteres:

...
@Override public void setValidStructures() {
    validStructures.add("CVCCV");
    validStructures.add("CVCCC");
    validStructures.add("CVCVC");
    validStructures.add("CCVCC");
    validStructures.add("CCVCV");
    validStructures.add("CVVCV");
    validStructures.add("VCCCV");
    validStructures.add("VCCVC");
    validStructures.add("VCVCC");
    validStructures.add("VCVCV");
    validStructures.add("VCVVC");
    validStructures.add("VVCVC");
}
...

Obtuve 12 estructuras de cientos de nombres que analicé manualmente. Algunos de mis amigos dirían “tienes mucha paciencia”. Pero esto solo es el comienzo…

Después de obtener esta lista de estructuras válidas, las sometí a pruebas, y no siempre quedaba satisfecho con el resultado final. Por ejemplo, la estructura cvccv, que generaba nombres como dante o balta, también podía generar xitzo y wulln. ¿Ves el problema? Estos no podía considerarlos “nicknames fácilmente pronunciables en español e inglés”.

Así que, determiné que mis nicknames estarían compuestos por combinaciones de vocales, consonantes, dobles vocales, dobles consonantes y triples consonantes. Esto como una abstracción intermedia que me facilitara emitir un juicio sobre las combinaciones y después poder crear reglas (antes de eso, también consideré usar sílabas, pero lo descarté).

Dado que una de las características clave que buscaba era la pronunciación, no permitiría casos de doble vocal (como “ii”), ya que esto solo prolonga la pronunciación sin cambiarla. Por ejemplo, una palabra de 5 caracteres como “danii” podría sonar igual que una de 4 caracteres como “dani”. Sin embargo, en el caso de las consonantes, había combinaciones que podían modificar la pronunciación si la letra se repetía, como la “ll” en “lluvia” o consonantes que, aunque no se repitieran, creaban una nueva pronunciación, como la “dr” en “pedro”. Incluso con las combinaciones de triple consonante, como “lly”, se podía formar una pronunciación. Esos son solo algunos pocos ejemplos de lo que analicé. Para dar una mejor idea, aquí dejo las combinaciones de triple consonante que usé solo para las letras “x”, “y” y “z”:

...
TRIPLE_CONSONANTS_THAT_STARTS_WITH_X
    = "xth-xtr-xtt-xtw-xty",
TRIPLE_CONSONANTS_THAT_STARTS_WITH_Y
    = "ybb-ybh-ybl-ybr-ybs-yby-ybz-"
    + "ydd-ydg-ydh-ydk-ydm-ydr-yds-ydw-ydy-"
    + "ylb-ylc-yld-ylf-ylg-ylk-yll-ylm-yls-ylt-ylw-yly-ylz-"
    + "ymb-ymy-"
    + "yph-ypl-ypb-ypp-ypr-yps-ypt-ypx-ypy-"
    + "yrb-yrc-yrd-yrf-yrg-yrj-yrk-yrl-yrm-"
    + "yrn-yrp-yrq-yrr-yrs-yrt-yrv-yry-yrz-"
    + "ysb-ysc-ysg-ysh-ysk-ysl-ysm-ysn-ysp-ysq-yss-yst-ysv-ysw-ysy-"
    + "yth-ytl-ytr-yts-ytt-ytw-yty-ytz-"
    + "yvl-yvn-yvr-yvs-yvv-yvy-yvz-"
    + "yzb-yzc-yzd-yzf-yzg-yzk-yzn-yzy-yzz",
TRIPLE_CONSONANTS_THAT_STARTS_WITH_Z
    = "zbb-zbh-zbr-zby-"
    + "zch-zcl-"
    + "zdd-zdh-zdr-zdw-zdy-"
    + "zff-zfl-zfr-"
    + "zgg-zgh-zgl-zgr-"
    + "zkh-zkk-zkl-zkr-zky-"
    + "znn-zny-"
    + "zyb-zyl-zym-zyp-zyr-zys-zyt-zyv-zyz-"
    + "zzy",
...

Si hasta este punto me estás “siguiendo el hilo”, es posible que te preguntes: ¿Por qué algunas de estas combinaciones son difíciles de pronunciar? ¿No deberían ser todas fáciles de pronunciar?

Bien, a partir de este punto, llamaré “tokens” a los posibles componentes de un nickname (por su significado de componente léxico en teoría de compiladores): vocales, consonantes, dobles vocales, dobles consonantes y triples consonantes. En su momento lo pensé de esa forma para poder establecer un orden y darle una “sintaxis” a los nicknames.

Tomando de ejemplo el token de triple consonante “ypr”. Vemos que, por sí solo, es difícil de pronunciar. Sin embargo, al utilizarlo en una combinación de 5 caracteres como “eypro”, se vuelve mucho más fácil. Y descomponiendo la palabra “eypro”, podemos decir que está formada por tres tokens: “e-ypr-o”. ¿Ves cómo puedes establecer un orden?

En la “sintaxis” de los nicknames, existen tres componentes clave: sucesión (qué caracteres deben iniciar los tokens que siguen a otros), posicionamiento (si un token puede ubicarse al principio, al centro o al final del nickname) y un conjunto de reglas para casos especiales.

Para establecer la sucesión de los tokens, diseñé una matriz que, por comodidad, primero plasmé en una hoja de cálculo.

Fragmento 01 Hoja de Cálculo Fragmento 02 Hoja de Cálculo

Curiosamente, según los metadatos de mi hoja de cálculo, la última vez que la guardé fue el 17 de octubre de 2016. Hace casi 7 años exactos. ¿Coincidencia? Por supuesto que sí.

Luego, incorporé esta matriz en el código del programa e hice un método para validarlas.

public static boolean canBeSequence(char character, char successor) {
    return rulesMatrix
        [getCharacterIndex(character)]
        [getCharacterIndex(successor)];
}

Para determinar el posicionamiento de los tokens (ya sea al inicio, en el centro o al final del nickname), también empleé una matriz.

...
this.positionsMatrixForX
    = new boolean[getCollectionSizeForX()][NUMBER_OF_POSITIONS];
positionsMatrixForX[XTH] = new boolean[] {false,true,false};
positionsMatrixForX[XTR] = new boolean[] {true,true,false};
positionsMatrixForX[XTT] = new boolean[] {false,true,false};
positionsMatrixForX[XTW] = new boolean[] {false,true,true};
positionsMatrixForX[XTY] = new boolean[] {false,true,true};
...

Las reglas para los casos especiales, no recuerdo con exactitud en qué consistían. Pero parece había algo de especial con algunas letras.

 SPECIAL RULES FOR LENGTH 3

 consonante + w          -> (vocales, consonantes) de w
 consonante + y          -> (vocales, consonantes) de y
 consonante + q          -> (vocales, consonantes) de q solo u
 q          + u          -> vocales de u
 w          + consonante -> (vocales, consonantes) de consonante
 y          + consonante -> (vocales, consonantes) de consonante

📝 Resultados

El generador de nicknames terminó siendo una herramienta de línea de comandos que utilicé para generar la base de datos con los nicknames. Lo ejecuté de la siguiente forma:

$ java -jar jnick.jar \
| --alphabet 'a,b,c,d,e,f,g,l,n,o,r,s,t,v,y' \
| --length '5' \
| --filter 'cvccv' \
| --filter 'cvcvc' \
| --filter 'vccvc' \
| --custom-sort 'f,l,t,e,d,r' \
| --sort 'asc' \
| --db-server 'mysql' \
| --db-name $MYSQL_DATABASE \
| --db-user $MYSQL_USER \
| --db-password $MYSQL_PASSWORD \
| --db-port $MYSQL_PORT \
| --db-table 'jnick_nicknamebasemodel'

🥁 Lo llamaré… después de 7 años… “Comando del Génesis”.

¿Recuerdas que mencioné que había sobrecargado el método para establecer las estructuras válidas? Esto me permitió personalizar la configuración. En este caso, usé solo las letras que me interesaban, generé nicknames de 5 caracteres, con estructuras cvccv, cvcvc y vccvc, y apliqué un orden específico antes de seguir con el orden del alfabeto.

Esta configuración resultó en la generación de alrededor de 40,000 nicknames. Al momento de escribir esta publicación, no tenía acceso a mi Raspberry Pi para verificar el número exacto, pero al parecer se descartaron alrededor de 720,000 combinaciones en el proceso. Además, aquí hay un detalle adicional, la función de verificación de disponibilidad de nicknames se ejecutaba cada minuto:

* * * * * socialminer /home/socialminer/.virtualenvs/socialminer/bin/python /home/socialminer/www/api.socialminer.lan/manage.py crawlnextnickname

Esta decisión la tomé principalmente por “paranoia de programador” (nuevamente). Me preocupaba que, si hacía peticiones con demasiada frecuencia, corriera el riesgo de ser incluido en lista negra dentro de alguna red social. Recuerdo que pensé “tardará casi un mes”, y si vemos el número de minutos que tienen un mes 30*24*60min = 43,200 mins, no creo mi memoria falle al recordar que se generaron alrededor de 40,000 nicknames.


🥂 El Momento De La Verdad…

A pesar de que había probado que todo funcionara y que en diferentes días verificase que todo continuara operativo, al finalizar el mes, experimentaba nerviosismo: ¿Y si algo falló y no me di cuenta? ¿Y si mi actividad resultó sospechosa y terminé siendo incluido en una lista negra? ¿Qué tal que encuentro la mitad de mis nicknames con falsos positivos? ¿Y si al intentar registrarme en redes sociales descubro que he pasado por alto algún detalle importante?

Simultáneamente, intentaba mantenerme optimista. Me recordaba a mí mismo que, incluso en el caso más pesimista, podría haber algunos nicknames rescatables de los 40,000 generados o, en última instancia, podría corregir cualquier problema y repetir el proceso.

Así que, tomé mi frontend, y empecé a interactuar… comencé por ordenar los nicknames por disponibilidad. Y ahí estaban, esos “golden nicknames ya no eran solo una hipótesis. Empecé a hacer scroll, y rápidamente llegué al punto donde no todos estaban disponibles. Sin embargo, todavía había muchas opciones donde de 23 redes sociales, había disponibilidad en 22. Mi elección era obvia: 23 de 23. Y el nickname que más me gustó fue “eyvot”.

Dato curioso: tras elegir a eyvot, también me surgió otra pregunta. ¿Cuál será el nickname menos disponible? Así que ordené los nicknames de menos disponibles a más disponibles, y el primer resultado fue “logan”. En ese momento, estaba a punto de estrenarse la película “Logan” de los X-Men.

Después, comencé a crear una cuenta en cada red social. Y a medida que me registraba, actualizaba la página de perfil de mi nickname. Me impresionaba cómo se volvía menos disponible con cada registro. Era un momento mágico: tenía todo el conocimiento teórico, pero verlo en acción y observar cómo mi registro en una red social afectaba un dato booleano en una base de datos local de mi pequeño backend era satisfactorio y sorprendente. Justo esto es a lo que me refiero con “sensación creadora” en mi primer post.

Hasta aquí llega la historia de cómo elegí mi seudónimo “eyvot”. Espero haber respondido adecuadamente la pregunta.

Si estás interesado en echar un vistazo a mi antiguo código del generador de nicknames, aquí lo tienes. No cuenta con instrucciones en el readme, pero creo que con la descripción que he proporcionado en este post, será entendible. El código tiene algunas ineficiencias; en su momento, generé las combinaciones mediante un árbol n-ario, simplemente porque quería practicarlos, pero un enfoque iterativo habría sido más eficiente en memoria.


🙋‍♂️ Hasta La Próxima

Tengo varias ideas en mente para mi próximos posts, es probable que el siguiente esté relacionado con las herramientas que utilizo para gestionar mi vida. De hecho, estoy considerando hacer un video sobre cómo entender Notion para uno de mis canales de YouTube.

Espero que hayas disfrutado de esta la lectura. ¡Nos vemos en mi próximo post!

Gracias 🙏