541

Base64 кодирование

Курсовая

Информатика, кибернетика и программирование

Base64 - это схема кодирования символьной строки любого набора байт в последовательность только печатных ASCII символов. Программа, осуществляющая Base64 кодирование/декодирование.

Русский

2013-01-06

81.5 KB

43 чел.

Министерство образования и науки РФ

Государственное образовательное учреждение высшего профессионального образования

Ивановский государственный энергетический университет имени В.И.Ленина

Кафедра программного обеспечения компьютерных систем

ОТЧЕТ

по курсовой работе

по курсу «Структуры и алгоритмы обработки данных»

Base64 кодирование

Выполнил:

студент группы 3-42хх Чуенков И.Е.

Проверил:

Второв А.В.

Иваново 2011

Оглавление

1. Задание 3

2. Теоретическая часть 4

3. Код программы 5


1. Задание

Написать программу, осуществляющую Base64 кодирование/декодирование.


2. Теоретическая часть

Base64 - это схема кодирования символьной строки любого набора байт в последовательность только печатных ASCII символов. Т.е. тех символов, которые легко можно передать по любым каналам связи.

Длина результирующего потока символов будет равна

ИСХОДНАЯ_ДЛИНА * 4 / 3 + 6

А если применяется перенос по строкам, то

ИСХОДНАЯ_ДЛИНА * 4 / 3 + len * 4 / (3 * 72) + 7

В общем случае длина исходно сообщения увеличивается примерно на 30%.

Основное правило кодирования - умышленное сокращение диапазона символов, которые мы имеем на выходе. Но из-за этого надо поступиться частью входной информацией или интерпретировать ее несколько иначе, чем поток байт.

Байт состоит из 8 бит. Если представить входную информацию как цепочку битов, то это будет цепочка длиной N * 8. Разделив эту цепочку на “минибайты” длиной по 6 бит мы получаем следующее:

  •  Минибайт становится больше чем настоящих байт
  •  Каждый минибайт (из 6 бит) можно представить (закодировать) как один из символов английского алфавита.

Действительно. Этих символов уже хватит, т.к. 26 это 64. Нам всего лишь надо отыскать эти 64 символа. В base64 используются символы a..z A..Z 0..9 + / и специальный символ =. Для преобразования нужно разбить поток байт на куски по 6 бит, и каждый кусок будет соответствовать одному из представленных выше символов. И в результате любой поток бит можно преобразовать в печатный вид.

Применение такая схема кодирования нашла в электронной почте. Ведь не секрет, что иногда по почте надо передать какой-нибудь архив, а архив это не простой текст, а бинарные данные. Вот и получается, что немного проиграв в размере мы сможем легко передать этот файл как кусок текста.

Наименьший общий делитель числа 8 и 6 - 24 (3 байта) является и тем самым числом байт на который должна быть выровнена исходная строка, что бы ее можно было кодировать. Если же байт до 3х кратного количества не хватает, то в конце результирующей строки base64 дописывается знак =. Если не хватает 1 байта - один знак =, если двух - два символа ==.

3. Код программы

#include <stdio.h>

#include <stdlib.h>

/*

** Tablica transliacii

*/

static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

/*

** Tablica transliacii dlia decodirovaniia

*/

static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";

/*

** block kodirovaniia

**

** preobrazovaniie 3x 8-bitnix baitov v 4 6-bitnix

*/

void encodeblock( unsigned char in[3], unsigned char out[4], int len )

{

   out[0] = cb64[ in[0] >> 2 ];

   out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];

   out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');

   out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');

}

/*

** kodirovanie

**

** base64 kodirovanie stroki s dobavleniem simvolov = i perexodov

*/

void encode( FILE *infile, FILE *outfile, int linesize )

{

   unsigned char in[3], out[4];

   int i, len, blocksout = 0;

   while( !feof( infile ) ) {

       len = 0;

       for( i = 0; i < 3; i++ ) {

           in[i] = (unsigned char) getc( infile );

           if( !feof( infile ) ) {

               len++;

           }

           else {

               in[i] = 0;

           }

       }

       if( len ) {

           encodeblock( in, out, len );

           for( i = 0; i < 4; i++ ) {

               putc( out[i], outfile );

           }

           blocksout++;

       }

       if( blocksout >= (linesize/4) || feof( infile ) ) {

           if( blocksout ) {

               fprintf( outfile, "\r\n" );

           }

           blocksout = 0;

       }

   }

}

/*

** block dekodirovaniia

**

** preobrazovaniie 4x 6-bitnix minibaitov v 3 8-bitnix baitov

*/

void decodeblock( unsigned char in[4], unsigned char out[3] )

{   

   out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4);

   out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2);

   out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);

}

/*

** dekodirovaniie

**

** dekodirovanie base64 stroki s ydaleniem simvolov = i perexodov

*/

void decode( FILE *infile, FILE *outfile )

{

   unsigned char in[4], out[3], v;

   int i, len;

   while( !feof( infile ) ) {

       for( len = 0, i = 0; i < 4 && !feof( infile ); i++ ) {

           v = 0;

           while( !feof( infile ) && v == 0 ) {

               v = (unsigned char) getc( infile );

               v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);

               if( v ) {

                   v = (unsigned char) ((v == '$') ? 0 : v - 61);

               }

           }

           if( !feof( infile ) ) {

               len++;

               if( v ) {

                   in[ i ] = (unsigned char) (v - 1);

               }

           }

           else {

               in[i] = 0;

           }

       }

       if( len );; {

           decodeblock( in, out );

           for( i = 0; i < len - 1; i++ ) {

               putc( out[i], outfile );

           }

       }

   }

}

/*

** vozvrashiaemie oshibki

**

** Oshibki vozvrashiaemie operacionnoi sisteme.

**

*/

#define B64_SYNTAX_ERROR        1

#define B64_FILE_ERROR          2

#define B64_FILE_IO_ERROR       3

#define B64_ERROR_OUT_CLOSE     4

#define B64_LINE_SIZE_TO_MIN    5

/*

** b64_message

**

** Gryppirovka tekstovix soobshenii.

**

*/

char *b64_message( int errcode )

{

   #define B64_MAX_MESSAGES 6

   char *msgs[ B64_MAX_MESSAGES ] = {

           "b64:000:Nepravilnii kod soobsheniia.",

           "b64:001:Sintakcicheskaia oshibka.",

           "b64:002:Oshibka otkritiia/sozdaniia faila.",

           "b64:003:Oshibka vvoda-vivoda faila.",

           "b64:004:Oshibka zakritiia vixodnogo faila.",

           "b64:004:Ystanovlen minimalnii razmer stroki."

   };

   char *msg = msgs[ 0 ];

   if( errcode > 0 && errcode < B64_MAX_MESSAGES ) {

       msg = msgs[ errcode ];

   }

   return( msg );

}

/*

** b64

**

** mexanizm otkritiia potokov i vizova kodirovaniia/decodirovaniia

*/

int b64( int opt, char *infilename, char *outfilename, int linesize )

{

   FILE *infile;

   int retcode = B64_FILE_ERROR;

   if( !infilename ) {

       infile = stdin;

   }

   else {

       infile = fopen( infilename, "rb" );

   }

   if( !infile ) {

       perror( infilename );

   }

   else {

       FILE *outfile;

       if( !outfilename ) {

           outfile = stdout;

       }

       else {

           outfile = fopen( outfilename, "wb" );

       }

       if( !outfile ) {

           perror( outfilename );

       }

       else {

           if( opt == 'e' ) {

               encode( infile, outfile, linesize );

           }

           else {

               decode( infile, outfile );

           }

           if (ferror( infile ) || ferror( outfile )) {

               retcode = B64_FILE_IO_ERROR;

           }

           else {

                retcode = 0;

           }

           if( outfile != stdout ) {

               if( fclose( outfile ) != 0 ) {

                   perror( b64_message( B64_ERROR_OUT_CLOSE ) );

                   retcode = B64_FILE_IO_ERROR;

               }

           }

       }

       if( infile != stdin ) {

           fclose( infile );

       }

   }

   return( retcode );

}

/*

** rykovodstvo

**

** otobrazheniie poleznoi informacii

*/

void showuse( int morehelp )

{

   {

       printf( "\n" );

       printf( "  b64      (Base64 Kodirovaniie/Dekodirovaniie)                     \n" );

       printf( "  Ispolzovaniie:   b64 -opciia  [ -l num ] [<FileIn> [<FileOut>]]  \n" );

       printf( "  Naznacheniie: Eta programma ocishestvliaiet             \n" );

       printf( "           Base64 Kodirovaniie-Dekodirovaniie.                \n" );

   }

   if( !morehelp ) {

       printf( "           Nazmite -h dlia dopolnitelnoi pomoshi.              \n" );

   }

   else {

       printf( "  Opcii: -e  kodirovaniie v  Base64   -h  Pomosh.       \n" );

       printf( "           -d  dekodirovaniie iz Base64 -?  Pomosh.       \n" );

       printf( "  Primechaniie:    -l  nazmite dlia izmeneniia dlini stroki (ot 72 simvolov)\n" );

       printf( "  Vozvrat: 0 = yspex.  Nenylevoi kod - oshibochnii.        \n" );

       printf( "  Obrazec: b64 -e binfile b64file     <- Kodirovaniie     \n" );

       printf( "           b64 -d b64file binfile     <- Dekodirovaniie   \n" );

       printf( "           b64 -e -l40 infile outfile <- dlina stroki 40  \n" );

   }

}

#define B64_DEF_LINE_SIZE   72

#define B64_MIN_LINE_SIZE    4

#define THIS_OPT(ac, av) (ac > 1 ? av[1][0] == '-' ? av[1][1] : 0 : 0)

/*

** glavnaia fynkciia

**

** analiziryet parametri i vizivaet b64 ili pomosh

*/

int main( int argc, char **argv )

{

   int opt = 0;

   int retcode = 0;

   int linesize = B64_DEF_LINE_SIZE;

   char *infilename = NULL, *outfilename = NULL;

   while( THIS_OPT( argc, argv ) ) {

       switch( THIS_OPT(argc, argv) ) {

           case 'l':

                   linesize = atoi( &(argv[1][2]) );

                   if( linesize < B64_MIN_LINE_SIZE ) {

                       linesize = B64_MIN_LINE_SIZE;

                       printf( "%s\n", b64_message( B64_LINE_SIZE_TO_MIN ) );

                   }

                   break;

           case '?':

           case 'h':

                   opt = 'h';

                   break;

           case 'e':

           case 'd':

                   opt = THIS_OPT(argc, argv);

                   break;

            default:

                   opt = 0;

                   break;

       }

       argv++;

       argc--;

   }

   switch( opt ) {

       case 'e':

       case 'd':

           infilename = argc > 1 ? argv[1] : NULL;

           outfilename = argc > 2 ? argv[2] : NULL;

           retcode = b64( opt, infilename, outfilename, linesize );

           break;

       case 0:

           retcode = B64_SYNTAX_ERROR;

       case 'h':

           showuse( opt );

           break;

   }

   if( retcode ) {

       printf( "%s\n", b64_message( retcode ) );

   }

   return( retcode );

}


 

А также другие работы, которые могут Вас заинтересовать

63459. Основы проектирования систем охраны объектов. Методика определения варианта и тактики охраны 541 KB
  Требования к проекту оборудования объекта ТСОС Методика выбора системы сбора и обработки информации. Технические средства охраны. Состояние физических преград инженерных сооружений имеющих большую стойкость и в связи с этим не блокированных...
63462. Строительство в системе народного хозяйства страны 33.5 KB
  Эффективность капитальных вложений во многом определяется их рациональной структурой. Например технологическая структура капитальных вложений представляет собой соотношение между затратами на производство СМР на приобретение технологического оборудования и прочими затратами.
63464. ОЦЕНКА НАДЕЖНОСТИ КОММЕРЧЕСКОГО БАНКА 281.5 KB
  Сущность цели и задачи оценки надежности деятельности коммерческих банков Деятельность любого функционирующего коммерческого банка требует оценки как отражения достигнутых им результатов.
63465. Региональные и местные налоги 188 KB
  Согласно принципам налогового федерализма все налоги в налоговой системе РФ распределены по 3 уровням в зависимости от компетенции властей в сфере установления и налогов и сборов: федеральные, региональные и местные.
63466. Ресурсные налоговые платежи 103.5 KB
  Налог исчисляется налогоплательщиком отдельно по каждому виду ДПИ по итогам каждого налогового периода Срок уплаты Налог подлежит уплате по месту нахождения каждого участка недр не позднее 25 числа месяца следующего за истекшим налоговым периодом...
63467. Струйная печать 370 KB
  Лишние капли отклоняющая система направляет в систему сбора и рециркуляции чернил чтобы затем использовать их вновь иначе расход красителя сделал бы себестоимость печати дорогой. Так в коммерческих системах печати капли генерируются...