Quoted printable в koi8-r. Как перекодировать?
=?koi8-r?Q?=C1=C2=D7?=
Эта строка ничто иное как текст "абв".
Воспользовавшись этой таблицей сформировал словарик, при помощи которого перевожу QuotedPrintable символы, в читаемый кирилический вид. Однако тут далее трабла... Расшифровав это дело, я получаю вместо "абв" строку "БВЧ". Насколько я понял, это у нас "абв" но только в KOI8-R . Я прав? поправьте меня если - нет.
Каким-же образом преобразовать этот "БВЧ" в "абв"?
п.с. а если так нужно сначала заюзать 1251 кодировку, то что мешает потом сопоставить каждому символу из 1251 кодировки символ из koi8-r кодировки(таблицы то есть)?
просто если ставить вопрос так абстрактно, как он сейчас звучит, то всё сводится к взятию другой таблицы для раскодирования как бы...
---
хотя боюсь таки да... придётся нарисовать для каждой кодировки - таблицу соответствий. пусть это и не гибко, зато никакой мороки с перегонкой из кодировок туда-сюда.
Спасибо кстати за таблички кодировок :)
Так и декодируй последовательно, сначало с QuotedPrintable вANSI , а далее koi8-r.
После QuotedPrintable получаем "БВЧ", а после применения koi8-r "БВЧ" декодируется в "абв". Проверил, все работает, строка "=C1=C2=D7" преобразуется в "абв".
Я пишу приложение на C++ и Qt.
Любой, который поддерживает строковые и арифметические операции. C++ подойдёт.
Символы после = содержат 16-ричный код символа. Достаточно просто заменить эти три символа на символ с таким кодом. Таблицы соответствия нужны будут потом, чтобы преобразовать из ANSI в Windows-1251. Но тут без таблиц не обойтись никак.
Я пишу приложение на C++ и Qt.
Думаю, нижеприведенный пример закроет тему:
#define WRBYTE(v) {if(bCalc){lposOut++;}else{if(lposOut>=lszOut) break; bufOut[lposOut++]=v;}}
long STDCALL CConvert::QuotedToANSI(const char *bufIn, long *lszIn, char *bufOut, long lszOut)
{
if(!bufIn || !lszIn) return 0;
if(!*lszIn) return 0;
long lposIn = 0, lposOut=0;
BYTE bin;
int k;
bool bflag;
BOOL bCalc = (bufOut && lszOut>0) ? FALSE : TRUE;
#define ISHEX(b) ((b=='a' || b=='A' || b=='b' || b=='B' || b=='c' || b=='C' || b=='d' || b=='D' || b=='e' || b=='E' || b=='f' || b=='F') ? 1 : 0)
while(lposIn < *lszIn) {
if(bufIn[lposIn]=='='){
if(lposIn==*lszIn-1) {
lposIn++;
break;
}
bflag = 0;
if(isdigit((int)bufIn[lposIn + 1]) || ISHEX(bufIn[lposIn + 1]))
if(isdigit((int)bufIn[lposIn + 2]) || ISHEX(bufIn[lposIn + 2]))
bflag = 1;
if(bflag){
bin = (BYTE)bufIn[lposIn + 1];
if(isdigit((int)bin))
k = bin - 48;
else {
if(bin<'a') bin += 32;
k = bin - 87;
}
bin = (BYTE)bufIn[lposIn + 2];
if(isdigit((int)bin))
k = (k<<4) + bin - 48;
else {
if(bin<'a') bin += 32;
k = (k<<4) + bin - 87;
}
WRBYTE(k);
lposIn+=3;
} else {
if(bufIn[lposIn+1]=='\x0d')
lposIn += 3;
else
WRBYTE(bufIn[lposIn++]);
}
} else {
WRBYTE(bufIn[lposIn++]);
}
}
if(!bCalc) *lszIn = lposIn;
return lposOut;
}
static char Win_KoiRChars[] = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 060, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 169, 150, 151, 152, 153, 154, 062, 176, 157, 183, 159,
160, 246, 247, 074, 164, 231, 166, 167, 179, 169, 180, 060, 172, 173, 174, 183,
156, 177, 073, 105, 199, 181, 182, 158, 163, 191, 164, 062, 106, 189, 190, 167,
225, 226, 247, 231, 228, 229, 246, 250, 233, 234, 235, 236, 237, 238, 239, 240,
242, 243, 244, 245, 230, 232, 227, 254, 251, 253, 154, 249, 248, 252, 224, 241,
193, 194, 215, 199, 196, 197, 214, 218, 201, 202, 203, 204, 205, 206, 207, 208,
210, 211, 212, 213, 198, 200, 195, 222, 219, 221, 223, 217, 216, 220, 192, 209};
long STDCALL CConvert::FromANSI(const char *bufIn, long lszIn, char *bufOut, long lszOut, const char* cTable/* Win_KoiRChars */)
{
if(!bufIn || !lszIn || !cTable) return 0;
if(!bufOut) return lszIn;
long lposIn = 0;
while(lposIn<lszIn) {
if(lposIn>=lszOut) break;
if((unsigned char)bufIn[lposIn]>127) {
bufOut[lposIn] = cTable[(unsigned char)bufIn[lposIn]-128];
} else
bufOut[lposIn] = bufIn[lposIn];
lposIn++;
}
return lposIn;
}
Вот так нельзя было сделать?