Bytes de strings em C# sem codificação: resolvendo o problema corretamente

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que esta pergunta é tão popular no Stack Overflow?



Se você já programou em C# e precisou converter uma string em um array de bytes, certamente já se perguntou: "Por que eu preciso especificar a codificação? Afinal, uma string é apenas uma string!". Esta pergunta acumulou milhares de visualizações no Stack Overflow não por acaso. Ela aborda um mal-entendido fundamental entre como vemos o texto e como o computador o vê.



Neste artigo, não vamos apenas fornecer o código pronto, mas também explicar por que Encoding.UTF8.GetBytes("hello") não é uma gambiarra, mas sim a única maneira correta. Você aprenderá como obter a representação de bytes de strings em C# sem risco de perder dados, e o que está por trás da mágica da "seleção automática de codificação".



O mito da "string sem codificação"



Muitos iniciantes pensam que uma string em C# é apenas uma sequência de bytes. Isso não é verdade. Internamente, a string no .NET é armazenada como UTF-16 (caracteres de dois bytes). Quando você escreve "Привет", na memória são 12 bytes (6 caracteres × 2 bytes). Mas se você tentar enviar essa string para um arquivo, rede ou banco de dados, quase sempre precisará de outro formato — geralmente UTF-8.



Tentar obter bytes "sem codificação" é como perguntar: "Como traduzir um livro do russo para o inglês sem especificar o idioma?". Impossível. A codificação são as regras de conversão de caracteres em bytes. Sem elas, você terá uma bagunça.



Como NÃO fazer (erro típico)



string text = "Hello, мир!";byte[] wrongBytes = System.Text.Encoding.Default.GetBytes(text); // RUIM!


Este código usa a codificação padrão do sistema (geralmente Windows-1251 no Windows em russo). Se você executar este código em outra máquina ou no Linux — obterá bytes diferentes. Sua aplicação se tornará imprevisível.



Abordagem correta: especificação explícita da codificação



A única maneira confiável de obter uma representação de bytes consistente para strings é especificar explicitamente a codificação. A opção mais popular e recomendada é UTF-8:



string text = "Hello, мир!";byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(text);// Resultado: [72, 101, 108, 108, 111, 44, 32, 208, 188, 208, 184, 209, 128, 33]


Este código sempre dará o mesmo resultado em qualquer plataforma. Por quê? Porque UTF-8 é um padrão internacional que funciona da mesma forma em todos os lugares.



Outras opções de codificação (quando são necessárias)



  • ASCII — apenas latim, descarta todos os caracteres >127.
  • Unicode (UTF-16LE) — formato interno do C#, mas ineficiente para armazenamento.
  • Windows-1251 — legado, apenas para compatibilidade com sistemas antigos.


Para 99% das tarefas modernas, use Encoding.UTF8.



E se eu quiser "sem especificar"? Existe um hack?



Tecnicamente, você pode usar BitConverter.ToString() ou código unsafe com ponteiros, mas isso fornecerá os bytes brutos do UTF-16 armazenados na memória. Isso é uma má ideia por vários motivos:



  • O resultado depende da plataforma (Little-Endian vs Big-Endian).
  • Você obterá bytes nulos extras para caracteres latinos (cada caractere ocupará 2 bytes).
  • Com a mudança de versão do .NET, a representação interna pode mudar (improvável, mas possível).


Exemplo de código perigoso que não deve ser repetido:



unsafe{    string text = "Hello";    fixed (char* ptr = text)    {        byte* bytePtr = (byte*)ptr;        // Trabalhando com bytes brutos do UTF-16    }}


Isso funciona, mas viola o princípio "não mexa nos internos se você não entende as consequências".



Melhores práticas para iniciantes

Blogs

Book Recommendations