It's 22022 and the Unicode consortium is having a problem. After the writing system of the ⮧⣝Ⅲⴄ⟢⧩⋓⣠ civilization was assigned the last Unicode block, the consortium members have been scrambling to find a new encoding to replace UTF-8. Finally UTF-∞, a proposal by Bob Rike, was adopted. UTF-∞ is backwards compatible with UTF-8. If you know how UTF-8 works, then TLDR; UTF-∞ is the natural extension of UTF-8.
UTF-∞, like UTF-8, encodes an integer to some sequence of bytes like so (each byte shown as 8 bits)
xxxxxxxx 10xxxxxx 10xxxxxx 10xxxxxx ...
If the sequence of bytes has length \$n\$, then the first \$n\$ x
:s (from left to right), are set to 1
and the \$n+1\$:th x
is set to 0. The rest of the x
:s encode a big-endian binary representation of the integer.
There is an exception. If the length of the sequence is 1
(meaning the input number is less than 128), then the encoding looks as follows:
0xxxxxxx
Where the x
:s contain the binary representation of the integer.
Also, in order for an encoding to be valid, the minimum amount of bytes has to be used (no overlong encodings).
Your task is to take in a non-negative integer and output the UTF-∞ representation of the integer. You can output a list/string of bytes or a list of numbers between 0 and 255 inclusive. This is code-golf so shortest code wins.
Example
Let's take the input 8364 (the euro symbol "€") as an example. We somehow know that we need 3 bytes, so \$n=3\$. Let's take
xxxxxxxx 10xxxxxx 10xxxxxx 10xxxxxx ...
And take the first 3 bytes:
xxxxxxxx 10xxxxxx 10xxxxxx
Next, the first \$n\$ "x"s are set to 1:
111xxxxx 10xxxxxx 10xxxxxx
And then the leftmost "x" is set to 0. (index \$n+1\$ before any "x"s were replaced)
1110xxxx 10xxxxxx 10xxxxxx
Finally, we fill the binary expansion of 8364 (which is 10 0000 1010 1100) into the remaining "x"s
11100010 10000010 10101100
And convert to bytes:
[226, 130, 172]
Now you might wonder how we know what value of \$n\$ to use? One option is trial and error. Start from \$n=1\$ and increment \$n\$ until we find an \$n\$ where the binary expansion of our input fits.
If we had the input 70368744177663 (\$n=9\$) we would start like so:
xxxxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
and then
11111111 1010xxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
and then fill the binary expansion of 70368744177663
Test cases
0 -> [0]
69 -> [69]
127 -> [127]
128 -> [194, 128]
1546 -> [216, 138]
2047 -> [223, 191]
2048 -> [224, 160, 128]
34195 -> [232, 150, 147]
65535 -> [239, 191, 191]
65536 -> [240, 144, 128, 128]
798319 -> [243, 130, 185, 175]
2097151 -> [247, 191, 191, 191]
2097152 -> [248, 136, 128, 128, 128]
30606638 -> [249, 180, 176, 148, 174]
67108863 -> [251, 191, 191, 191, 191]
67108864 -> [252, 132, 128, 128, 128, 128]
20566519621 -> [254, 147, 137, 183, 130, 189, 133]
68719476735 -> [254, 191, 191, 191, 191, 191, 191]
68719476736 -> [255, 129, 128, 128, 128, 128, 128, 128]
1731079735717 -> [255, 153, 140, 140, 153, 136, 166, 165]
2199023255551 -> [255, 159, 191, 191, 191, 191, 191, 191]
2199023255552 -> [255, 160, 160, 128, 128, 128, 128, 128, 128]
64040217759022 -> [255, 174, 163, 186, 134, 155, 164, 180, 174]
70368744177663 -> [255, 175, 191, 191, 191, 191, 191, 191, 191]
70368744177664 -> [255, 176, 144, 128, 128, 128, 128, 128, 128, 128]
34369578119952639221217025744100729453590194597032 -> [255, 191, 191, 191, 191, 165, 184, 145, 129, 139, 182, 177, 159, 176, 167, 155, 139, 159, 138, 163, 170, 143, 151, 141, 156, 154, 134, 183, 176, 175, 170, 178, 168]