2016-12-21 2 views
2

Я работаю с библиотекой base64, которую я нашел на GitHub Link to b64.c, и он работает нормально, когда я кодирую строки ascii, но когда я пытаюсь кодировать двоичный файл, например изображение, он не работает. Ниже приведен фрагмент кода, который я использую для чтения в файле.Base64 не работает при кодировании специальных символов

hello.txt

héllo 

hello.txt имеет только один специальный символ. Он работает нормально, если специальный персонаж был просто обычным персонажем.

main.c

int main() 
{ 
    FILE *fp=NULL; 
    char *buf=NULL, *str1="héllo", *str2="hello"; 
    int i=0; 
    size_t fsize=0, bytes_read=0; 

    fp=fopen("hello.txt", "rb"); 
    fseek(fp, 0, SEEK_END); 
    fsize=ftell(fp); 
    rewind(fp); 
    buf=(char*)malloc(sizeof(char)*(fsize)); 
    //buf[fsize]='\0'; 
    bytes_read=fread(buf, 1, fsize, fp); 
    if(bytes_read!=fsize) exit(-1); 
    fclose(fp); 
    printf("encoded=%s\n", b64_encode((const unsigned char*)buf, fsize)); 

    getchar(); 
    return 0; 
} 

encode.c // имеет функцию base64_encode

char *b64_encode(const unsigned char* src, size_t len) 
{ 
    int i=0, j=0; 
    char *enc=NULL; 
    size_t size=0; 
    unsigned char buf[4], tmp[3]; 

    // alloc 
    enc=(char*)malloc(0); 
    if(enc==NULL) 
    { 
     perror("enc"); 

     return NULL; 
    } 

    while(len--) 
    { 
     tmp[i++]=*(src++); 
     if(i==3) 
     { 
      buf[0]=(tmp[0]&0xfc)>>2; 
      buf[1]=((tmp[0]&0x03)<<4)+((tmp[1]&0xf0)>>4); 
      buf[2]=((tmp[1]&0x0f)<<2)+((tmp[1]&0xc0)>>6); 
      buf[3]=tmp[2]&0x3f; 

      /* 
      * alloc 4 bytes for 'enc' and then translate 
      * each encoded buffer part by index from 
      * the base64 table into 'enc' unsigned char array 
      */ 
      enc=(char*)realloc(enc, size+4); 
      for(i=0; i<4; ++i) 
      { 
       enc[size++]=b64_table[buf[i]]; 
      } 

      // reset index 
      i=0; 
     } 
    } 

    if(i>0) 
    { 
     // fill 'tmp' with '\0' at most 3 times 
     for(j=i; j<3; ++j) 
     { 
      tmp[j]='\0'; 
     } 

     // perform same codes as above 
     buf[0]=(tmp[0]&0xfc)>>2; 
     buf[1]=((tmp[0]&0x03)<<4)+((tmp[1]&0xf0)>>4); 
     buf[2]=((tmp[1]&0x0f)<<2)+((tmp[1]&0xc0)>>6); 
     buf[3]=tmp[2]&0x3f; 

     // same write to enc with new allocation 
     for(j=0; j<i+1; ++j) 
     { 
      enc=(char*)realloc(enc, size+1); 
      enc[size++]=b64_table[buf[j]]; 
     } 

     while((i++)<3) 
     { 
      enc=(char*)realloc(enc, size+1); 
      enc[size++]='='; 
     } 
    } 

    enc=(char*)realloc(enc, size+1); 
    enc[size]='\0'; 

    return enc; 
} 

Ouput по программе

aOnsbG9= 

после сохранения с UTF-8

aMPpbGxv 

ожидается выходной

aMOpbGxv 

PS. Я читаю файл как двоичный, так как он имеет специальные символы, и потому что позже я хотел бы читать двоичные данные, такие как изображения или видео.

+0

Будьте осторожны с 'malloc (0)'. Это реализация определена, если она вернет нулевой указатель или ненулевой указатель. –

+3

Можете ли вы уточнить, что «это не работает»? – Ctx

+0

вывод, который задан, не соответствует ожидаемому результату. – Hawk

ответ

3

Проблема заключается в функции b64_encode:

buf[2]=((tmp[1]&0x0f)<<2)+((tmp[1]&0xc0)>>6); 

должен быть

buf[2]=((tmp[1]&0x0f)<<2)+((tmp[2]&0xc0)>>6); 

Обязательно, чтобы исправить это на обоих вхождений.

+0

Это заняло некоторое время, чтобы увидеть .... – Ctx

+0

проклятый..показывает много..поэтому..все это время я подчеркивал ... оцените время, которое вы взяли, чтобы просмотреть его. – Hawk

Смежные вопросы