Encode unicode codepoints to UTF-8 manually I want to encode unicode codepoints to UTF-8 manually. I wrote the following C# code. I tested it with some cases I know, but I would like to know if it's correct for all inputs. I know that Unicode codepoints are undefined beyond 0x10FFFF ,but I don't care about that. Therefore the output of my method might be more than 4 bytes.

private byte[] CodePointToUtf8 (int codepoint)
{
    if (codepoint &lt; 0x80) {
        return new byte[]{ 
            (byte)(codepoint) 
        };
    } else if (codepoint &lt; 0x800) {         
        return new byte[]{ 
            (byte)(0xC0 | (codepoint &lt;&lt; 21 &gt;&gt; 27)), 
            (byte)(0x80 | (codepoint &lt;&lt; 26 &gt;&gt; 26))
        };
    } else if (codepoint &lt; 0x10000) {
        return new byte[] {
            (byte)(0xE0 | (codepoint &lt;&lt; 16 &gt;&gt; 28)),
            (byte)(0x80 | (codepoint &lt;&lt; 20 &gt;&gt; 26)) ,
            (byte)(0x80 | (codepoint &lt;&lt; 26 &gt;&gt; 26))
        };
    } else if (codepoint &lt; 0x200000) {
        return new byte[] {
            (byte)(0xF0 | (codepoint &lt;&lt; 11 &gt;&gt; 29)),
            (byte)(0x80 | (codepoint &lt;&lt; 14 &gt;&gt; 26)),
            (byte)(0x80 | (codepoint &lt;&lt; 20 &gt;&gt; 26)) ,
            (byte)(0x80 | (codepoint &lt;&lt; 26 &gt;&gt; 26))
        };
    } else if (codepoint &lt; 0x4000000) {
        return new byte[] {
            (byte)(0xF8 | (codepoint &lt;&lt; 6 &gt;&gt; 30)),
            (byte)(0x80 | (codepoint &lt;&lt; 8 &gt;&gt; 26)),
            (byte)(0x80 | (codepoint &lt;&lt; 14 &gt;&gt; 26)),
            (byte)(0x80 | (codepoint &lt;&lt; 20 &gt;&gt; 26)) ,
            (byte)(0x80 | (codepoint &lt;&lt; 26 &gt;&gt; 26))
        };
    } else {
        return new byte[] {
            (byte)(0xFC | (codepoint &lt;&lt; 1 &gt;&gt; 31)),
            (byte)(0x80 | (codepoint &lt;&lt; 2 &gt;&gt; 26)),
            (byte)(0x80 | (codepoint &lt;&lt; 8 &gt;&gt; 26)),
            (byte)(0x80 | (codepoint &lt;&lt; 14 &gt;&gt; 26)),
            (byte)(0x80 | (codepoint &lt;&lt; 20 &gt;&gt; 26)) ,
            (byte)(0x80 | (codepoint &lt;&lt; 26 &gt;&gt; 26))
        };
    }
}


Bonus question: Is there an build in way to do that?
Yes, the code is correct for all valid code points. I was first confused about the double shifts, since I have never seen them before, but they do their job well. Other authors typically do a single &gt;&gt; followed by a bit mask, e.g. (codepoint &gt;&gt; 12) &amp; 0x3F to skip the 12 bits to the right and take the next 6 bits. That way, the numbers can be verified more easily, since they are smaller. Plus, all the 01xxxxxx bytes have the same bitmask.

Your code omits some validity checks:


codepoint could be &lt; 0
codepoint could be between 0xD800 and 0xDFFF


Other than these, it is perfect.

I know for sure that this conversion is built-in into C#, I just don't know where. Try loading a file into a string using the UTF-8 encoding. During that loading, the built-in conversion code gets called.