Calculadora de Longitud de Cadenas

Pega una cadena y la herramienta informa su longitud en cuatro sentidos diferentes: .length estilo JavaScript (unidades de código UTF-16), puntos de código Unicode, grupos de grafemas (lo que los usuarios perciben como un carácter) y bytes UTF-8 (lo que tu columna de base de datos realmente almacena). Estos números no coinciden para cualquier cadena con emoji, banderas o marcas combinatorias, y esa discrepancia es la fuente de muchos errores.

Los cuatro sentidos de la longitud de la cadena

  1. 1

    Unidades de código UTF-16

    Lo que `str.length` devuelve en JavaScript. 1 para la mayoría de los caracteres, 2 para cualquier punto de código más allá de U+FFFF (emoji, escrituras antiguas).

  2. 2

    Puntos de código

    Uno por escalar Unicode. Los emoji son 1 cada uno; las secuencias ZWJ son múltiples.

  3. 3

    Grupos de grafemas

    Lo que un usuario llama "un carácter". `🇺🇸` son 2 puntos de código pero 1 grafema. `n̈` son 2 puntos de código pero 1 grafema.

  4. 4

    Bytes UTF-8

    Lo que almacena tu base de datos. ASCII = 1 byte cada uno; común europeo = 2; CJK = 3; la mayoría de los emoji = 4.

Ejemplos

Cadena JS .length Puntos de código Grafemas Bytes UTF-8
hello 5 5 5 5
café 4 4 4 5
😀 2 1 1 4
🇺🇸 4 2 1 8
👨‍👩‍👧 (familia) 8 5 1 18
n̈ (n + diéresis) 2 2 1 3

Por qué los números difieren

Las cadenas de JavaScript son UTF-16, por lo que un punto de código por encima de U+FFFF se almacena como un par de sustitutos: dos unidades de código UTF-16. "😀".length === 2. A los usuarios no les gusta esto porque piensan en 😀 como un solo carácter.

Los grafemas van más allá: una bandera de país son dos puntos de código de indicador regional que el usuario ve como una sola bandera. "🇺🇸".length === 4 en JavaScript, lo cual parece absurdo, pero ahí está. Para iterar sobre grafemas, usa Intl.Segmenter (moderno), la biblioteca grapheme-splitter, o maneja manualmente.

Bytes UTF-8: lo que almacena tu base de datos

Para una columna tipada VARCHAR(255):

  • En MySQL utf8 (real: utf8mb3), los 255 son bytes. café ocupa 5 bytes, así que caben 51 copias.
  • En MySQL utf8mb4 (UTF-8 real, incluye emoji), sigue siendo bytes pero la codificación admite secuencias de 4 bytes.
  • En Postgres VARCHAR(255), los 255 son caracteres (puntos de código), no bytes.
  • En SQL Server VARCHAR, varía según la colación; NVARCHAR cuenta unidades UCS-2 de 2 bytes.

Si dimensionas los campos de la base de datos por el límite de caracteres visibles para el usuario, usa bytes × 4 para seguridad en columnas UTF-8: cada grafema puede ocupar hasta 4 bytes por punto de código, con secuencias ZWJ añadiendo más.

Conteo de caracteres al estilo Twitter

Twitter cuenta un tweet por una regla personalizada: puntos de código, pero los emoji y los ideogramas CJK cuentan como 2. Un tweet 100% ASCII puede tener 280 caracteres; un tweet con 140 emoji alcanza un máximo de 140 “caracteres”.

Conteo de SMS: 160 caracteres en GSM de 7 bits. Cualquier carácter no GSM (á, é, ñ, emoji) cambia la codificación a UCS-2, y la longitud de tu mensaje se reduce a 70 caracteres.

Usos prácticos

  • Dimensionamiento de columnas de base de datos, verifica el conteo de bytes antes de escribir una migración.
  • Aplicación de cuotas de API, la mayoría de las API cuentan bytes, no caracteres.
  • Validación de formularios, muestra al usuario un conteo de caracteres preciso que coincida con su expectativa (grafemas).
  • Depuración de rendimiento, ¿por qué esta expresión regular itera lentamente? Porque la entrada es 3 veces más larga en unidades de código que en grafemas.

Preguntas frecuentes

Ese emoji es una secuencia ZWJ que combina múltiples puntos de código (por ejemplo, un emoji de familia son 7 puntos de código). Twitter lo cuenta como 2 caracteres según la regla de peso Unicode; tu editor muestra 1 grafema. Ambos son técnicamente correctos, solo miden cosas diferentes.

En bases de datos UTF-8, permite 4 bytes por carácter esperado para seguridad. Un campo de 100 caracteres (grafema) debería ser VARCHAR(400) bytes, o si tu base de datos cuenta en caracteres como Postgres, VARCHAR(100) con el manejo del conjunto de caracteres.

En JavaScript: depende de la forma de composición. NFC compuesto (U+00E1) tiene longitud 1; NFD descompuesto (U+0061 + U+0301) tiene longitud 2. Mismo carácter visible, diferentes secuencias de bytes.

Los emoji de familia y profesión son largas secuencias ZWJ. Las fuentes sin soporte completo renderizan cada punto de código como un glifo separado, así que 👨‍💻 se convierte en 👨+💻. Actualizar la fuente del sistema operativo lo soluciona.

Herramientas relacionadas

Herramienta disponible en otros idiomas