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 );

}


 

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

81960. Единица величины, основной принцип измерения, результат измерения 90.58 KB
  Таким образом получение информации о значениях физической величины как некоего числа принятых для нее единиц и есть главная задача измерений. А вторые неаддитивные величины прямо не измеряются так как они преобразуются в непосредственное измерение величины или измерение путем косвенных измерений.
81961. Рыцари периода сервантесовской Испании. Пародийность рыцарского романа «Хитроумный идальго Дон Кихот Ламанчский» 45.12 KB
  Роман по своей форме является пародией на рыцарские романы, очень популярные в то время. Роман, состоит из двух частей, при всем единстве фабулы существенно отличающихся друг от друга. Однако основным моментом содержания является описание окружающего общества, социальной несправедливости, и все это в форме рыцарского романа.
81962. Системы и методы инвестиционного анализа 62 KB
  В соответствии с предлагаемой схемой проведения инвестиционного анализа или анализа инвестиционной привлекательности региона или других объектов по нашему мнению следует использовать различные экономико-математические статистические и другие методы.
81963. Экономическая диагностика предприятия 1.33 MB
  Цель экономической диагностики предприятия – оценка финансового состояния и динамики развития хозяйствующего субъекта. Экспресс диагностику рекомендуется осуществить методом оценки финансовых коэффициентов.
81964. Основы системы социальной защиты населения в России. Структура социальной защиты населения на примере Туринского района 43 KB
  Сложившаяся ситуация требует от государства и неправительственных организаций общественных объединений принятия адекватных мер прежде всего в сфере развития системы социальной защиты населения и обеспечения социальной безопасности.
81965. ПРЕС-КОНФЕРЕНЦІЯ «ВОДА – НАЙВАЖЛИВІШИЙ МІНЕРАЛ» 1.29 MB
  Мета: Розширити і збагатити знання учнів про воду, дати уявлення про значення води на планеті Земля, закріпити знання про властивості води та її народногосподарське призначення, в тому числі в рідному краї. Виховувати в учнів бережне ставлення до води та бажання зберегти запаси прісної води чистими для себе і майбутніх поколінь.
81966. Вода. Кругообіг води 248 KB
  Мета: На основі вивченого матеріалу систематизувати знання учнів про властивості води, стани води, кругообіг води, значення води в природі і для людей; формувати вміння застосовувати засвоєні знання. Розвивати вміння аналізувати природні явища, робити висновки.
81967. Земля – голуба планета. Водойми України 59.5 KB
  Повторити і розширити поняття про водойми України їх різноманітність джерело річка її будова складові частини; озеро болото море значення та охорону; продовжувати формувати вміння учнів працювати з фізичною картою зошитом підручником; розвивати уміння логічно мислити працювати у групі...
81968. Практичне заняття «Вогонь – друг, вогонь – ворог» 69 KB
  Мета: продовжити формувати уявлення про причини виникнення пожежі в побуті та її наслідки; вчити учнів правильно діяти у випадку виникнен ня пожежі в сусідів чи на інших об’єктах; розвивати навички самозахисту; виховувати розсудливість, почуття відповідальності за свої вчинки.