"Strings" and "bytes": why is this a programmer's eternal headache?
\nImagine this situation: you are writing a network application in C#, sending data to a server, and the output is a mess of characters. Or you encrypt a password, and on the other end they can't decrypt it. Sound familiar? The root of the evil often lies in incorrectly converting a string to a byte array (and back).
\nThe question "Converting string to byte array in C#" on Stack Overflow has gathered thousands of views for a reason. This is the foundation on which working with files, cryptography, serialization, and network communication rest. Without understanding this topic, you will keep stepping on the same rake. Let's finally figure out how to do it correctly once and for all.
\n\nWhy can't you just take and convert a string to bytes?
\nA naive approach is to use BitConverter.GetBytes() for a character? No. The problem is that a string is an abstraction consisting of characters (char, 2 bytes in C#). And a byte array is raw data that depends on the encoding.
The same character "A" in UTF-8 encoding takes 1 byte, in UTF-16 — 2 bytes, and in UTF-32 — 4 bytes. If you choose the wrong encoding, data will be lost. Remember the main rule: always specify the encoding explicitly.
\n\nThe most popular method: Encoding.UTF8.GetBytes()
\nThis is what you will use in 90% of cases. UTF-8 is the de facto standard for the web, JSON, and most APIs.
\n\nusing System;\nusing System.Text;\n\nclass Program\n{\n static void Main()\n {\n string original = "Привет, мир! 🌍";\n \n // Convert the string to a byte array (UTF-8)\n byte[] utf8Bytes = Encoding.UTF8.GetBytes(original);\n \n // Reverse conversion (for verification)\n string restored = Encoding.UTF8.GetString(utf8Bytes);\n \n Console.WriteLine($"Original string: {original}");\n Console.WriteLine($"Byte array (length {utf8Bytes.Length}): {BitConverter.ToString(utf8Bytes)}");\n Console.WriteLine($"Restored string: {restored}");\n }\n}\n\nResult:
\nOriginal string: Привет, мир! 🌍\nByte array (length 18): D0-9F-D1-80-D0-B8-D0-B2-D0-B5-D1-82-2C-20-D0-BC-D0-B8-D1-80-21-20-F0-9F-8C-8D\nRestored string: Привет, мир! 🌍\n\nNote: the emoji "🌍" takes 4 bytes (F0-9F-8C-8D). UTF-8 can work with any Unicode characters, unlike outdated encodings.
\n\nOther popular encodings
\n- \n
- Encoding.ASCII — only 7-bit characters (0-127). Not suitable for Cyrillic or special characters — anything above 127 will turn into '?' \n
- Encoding.Unicode (also known as UTF-16LE) — used internally by C# to store strings. Each character takes 2 bytes (or 4 for surrogate pairs). \n
- Encoding.UTF32 — each character is strictly 4 bytes. Resource-intensive but predictable. \n
- Encoding.Default — system encoding (ANSI). Avoid it! It differs on different computers. \n
Conversion using BitConverter and MemoryStream
\nSometimes you need to get a "raw" representation of a string as an array of characters (char). This is not the same as bytes in an encoding, but it can be useful for low-level work.
\n\nstring text = "C#";\n// Get the char array\nchar[] chars = text.ToCharArray();\n// Convert each char to 2 bytes (Little-Endian)\nbyte[] rawBytes = new byte[chars.Length * sizeof(char)];\nBuffer.BlockCopy(chars, 0, rawBytes, 0, rawBytes.Length);\n\nConsole.WriteLine(BitConverter.ToString(rawBytes)); // 43-00-23-00\n\nThis method gives an array in UTF-16LE encoding (as stored in memory). Use it only if you know exactly what you are doing.
\n\nSpecial case: Base64
\nYe