Octets à partir de chaînes en C# sans encodage : résoudre le problème correctement

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi cette question est-elle si populaire sur Stack Overflow ?



Si vous avez déjà programmé en C# et avez été confronté à la nécessité de convertir une chaîne en tableau d'octets, vous vous êtes sûrement demandé : « Pourquoi dois-je spécifier l'encodage ? Une chaîne est juste une chaîne ! ». Cette question a recueilli des milliers de vues sur Stack Overflow non sans raison. Elle touche à une incompréhension fondamentale entre comment nous voyons le texte et comment l'ordinateur le voit.



Dans cet article, nous ne donnerons pas seulement un code prêt à l'emploi, mais nous comprendrons pourquoi Encoding.UTF8.GetBytes("hello") n'est pas une solution de contournement, mais la seule manière correcte. Vous apprendrez comment obtenir la représentation en octets des chaînes en C# sans risque de perte de données, et ce qui se cache derrière la magie de la « sélection automatique de l'encodage ».



Le mythe de la « chaîne sans encodage »



Beaucoup de débutants pensent qu'une chaîne en C# est simplement une séquence d'octets. Ce n'est pas le cas. En interne, string dans .NET est stockée en UTF-16 (caractères sur deux octets). Lorsque vous écrivez "Привет", cela occupe 12 octets en mémoire (6 caractères × 2 octets). Mais si vous essayez d'envoyer cette chaîne dans un fichier, sur le réseau ou dans une base de données, vous aurez presque toujours besoin d'un autre format — le plus souvent UTF-8.



Essayer d'obtenir des octets « sans encodage » revient à demander : « Comment traduire un livre du russe vers l'anglais sans préciser la langue ? ». C'est impossible. L'encodage est l'ensemble des règles de conversion des caractères en octets. Sans lui, vous obtiendrez un charabia.



Comment NE PAS faire (une erreur typique)



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


Ce code utilise l'encodage système par défaut (généralement Windows-1251 sur une version russe de Windows). Si vous exécutez ce code sur une autre machine ou sous Linux, vous obtiendrez des octets différents. Votre application deviendra imprévisible.



L'approche correcte : spécification explicite de l'encodage



La seule manière fiable d'obtenir une représentation en octets cohérente des chaînes est de spécifier explicitement l'encodage. L'option la plus populaire et recommandée est UTF-8 :



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


Ce code donnera toujours le même résultat sur n'importe quelle plateforme. Pourquoi ? Parce que UTF-8 est une norme internationale qui fonctionne partout de la même manière.



Autres options d'encodage (quand sont-elles nécessaires)



  • ASCII — uniquement le latin, supprime tous les caractères >127.
  • Unicode (UTF-16LE) — format interne de C#, mais inefficace pour le stockage.
  • Windows-1251 — legacy, uniquement pour la compatibilité avec les anciens systèmes.


Pour 99 % des tâches modernes, utilisez Encoding.UTF8.



Et si je veux « sans spécification » ? Existe-t-il une astuce ?



Techniquement, vous pouvez utiliser BitConverter.ToString() ou du code unsafe avec des pointeurs, mais cela vous donnera les octets bruts UTF-16 stockés en mémoire. C'est une mauvaise idée pour plusieurs raisons :



  • Le résultat dépend de la plateforme (Little-Endian vs Big-Endian).
  • Vous obtiendrez des octets nuls supplémentaires pour le latin (chaque caractère occupe 2 octets).
  • Lors d'un changement de version de .NET, la représentation interne peut changer (peu probable, mais possible).


Exemple de code dangereux à ne pas reproduire :



unsafe{    string text = "Hello";    fixed (char* ptr = text)    {        byte* bytePtr = (byte*)ptr;        // Travailler avec les octets bruts UTF-16    }}


Cela fonctionne, mais viole le principe « ne touche pas aux internes si tu n'en comprends pas les conséquences ».



Meilleures pratiques pour les débutants

Blogs

Book Recommendations