How text becomes binary
Computers store text as bytes, and a byte is 8 bits. A binary translator does two steps: it encodes the text into bytes with a character encoding, then writes each byte in base 2, padded to 8 digits. The encoding matters as soon as you leave plain English letters:
| Character | UTF-8 bytes | Binary |
|---|---|---|
| H | 48 | 01001000 |
| i | 69 | 01101001 |
| é (U+00E9) | C3 A9 | 11000011 10101001 |
| 😀 (U+1F600) | F0 9F 98 80 | 11110000 10011111 10011000 10000000 |
In UTF-8, ASCII characters take one byte, accented Latin letters two, most Chinese characters three, and emoji four. In UTF-16 (Encoding.Unicode, the way .NET strings are stored in memory) every character takes two bytes, and emoji take four. That is why "H" is 01001000 in UTF-8 but 01001000 00000000 in UTF-16 little-endian.
Text to binary in C#
using System.Text;
string text = "Hi";
byte[] bytes = Encoding.UTF8.GetBytes(text);
string binary = string.Join(" ", bytes.Select(b => Convert.ToString(b, 2).PadLeft(8, '0')));
Console.WriteLine(binary); // 01001000 01101001
Convert.ToString(b, 2) drops leading zeros (72 becomes 1001000), so PadLeft(8, '0') puts them back. Without it, binary strings cannot be split back into bytes.
Binary to text in C#
using System.Text;
string binary = "01001000 01101001";
byte[] bytes = binary.Split(' ', StringSplitOptions.RemoveEmptyEntries)
.Select(b => Convert.ToByte(b, 2))
.ToArray();
string text = Encoding.UTF8.GetString(bytes);
Console.WriteLine(text); // Hi
Use the same encoding in both directions. Bytes that are not valid UTF-8 (for example a lone 11000011) do not throw: GetString puts the replacement character U+FFFD (�) in their place. Use new UTF8Encoding(false, throwOnInvalidBytes: true) if you would rather get an exception.
Convert.ToByte(s, 2) is more forgiving than it looks:
Console.WriteLine(Convert.ToByte("1001000", 2)); // 72: leading zeros are optional
Console.WriteLine(Convert.ToByte("0000001001000", 2)); // 72: so are extra ones
Console.WriteLine(Convert.ToByte("+1001000", 2)); // 72: a leading + is accepted
// Convert.ToByte("101001000", 2) throws OverflowException: 328 does not fit in a byte.
// Convert.ToByte("0b1001000", 2) throws FormatException: no 0b prefix here.
7-bit binary
ASCII only uses the values 0 to 127, which fit in 7 bits, so some texts and exercises write each character with 7 digits: "Hi" is 1001000 1101001. It only works for ASCII; any byte of 128 or more needs all 8 bits, which is why the 7-bit option refuses accented letters in UTF-8. When you read 7-bit binary without spaces, choose 7 bits so the digits are cut in the right places.
The BitArray trap
System.Collections.BitArray looks like the obvious way to get the bits of a byte array, but it numbers the bits of each byte from the least significant one. Printed in order, every byte comes out backwards:
using System.Collections;
// BitArray counts bits from the least significant one, so this prints the bits of "H" backwards.
var bits = new BitArray(new byte[] { 0b01001000 });
Console.WriteLine(string.Concat(bits.Cast<bool>().Select(b => b ? '1' : '0'))); // 00010010
Use Convert.ToString(b, 2) for text output, and keep BitArray for flags and bit sets, where the order does not matter.
FAQ
What is "Hello" in binary?
01001000 01100101 01101100 01101100 01101111 in ASCII or UTF-8: one byte per letter, each written with 8 binary digits.
How many bits is one character?
It depends on the encoding. In ASCII and UTF-8 an English letter is 8 bits (7 would fit), accented letters are 16 bits in UTF-8, and emoji are 32. In UTF-16 every character is at least 16 bits.
How do I convert text to binary in C#?
Get the bytes with Encoding.UTF8.GetBytes(text), then write each one with Convert.ToString(b, 2).PadLeft(8, '0') and join them with spaces.
How do I convert binary to text in C#?
Split the binary into 8-digit groups, turn each into a byte with Convert.ToByte(group, 2), and decode the bytes with Encoding.UTF8.GetString(bytes).
Why is my binary 16 bits per letter?
The text was encoded as UTF-16 (Encoding.Unicode in .NET), which uses two bytes per character. Choose UTF-8 for one byte per ASCII letter.
Why does the text come out as question marks or diamonds?
The bytes were decoded with the wrong encoding. Encoding.ASCII turns every byte above 127 into "?", and UTF-8 turns invalid byte sequences into U+FFFD. Decode with the encoding the binary was made with.