UTF-8, за исключением самой нулевой кодовой точки, не будет содержать нулевых байтов.Первый байт всех многобайтовых кодировок (не кодовые точки ASCII) всегда начинается с битовой комбинации 11
, а последующие байты всегда начинаются с битовой комбинации 10
.
Как вы можете видетьиз следующей таблицы U+0000
- это единственная кодовая точка, которая может дать вам нулевой байт в UTF-8.
+----------------+----------+----------+----------+----------+
| Unicode | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
+----------------+----------+----------+----------+----------+
| U+0000-007F | 0xxxxxxx | | | |
| U+0080-07FF | 110yyyxx | 10xxxxxx | | |
| U+0800-FFFF | 1110yyyy | 10yyyyxx | 10xxxxxx | |
| U+10000-10FFFF | 11110zzz | 10zzyyyy | 10yyyyxx | 10xxxxxx |
+----------------+----------+----------+----------+----------+
UTF-16 будет вбрасывать нулевые байты между вашими байтами ASCII, но тогда этопросто выбрасывать каждый второй байт.Будет ли это 0, 2, 4, ...
или 1, 3, 5, ...
, зависит от того, является ли ваша кодировка UTF-16 прямым или младшим.
Из вашего примера видно, что ваш поток данных делает укажите UTF-8 (43 4f 44 45 53 45 54 3d 55 54 46 38
переводится в текст CODESET=UTF8
), но я гарантирую вам, что он врет: -)
Сегмент 72 00 65 00 61 00 74 00 68 00 69 00 6e 00 67 00
- это UTF-16 для reathing
, предположительно aсегмент слова, так как я не знаком с этим словом (во всяком случае, на английском).
Я бы посоветовал вам уточнить, кто бы ни генерировал эти данные, поскольку они явно ошибочны.Что касается того, как вы обрабатываете UTF-16, я рассмотрел это выше.При условии, что там есть данные ASCII (альтернативные байты всегда равны нулю), вы можете просто выбросить эти альтернативы что-то вроде:
// Process a UTF16 buffer containing ASCII-only characters.
// buff is the buffer, count is the quantity of UTF-16 chars.
// Will change buffer.
void compressUtf16 (char *buff, size_t count) {
int i;
for (i = 0; i < count; i++)
buff[i] = buff[i*2]; // for xx 00 xx 00 xx 00 ...
}
И, если вы используете other endian UTF-16, просто измените:
buff[i] = buff[i*2]; // for xx 00 xx 00 xx 00 ...
на:
buff[i] = buff[i*2+1]; // for 00 xx 00 xx 00 xx ...