search

Found

info Visão geral

Conta bytes UTF-8, pontos de código, unidades UTF-16 e linhas em paralelo, com detalhamento em 4 categorias (ASCII, Latin, BMP CJK, emoji).

📘 Como usar

  1. Cole ou digite o texto na caixa à esquerda
  2. Consulte bytes UTF-8, pontos de código, unidades UTF-16 e linhas no painel à direita
  3. Veja o detalhamento ASCII / Latin / CJK / emoji para identificar quais caracteres pesam mais

Contador de bytes UTF-8

Bytes UTF-8
0 bytes
Caracteres
0
Unidades UTF-16
0
Linhas
0
Detalhamento por bytes
1 byte (ASCII) 0
2 bytes (Latin, etc.) 0
3 bytes (BMP CJK) 0
4 bytes (emoji, suplementares) 0

※ As unidades UTF-16 equivalem a string.length do JavaScript. Pares substitutos (emojis, etc.) contam como 2 unidades.

※ 1 byte = ASCII, 2 bytes = Latin estendido / grego / cirílico, 3 bytes = BMP CJK / Hangul / Kana, 4 bytes = emojis e planos suplementares.

Copiado!
Article

Contador de bytes UTF-8 | Identifique a divergência entre VARCHAR e String.length em uma única tela

Cole um texto e veja simultaneamente os bytes UTF-8, pontos de código Unicode (caracteres reais), unidades de código UTF-16 (o valor que string.length retorna em JavaScript) e o número de linhas. O detalhamento em 4 categorias (ASCII, Latim estendido, BMP CJK, emoji e planos suplementares) mostra exatamente quais caracteres estão inflando seu orçamento de armazenamento.

💡 Sobre esta ferramenta

Se você já recebeu ERROR 1406: Data too long for column ao inserir um nome com til, percebeu que um JWT contendo emoji quase dobra de tamanho, ou descobriu no console que '😀'.length === 2, você esbarrou na diferença entre pontos de código Unicode, bytes UTF-8 e unidades UTF-16.

UTF-8 é uma codificação de comprimento variável definida pelo RFC 3629: ASCII cabe em 1 byte, o Latim estendido (ã, ç, é, õ), grego e cirílico em 2, o bloco BMP CJK em 3, e tudo acima de U+FFFF — emoji, ideogramas suplementares, símbolos matemáticos — em 4 bytes. As strings de JavaScript, por outro lado, vivem internamente em UTF-16, então qualquer caractere fora do BMP aparece como par substituto (surrogate pair) e conta como 2 em length. Resultado: bancos de dados medem em bytes, APIs de JS raciocinam em unidades UTF-16 e nós humanos contamos em grafemas. As três medidas divergem assim que um emoji ou caractere exótico entra em cena.

Esta ferramenta exibe as quatro métricas lado a lado e classifica cada caractere em um dos quatro buckets de bytes UTF-8, permitindo responder perguntas práticas: "Por que um texto em português pesa mais que a versão em inglês?", "Quantos emoji cabem em uma chave Redis de 4 KB?", "Meu display_name cabe nesta coluna NVARCHAR(50)?".

🧐 Perguntas frequentes

Q. VARCHAR(255) significa 255 caracteres ou 255 bytes? A. No MySQL 5.0.3 ou superior são 255 caracteres, mas o limite de tamanho de linha é calculado em bytes (65.535 por linha). Com utf8mb4, um VARCHAR(N) é tratado como podendo ocupar até N × 4 bytes nos cálculos de índice e linha — portanto uma única coluna VARCHAR(16383) já preenche a linha inteira. Use o campo "Bytes UTF-8" desta ferramenta para dimensionar colunas com dados reais.

Q. Por que '😀'.length retorna 2 em JavaScript? A. String.prototype.length retorna unidades de código UTF-16. U+1F600 fica fora do BMP, então é codificado como o par substituto 😀. Para contar caracteres reais, use [...string].length, Array.from(string).length ou o campo "Caracteres" desta ferramenta, que itera pontos de código com for..of.

Q. Qual a diferença entre utf8 e utf8mb4 no MySQL? A. O charset legado utf8 armazena no máximo 3 bytes por caractere e converte silenciosamente qualquer caractere de 4 bytes (emoji, vários ideogramas suplementares, símbolos matemáticos) em ?. utf8mb4 é o UTF-8 completo conforme o RFC 3629. Para novos esquemas escolha sempre utf8mb4: se o bucket "4 bytes" desta ferramenta tiver qualquer valor, o charset legado teria destruído seus dados.

Q. Caracteres vs unidades UTF-16: quando isso importa? A. Em qualquer API que confia em string.length: props key do React, truncamento ingênuo com substring, validadores de comprimento de senha, limites do Twitter antes de 2017. Grafemas (👨‍👩‍👧‍👦 = um único caractere percebido) também diferem de pontos de código; use Intl.Segmenter quando precisar de contagem voltada ao usuário final.

Q. Como são contadas as quebras de linha? A. LF (\n), CRLF (\r\n) e CR (\r) são todos tratados como um único separador de linha. Uma entrada vazia equivale a 0 linhas; qualquer entrada não vazia equivale a pelo menos 1. Observação: CRLF ainda ocupa 2 bytes e 2 unidades UTF-16 mesmo contando como um separador único.

📚 Curiosidades

  • A herança do latin1 no Brasil: Sistemas brasileiros nascidos nos anos 2000 — bancos legados de varejo, ERPs financeiros, ginecologia de prontuários eletrônicos antigos — frequentemente usavam latin1, onde cada caractere, incluindo ã, ç, é, ocupava 1 byte. A migração para utf8mb4 fez essas mesmas letras passarem a ocupar 2 bytes, e queries que confiavam em LENGTH(coluna) para validar tamanho começaram a falhar. O padrão correto é CHAR_LENGTH(coluna), e esta ferramenta mostra de relance qual das duas grandezas interessa.
  • Português europeu vs brasileiro: PT-PT usa formas como direcção, acção, colectivo (com c antes do t), enquanto PT-BR adotou direção, ação, coletivo após o Acordo Ortográfico de 1990. PT-PT também usa mais o ç e o trema (ü antes da reforma). Em termos de bytes, um texto PT-PT clássico tende a ser ligeiramente mais pesado por trazer mais ligaduras e acentos preservados. Cole um trecho em cada variante e compare o bucket "2 bytes" — a diferença é pequena mas visível.
  • Caracteres regionais e WhatsApp: O WhatsApp Brasil registra um dos maiores volumes globais de mensagens, e cerca de 70% delas contém pelo menos um emoji ou figurinha. Cada emoji padrão adiciona 4 bytes UTF-8 + 2 unidades UTF-16; "Oi 😊👍🎉" ocupa 15 bytes contra 2 bytes de "Oi". Para SMS-gateways e push notifications com APNS, onde a cota de bytes é estrita, esse acréscimo é sentido imediatamente em escala.