OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Среда, 20 Ноябрь, 2019 15:45

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
СообщениеДобавлено: Четверг, 27 Август, 2009 16:00 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4526
Откуда: Россия, Орёл
Задачка: найди ошибку (см. функцию idx64)
* Почему декодирование некорректной Base64-строки "не работает".
* Как не работает?

Как пользоваться такой библиотекой? Поставлять ей только корректные данные или исправить ошибку и потерять гарантию? :lol: (This module present "AS IS", absolutely no warranty, if anybody modyfied this source.)
Код:
/****************************************************************************************************************************
 *  Usage this module :
 *  size_t result = code64( JOB [ENCODE or DECODE], char *ASCII_Buffer, size_t ASCII_BUFFER_SIZE,
 *                          char *BASE64_Buffer,  size_t BASE64_BUFFER_SIZE );
 *  Sample for decode from ascii to base64 :
 *  result = code64( DECODE, char *ASCII_Buffer, size_t ASCII_BUFFER_SIZE, char *BASE64_Buffer,  size_t BASE64_BUFFER_SIZE );
 *  Parameter ASCII_BUFFER_SIZE - definition size input to decode sequence !
 *  function strlen() - may be used ONLY for text buffers, otherwize - BINARY DATA, use really size !
 *  Sample for encode from base64 to ascii :
 *  result = code64( ENCODE, char *ASCII_Buffer, size_t ASCII_BUFFER_SIZE, char *BASE64_Buffer,  size_t BASE64_BUFFER_SIZE );
 *  Parameter BASE64_BUFFER_SIZE - definition size input to encode sequence !
 *  function strlen() may be used for counting size for BASE64 array, if last symbol == '\0', otherwise use really size !
 *  .........................................................................................................................
 *  Return value:
 *  size_t result - counter, number of bytes in OUTPUT array, whose successfully encoded/decoded.
 *  if result == 0 - error found, abnormal terminating, nothing to encoding or decoding.
 *  .........................................................................................................................
 *  Internal function: idx64( char Ch ); Binary search index in Base64 array, for Ch character in parameter
 *  .........................................................................................................................
 *  This module present "AS IS", absolutely no warranty, if anybody modyfied this source.
 ****************************************************************************************************************************/
#include "base64.h"

/* Base_64 characters  */
const char Ch64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/*  Presort array for indexes  */
const INDEX64 Id64[64] = {
  {'+',62},{'/',63},{'0',52},{'1',53},{'2',54},{'3',55},{'4',56},{'5',57},{'6',58},{'7',59},{'8',60},{'9',61},
  {'A',0},{'B',1},{'C',2},{'D',3},{'E',4},{'F',5},{'G',6},{'H',7},{'I',8},{'J',9},{'K',10},{'L',11},{'M',12},
  {'N',13},{'O',14},{'P',15},{'Q',16},{'R',17},{'S',18},{'T',19},{'U',20},{'V',21},{'W',22},{'X',23},{'Y',24},{'Z',25},
  {'a',26},{'b',27},{'c',28},{'d',29},{'e',30},{'f',31},{'g',32},{'h',33},{'i',34},{'j',35},{'k',36},{'l',37},{'m',38},
  {'n',39},{'o',40},{'p',41},{'q',42},{'r',43},{'s',44},{'t',45},{'u',46},{'v',47},{'w',48},{'x',49},{'y',50},{'z',51}
};
 
/*  Base64 ENCODE / DECODE function  */
size_t code64( int job, char *buf_ascii, size_t ascii_size, char *buf_64, size_t buf_64_size )
{
  BASE64 b64;
  size_t i = 0, j = 0, k = 0, i3 = 0; /*  job indexes */
  size_t ask_len = 0;   /* Internal variable for size ascii buffer   */
  size_t buf64_len = 0; /* Internal variable for size base64 buffer  */

  b64.a[0] = 0; b64.a[1] = 0; b64.a[2] = 0;

/*  Decoding to Base64 code  */
  if( job == DECODE ) {
    ask_len = ascii_size;
    if( (ascii_size * 4 / 3) > buf_64_size ) return( CODE_ERR ); /* No enough space to decoding */
    if( ask_len == 0 ) return( CODE_ERR );
    i3 = (int) 3 * (ask_len / 3);      /* Dividing by 3       */
    if( i3 > 0 ) k = 3 - ask_len + i3; /* End of seq (1 or 2) */
    if( ask_len < 3 ) k = 3 - ask_len;

    while( i < i3 ) {
      b64.a[2] = buf_ascii[i];
      b64.a[1] = buf_ascii[i+1];
      b64.a[0] = buf_ascii[i+2];
      buf_64[j++] = Ch64[b64.b.b0];
      buf_64[j++] = Ch64[b64.b.b1];
      buf_64[j++] = Ch64[b64.b.b2];
      buf_64[j++] = Ch64[b64.b.b3];
      i+=3;
    }

    if( k == 2 ) {
      b64.a[2] = buf_ascii[i];
      b64.a[1] = 0;
      b64.a[0] = 0;
      buf_64[j++] = Ch64[b64.b.b0];
      buf_64[j++] = Ch64[b64.b.b1];
      buf_64[j++] = '=';
      buf_64[j++] = '=';
    }

    if( k == 1 ) {
      b64.a[2] = buf_ascii[i];
      b64.a[1] = buf_ascii[i+1];
      b64.a[0] = 0;
      buf_64[j++] = Ch64[b64.b.b0];
      buf_64[j++] = Ch64[b64.b.b1];
      buf_64[j++] = Ch64[b64.b.b2];
      buf_64[j++] = '=';
    }

    return( j );
  }

/* Restoring original characters */
  if( job == ENCODE ) {
    buf64_len = buf_64_size;
    if( buf64_len < 4 ) return( CODE_ERR ); /* Too small input buffer  */
    if( (buf_64_size * 3 / 4) > ascii_size ) return( CODE_ERR ); /* No enough space to encoding */
    i3 = buf64_len / 4;
    k = buf64_len - i3 * 4;
    if( k ) return( CODE_ERR ); /*  Illegal size for input sequence !! */
    k = 0;                      /*  Counter original bytes for output  */

    for( i = 0; i < buf64_len; i+=4 ) {
      b64.b.b0 = idx64( buf_64[i] );
      b64.b.b1 = idx64( buf_64[i+1] );
      b64.b.b2 = 0; b64.b.b3 = 0;
      if( buf_64[i+2] != '=' ) b64.b.b2 = idx64( buf_64[i+2] );
      else k--;
      if( buf_64[i+3] != '=' ) b64.b.b3 = idx64( buf_64[i+3] );
      else k--;
      buf_ascii[j++] = b64.a[2]; k++;
      buf_ascii[j++] = b64.a[1]; k++;
      buf_ascii[j++] = b64.a[0]; k++;
    }

    return( k );
  }

  return( CODE_ERR ); /*  Unknown command ! */
}

/*  Binary search character's index in array  */
int idx64( char ch )
{
  int start = 0;
  int pos   = 32;
  int end   = 63;

  while( (pos >= start) || (pos <= end) ) {
     if( ch == Id64[start].Ch ) return( Id64[start].Id );
     if( ch == Id64[pos].Ch )   return( Id64[pos].Id );
     if( ch == Id64[end].Ch )   return( Id64[end].Id );

     if( ch > Id64[pos].Ch ) {
        start = pos;
     }

     if( ch < Id64[pos].Ch ) {
        end = pos;
     }

     pos = (int) (start+end) / 2;
  }

/*  Illegal character found, task aborted !  */
  fprintf( stderr, "\n\rBase64 Fatal Error: Illegal character found : '%c' [%d] - No Base64 legal character!!\n\r", ch, ch );
  exit(1);
}
P.S. Надо, надо инварианты учить!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 27 Август, 2009 18:21 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2316
Откуда: Россия, Томск
Евгений Темиргалеев писал(а):
Как пользоваться такой библиотекой? Поставлять ей только корректные данные или исправить ошибку и потерять гарантию? :lol: (This module present "AS IS", absolutely no warranty, if anybody modyfied this source.)
Выходит, что на немодифицированный код есть гарантия? Заставить автора выполнять гарантийные обязательства! : )
Если гарантии и так нет, исправить самому.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 27 Август, 2009 20:24 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4526
Откуда: Россия, Орёл
Комментарий сильно порадовал, учитывая, что на некорректных данных библиотека не тестировалась... или просто на ошибку забили... Интересно, это профессиональный программист Си++ писал или любитель?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 27 Август, 2009 20:26 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Евгений Темиргалеев писал(а):
Как пользоваться такой библиотекой? Поставлять ей только корректные данные или исправить ошибку и потерять гарантию? :lol: (This module present "AS IS", absolutely no warranty, if anybody modyfied this source.)

Как вариант, сделайте свою обёртку для этой библиотеки и в ней проверяйте корректность данных, а саму эту библиотеку не трогайте, если уж она работает при корректных данных...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 27 Август, 2009 20:28 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Евгений Темиргалеев писал(а):
Интересно, это профессиональный программист Си++ писал или любитель?
Извините, а где Вы там увидели хоть одну строку на С++? Чистейший Си, никаких плюсов...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 27 Август, 2009 20:29 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4526
Откуда: Россия, Орёл
В названии файла (base64.cpp) и в Makefile (компилируется g++)... И Вы бы лучше ошибку поискали :)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 27 Август, 2009 20:35 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Вы его случайно не отсюда взяли?
Похоже, это какой-то древний сишный код. который без изменений вставили в более современный С++сный проект, ну и переименовали расширение на .cpp... :lol:


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 28 Август, 2009 10:20 
Аватара пользователя

Зарегистрирован: Суббота, 06 Декабрь, 2008 22:59
Сообщения: 246
Откуда: Волгоградская обл.
Цитата:
Почему декодирование некорректной Base64-строки "не работает".


А в чём заключается некорректность строки?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 28 Август, 2009 11:20 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4526
Откуда: Россия, Орёл
Наличие символов кроме A—Z, a—z, 0—9, «+» и «/».

http://ru.wikipedia.org/wiki/Base64


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 29 Август, 2009 16:44 
Аватара пользователя

Зарегистрирован: Суббота, 06 Декабрь, 2008 22:59
Сообщения: 246
Откуда: Волгоградская обл.
Евгений Темиргалеев писал(а):
Наличие символов кроме A—Z, a—z, 0—9, «+» и «/».

http://ru.wikipedia.org/wiki/Base64


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


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB