code = "й".charCodeAt(0)
//1081 или 0x0439
Далее смотрим, как
кодируется UTF-8.
Для русских букв (например,
й) упрощённо:
byteCode1 = code >> 6 | 0b11000000;
byteCode2 = code & 0b00111111 | 0b10000000;
Остаётся всё это склеить в одну функцию. В императивном стиле, конечно же, чтобы было понятно, что происходит:
function StringToBin(s) {
let arr = s.split(''); //разбиваем строку на символы
arr.forEach((symbol, index) => { //кодируем каждый символ
let code = symbol.charCodeAt(0);
let byteCode1 = code >> 6 | 0b11000000;
let byteCode2 = code & 0b00111111 | 0b10000000;
arr[index] = (code < 128 ? code.toString(16) : byteCode1.toString(16) + byteCode2.toString(16)).toUpperCase();
});
return arr.join(' '); //возвращаем кодированную строку
}
console.log(StringToBin("Хай"));
//D0A5 D0B0 D0B9
Но повторюсь, это упрощённый алгоритм, когда октетов не более двух. Если нужен универсальный вариант, то вам нужно слегка улучшить эту функцию. Проблем не должно возникнуть, ведь я рассказал, как и что нужно делать.