Artículos para desarrolladores
Explicaciones de formatos de codificación, del trabajo con JSON y de otros temas útiles para desarrolladores, con enlaces a las herramientas online de tulzy correspondientes.
Codificación
Base64: para qué sirve la codificación y cómo funciona
Cómo Base64 convierte datos binarios en texto ASCII y cuándo esto realmente hace falta.
Base32: en qué se diferencia de Base64 y cuándo es más práctico
El alfabeto de Base32, que no distingue mayúsculas, y los casos donde resulta más práctico que Base64.
URL Encode/Decode: el percent-encoding en los enlaces
Cómo los caracteres especiales en direcciones y parámetros se convierten en secuencias %XX.
HTML Entities: cómo mostrar caracteres especiales de forma segura
Por qué hay que escapar los caracteres < > & y cómo esto evita que el marcado se rompa.
JWT: la estructura del token y qué significa "decodificar" un JWT
El header, el payload y la signature de un token JWT, y por qué decodificar no es lo mismo que verificar la firma.
Unicode Escape: qué significan las secuencias \uXXXX
De dónde salen las secuencias tipo \u0041 en JSON y cadenas JS, y qué significan.
ROT13 y el cifrado César: sustitución simple de caracteres
Por qué un desplazamiento de 13 letras hace que ROT13 sea su propio inverso, y por qué se sigue usando hoy.
Punycode: cómo funcionan los dominios internacionalizados en el DNS
Cómo un dominio con caracteres no latinos se convierte en una representación ASCII con el prefijo xn--.
Código Morse: cómo el texto se convierte en puntos y rayas
El principio de codificar letras con puntos y rayas, y dónde se usa el código Morse hoy en día.
Data URI: cuándo incrustar imágenes directamente en el código
Cómo un Data URI incrusta el contenido de un archivo directamente en HTML o CSS, y cuándo vale la pena.
Gzip + Base64: comprimir datos para transmitirlos como texto
Por qué los datos binarios comprimidos también se codifican en Base64 antes de meterlos en un campo de texto.
XML Entities: escapar caracteres en documentos XML
Las cinco entidades XML obligatorias sin las cuales el documento se rompe al analizarlo.
JSON
JSON Formatter: formatear, minificar y validar
Formatear para legibilidad, minificar para tamaño, validar para corrección: tres tareas distintas con JSON.
JSONPath: buscar datos en JSON sin analizarlo a mano
Cómo JSONPath permite extraer los valores necesarios de un JSON grande con una sola expresión, sin recorrerlo a mano.
JSON Diff: en qué se diferencia la comparación estructural de la textual
Por qué el orden de las claves no debería afectar a la comparación de dos documentos JSON.
JSON Schema: cómo describir y validar la estructura de un JSON
Cómo JSON Schema permite comprobar automáticamente si unos datos cumplen el contrato esperado.
JSON Flatten: convertir una estructura anidada en una lista plana
Cómo un JSON muy anidado se convierte en una lista plana de claves como user.address.city.
JSON Sort Keys: por qué ordenar las claves de un objeto
Por qué el orden de las claves en JSON no está especificado, pero ordenarlas sigue siendo útil en la práctica.
JSON Repair: por qué se rompe el JSON y cómo arreglarlo
Causas habituales de un JSON «roto» y qué puede y no puede arreglar una reparación automática.
Mock JSON Generator: para qué sirven los datos ficticios
Cómo los datos de prueba permiten empezar a construir una interfaz antes de que el backend esté listo.
JSON ↔ YAML/CSV/XML/TOML: cuándo y por qué convertir
Qué datos se pierden al convertir JSON a CSV y por qué YAML y TOML son populares para archivos de configuración.
Texto
Case Converter: por qué existen distintos estilos de nomenclatura
Por qué un mismo proyecto escribe variables en camelCase pero archivos en kebab-case, y de dónde vienen estas reglas.
Text Diff: cómo los algoritmos encuentran la diferencia entre dos textos
Cómo un algoritmo de diff encuentra el conjunto mínimo de cambios entre dos versiones de un texto.
Expresiones regulares: sintaxis básica y patrones habituales
Cómo leer una expresión regular y en qué se diferencia la coincidencia voraz de la perezosa.
Ordenar y eliminar líneas duplicadas: para qué sirve
Por qué ordenar numéricamente poniendo «10» antes de «9» es un error, y cómo evitarlo.
String Escape: por qué el mismo texto necesita escaparse de forma distinta
Por qué la misma comilla se escapa de forma distinta en una cadena JS, en JSON y en un comando de shell.
CRLF frente a LF: por qué los caracteres de fin de línea aún importan
Por qué un archivo escrito en Windows puede aparecer como «completamente modificado» en git sobre Linux.
Contar caracteres y palabras: por qué no siempre es trivial
Por qué un emoji o una letra con tilde pueden contar como varios caracteres a la vez.
Lorem Ipsum: de dónde viene el texto de relleno y para qué sirve
Por qué los diseñadores usan deliberadamente texto «sin sentido» en lugar de contenido real en las maquetas.
Slugify: cómo convertir cualquier texto en una URL
Cómo un título como «¡Hola, Mundo!» se convierte en una cadena compatible con URL como hola-mundo.
Markdown: por qué la sintaxis de texto plano venció a los editores de texto enriquecido
Por qué los desarrolladores prefieren escribir documentación en Markdown en vez de un editor de texto enriquecido.
Espacios y caracteres invisibles: la causa oculta de errores extraños
Por qué dos cadenas que parecen idénticas pueden no coincidir por culpa de un carácter invisible.
Text Reverse: por qué «invertir un texto» es más difícil de lo que parece
Por qué invertir una cadena de forma ingenua puede convertir un emoji en bytes inutilizables.
Análisis de frecuencia de texto: para qué sirve contar repeticiones de palabras
Cómo la frecuencia de las letras en un texto cifrado ayuda a romper los cifrados de sustitución más simples.
Hashes/Cripto
Hash Generator: en qué se diferencian MD5, SHA-1 y SHA-256
Por qué MD5 todavía se usa para verificar la integridad de archivos, pero no para contraseñas.
Checksum Verifier: cómo comprobar que un archivo no está dañado
Por qué una suma de comprobación coincidente confirma la integridad de un archivo, pero no quién lo creó.
HMAC: en qué se diferencia un hash con clave de un hash normal
Por qué un SHA-256 normal no protege contra la manipulación de un mensaje, pero HMAC sí.
Bcrypt: por qué las contraseñas se hashean lento y no rápido
Por qué un SHA-256 rápido es una mala elección para contraseñas, y un bcrypt lento es la correcta.
UUID: cómo se generan identificadores que casi nunca se repiten
Por qué se puede generar un UUID v4 de forma independiente en millones de máquinas sin riesgo de colisión.
Generador de contraseñas: qué es lo que realmente la hace fuerte
Por qué una contraseña larga hecha de palabras del diccionario es más fuerte que una corta con símbolos y números.
AES: cómo funciona el cifrado simétrico
Por qué la misma clave cifra y descifra los datos en AES, y en qué se diferencia del cifrado asimétrico.
Argon2: por qué este algoritmo ganó el concurso de hasheo de contraseñas
Cómo Argon2 defiende mejor contra ataques con GPU que los algoritmos de hasheo de contraseñas más antiguos.
Scrypt: por qué el algoritmo necesita tanta memoria
Por qué scrypt exige deliberadamente mucha memoria para dificultar el ataque en dispositivos ASIC.
TOTP: cómo funcionan los códigos de un solo uso en las apps de autenticación
Por qué el código de Google Authenticator funciona sin internet y se sincroniza con el servidor solo por la hora.
PBKDF2: el estándar de estiramiento de claves más antiguo
Por qué el número de iteraciones recomendado para PBKDF2 crece cada año.
X.509: qué hay dentro de un certificado SSL
Qué comprueba exactamente el navegador en el certificado de un sitio antes de mostrar el candado verde.
PGP: cómo funciona el cifrado con clave pública y privada
Por qué se puede compartir libremente una clave pública PGP, pero nunca la privada.
Tiempo/Números
Tiempo Unix: por qué las computadoras cuentan el tiempo desde 1970
Por qué el 1 de enero de 1970 se convirtió en el punto de referencia del tiempo para la mayoría de los sistemas informáticos.
Expresiones cron: cómo descifrar un horario de tareas
Cómo descifrar una expresión como */15 * * * * y saber exactamente cuándo se ejecutará la tarea.
Sistemas numéricos: para qué sirven el binario, el octal y el hexadecimal
Por qué el color #FF5733 en CSS se escribe con dígitos hexadecimales en lugar de decimales.
Operaciones bit a bit: cómo funcionan AND, OR y XOR a nivel de bits
En qué se diferencia el AND bit a bit del lógico, y para qué sirve operar sobre bits individuales de un número.
Diferencia entre fechas: por qué contar días es más complicado de lo que parece
Por qué restar fechas de forma ingenua puede dar un resultado incorrecto por culpa de los años bisiestos.
Cálculo de edad: por qué no es una simple resta de años
Por qué restar simplemente los años de nacimiento puede dar una edad un año mayor que la real.
Zonas horarias: por qué UTC no es lo mismo que GMT
Por qué UTC nunca cambia dos veces al año, mientras que la hora de Londres (GMT/BST) sí lo hace.
Calculadora de duración: cómo sumar correctamente horas, minutos y segundos
Por qué al sumar minutos y segundos hay que "llevar" el resto a la siguiente posición, igual que en la suma decimal.
ISO 8601 Duration: cómo escribir una duración en formato estándar
Por qué PT1H30M significa «1 hora 30 minutos» y no «1 minuto 30 horas».
Número de semana: por qué en distintos países las semanas se cuentan diferente
Por qué el 1 de enero a veces pertenece a la semana 52 o 53 del año anterior según el estándar ISO 8601.
Números romanos: cómo funciona un sistema sin cero ni posiciones
Por qué IV significa 4 y no 6, y cómo funciona la regla de resta en los números romanos.
IEEE 754: por qué 0.1 + 0.2 no es igual a 0.3 en el código
Por qué en casi todos los lenguajes de programación 0.1 + 0.2 muestra 0.30000000000000004.
Número en letras: para qué convertir cifras en palabras
Por qué en los documentos bancarios la cantidad se escribe a la vez en cifras y en letras.
Red/HTTP
Análisis de URL: de qué partes se compone una dirección web
Por qué una URL tiene una parte después del símbolo # que el servidor ni siquiera llega a recibir.
Query string frente a JSON: por qué los parámetros GET son tan limitados
Por qué pasar un array o un objeto anidado por la query string de una URL no es tan sencillo como con JSON.
User-Agent: por qué esta cadena es un desastre
Por qué Chrome, Safari y Edge incluyen a la vez las palabras "Mozilla" y "Safari" en su User-Agent.
Basic Authentication: cómo funciona la forma más simple de proteger un recurso HTTP
Por qué Basic Auth exige obligatoriamente HTTPS, ya que Base64 es codificación, no cifrado.
Cabeceras HTTP: qué se esconde en cada petición y respuesta
Por qué la cabecera Content-Type determina cómo interpreta el navegador el cuerpo de la respuesta del servidor.
Cookies: cómo un pequeño fragmento de texto mantiene el estado de una sesión
Por qué el atributo HttpOnly protege una cookie de ser robada mediante JavaScript malicioso.
CORS: por qué el navegador bloquea peticiones "normales" a otro dominio
Por qué el error de CORS ocurre en el navegador, no en el servidor, y quién bloquea realmente la petición.
Cabeceras de email: cómo rastrear el recorrido de un mensaje desde el remitente hasta ti
Por qué hay que leer las cabeceras Received de abajo hacia arriba para rastrear el recorrido de un mensaje.
SEO
Meta tags: cuáles realmente afectan a la búsqueda y las redes sociales
Por qué un buscador a veces ignora tu meta description y genera su propio snippet a partir del texto de la página.
robots.txt: cómo deciden los bots de búsqueda qué pueden rastrear
Por qué una regla Disallow en robots.txt no oculta una página de los resultados de búsqueda si algo más enlaza a ella.
Sitemap.xml: por qué los buscadores necesitan un mapa del sitio
Por qué figurar en sitemap.xml no garantiza que un buscador vaya a indexar una página.
Favicon: por qué un solo icono necesita tantos tamaños y formatos
Por qué un solo favicon.ico ya no basta para mostrarse correctamente en todos los dispositivos.
Generar sitemap.xml: cómo construir un mapa del sitio automáticamente
Por qué los buscadores en su mayoría ignoran el campo priority en sitemap.xml pese a formar parte de la especificación.
Desarrollo Web
HEX, RGB, HSL: por qué existen tantas formas de escribir un color
Por qué los diseñadores suelen preferir HSL antes que HEX al elegir un tono de color a mano.
Minificación de CSS: qué se elimina realmente del archivo y por qué
Por qué el CSS minificado funciona exactamente igual en el navegador, aunque se vuelva ilegible para una persona.
Minificación de JavaScript: la diferencia entre minificar y ofuscar
Por qué el código minificado se puede leer si uno quiere, mientras que el ofuscado no.
Minificación de HTML: por qué importan los espacios en el marcado
Por qué eliminar espacios dentro de <pre> o un textarea puede romper el aspecto de la página, a diferencia de casi cualquier otro lugar.
Degradados CSS: en qué se diferencia linear de radial y conic
Por qué conic-gradient sirve para gráficos circulares y radial-gradient para un efecto de foco de luz.
El algoritmo de Luhn: cómo se comprueba la corrección de un número de tarjeta
Por qué un número de tarjeta que pasa la verificación de Luhn no significa que esa tarjeta exista realmente.
IBAN: cómo está estructurado un número de cuenta bancaria internacional
Por qué las dos primeras letras de un IBAN son el código de país, no parte del número de cuenta.
Códigos QR: cómo cabe un enlace en un cuadrado de píxeles
Por qué un código QR con un logo en el centro se sigue escaneando aunque parte del patrón esté tapada.
Códigos de barras: en qué se diferencia Code 128 de EAN-13
Por qué los productos en las tiendas casi siempre usan EAN-13 en lugar de Code 128.
Imágenes placeholder: por qué importan las imágenes ficticias durante el desarrollo
Por qué los desarrolladores colocan deliberadamente rectángulos grises en vez de fotos reales mientras se construye el maquetado.