Удаление байтов в дампе или utf-8 в c - PullRequest
1 голос
/ 12 июля 2011

У меня есть программа "C" на моей пожарной станции, которая перехватывает входящие пакеты на принтер станции. Затем программа сканирует пакет и отправляет звуковое оповещение о том, какое устройство должно быть на вызове. Округ недавно начал использовать пакеты UTF-8, и программа c не может обработать все лишние «00» в потоке данных. Мне нужно либо игнорировать 00, либо установить программу для обработки UTF-8. Я искал несколько дней, и нет ничего конкретного в том, как обращаться с utf-8, с которым может справиться новичок, такой как я. Ниже приведена интерпретируемая часть программы.

72 00 65 00 61 00 74 00 68 00 69 00 6e 00 67 00 позже в пакете

43 4f 44 45 53 45 54 3d 55 54 46 38 0a 40 50 4a начало пакета

***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 ...

} * {u_int i = 0; символ * искатель = 0; символ с; int j; int locflag; static int locationtripped = 0;

    static char currentline[256]; 
static int currentlinepos = 0;
static char lastdispatched[256];
static char dispatchstring[256];

char betastring[256];

static int a = 0;
static int e = 0;
static int pe = 0; 
static int md = 0;

static int pulse = 0;

static char location[128];
static char type[16];
static char station[16]; 

static FILE *fp;
static int printoutscanning = 0;
static char printoutID[20];
static char printoutfileID[32];

static FILE *dbg;

if(pulse) {
    if(pulse == 80) {
        sprintf(betastring, "beta a a a");
        printf("betastring: \"%s\"\n", betastring);
        system(betastring);
        pulse = 0; 
    } else
        pulse++;
}

    if(header->len > 96) {
        for(i=55; (i < header->caplen + 1 ) ; i++) {
            c = pkt_data[i-1];

        if(c == 13 || c == 10) {
            currentline[currentlinepos] = 0;
            currentlinepos = 0;
            j = strlen(currentline);
            if(j && (j > 1)) { 
                if(strlen(printoutfileID) && printoutscanning) {
                    dbg = fopen(printoutfileID, "a");
                    fprintf(dbg, "%s\n", currentline); 
                    fclose(dbg);
                }

                if(!printoutscanning) {
                    searcher = 0;
                    searcher = strstr(currentline, "INCIDENT HISTORY DETAIL:"); 
                    if(searcher) {
                        searcher = searcher + 26;
                        strncpy(printoutID, searcher, 9);
                        printoutID[9] = 0;
                        printoutscanning = 1; 
                        a = 0;
                 e = 0;
                        pe = 0;
                        md = 0;
            for(j = 0; j < 128; j++)
                            location[j] = 0; 
                        for(j = 0; j < 16; j++) {
                            type[j] = 0;
                            station[j] = 0;
                        }
                        sprintf(printoutfileID, "calls/%s %.6d.txt", printoutID, header-> ts.tv_usec);
                        dbg = fopen(printoutfileID, "a");
                        fprintf(dbg, "%s\n", currentline);
                        fclose(dbg);
                    } 

1 Ответ

3 голосов
/ 12 июля 2011

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 ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...