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

}


 

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

6044. Торгівля людьми в сучасному світі. Конспект уроку 77 KB
  Торгівля людьми в сучасному світі Мета: Проведення виховної години спрямоване на формування уявлень про торгівлю людьми, на розвиток навичок безпечної поведінки, на підвищення правових знань студентів. Ознайомити студентів із різними формами су...
6045. Вивчення несівних конструкцій радіоелектронної апаратури 6.66 MB
  Вивчення несівних конструкцій радіоелектронної апаратури Мета роботи: вивчення типових конструкцій корпусів радіоелектронної апаратури (РЕА) вивчення нормативної документації на несівні конструкції. Функціональна та конструктивна ієрархія РЕA...
6046. Системна папка Панель управления 741.51 KB
  Системна папка Панель управления Мета роботи Придбання навичок роботи з програмами налаштування властивостей операційної системи та апаратного забезпечення. Теоретичні відомості: Системна папка Панель управления...
6047. Определение момента инерции тел методом физического маятника 177.5 KB
  Конечной целью является определение момента инерции тел сложной формы, имеющих удлиненную форму, таких как шатунов двигателей, конструкция которых позволяет уподобить их физическому маятнику.
6048. Захист інформації за допомогою пароля 132 KB
  Захист інформації за допомогою пароля Мета роботи: дослідження захисту з застосуванням пароля, а також дослідження методів протидії атакам на пароль. Теоретична частина 1 Атаки на пароль На сьогоднішній день пароль є найбільш пр...
6049. Сетевые адаптеры. Создание локальной сети 3.3 MB
  Введение Сегодня уже трудно представить себе, как люди жили когда-то без столь удобного и полезного инструмента, как локальные сети. Однако знало человечество и такие времена. Впервые идея связать несколько независимо работающих компьютеров в ед...
6050. Семиотика: возникновение и развитие 168.5 KB
  Семиотика: возникновение и развитие Семиотика Несмотря на формальную институционализацию семиотики (существуют семиотическая ассоциация, журналы, регулярно проводятся конференции и т.д.), статус ее как единой науки до сих пор остается дискуссионным...
6051. Цифрование планово-картографической основы МР Бакалинский район РБ 13.16 MB
  Система автоматизированного проектирования в землеустройстве Целью курсовой работы является углубление теоретических знаний и применение практических навыков по созданию растровых и векторных цифровых карт. Задачи:подготовка исходных...
6052. Вплив розвитку цивілізації на рівень безпеки людини 30.26 KB
  Вступ Безпека життєдіяльності (БЖД) - наука про комфортну та безпечну взаємодію людини з середовищем, в якому вона перебуває. Завданням цієї науки є розробка методів прогнозування, виявлення та ідентифікації шкідливих факторів і вивчення їх впливу...