Программная реализация утилиты кодирования и декодирования формата BASE 64

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    916,97 Кб
  • Опубликовано:
    2013-09-10
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Программная реализация утилиты кодирования и декодирования формата BASE 64

ФЕДЕРАЛЬНОЕ Государственное АВТОНОМНОЕ образовательное учреждение высшего профессионального образования

БЕЛГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ

(НИУ "БелГУ")

ФАКУЛЬТЕТ КОМПЬЮТЕРНЫХ НАУК И ТЕЛЕКОММУНИКАЦИЙ

КАФЕДРА МАТЕМАТИЧЕСКОГО И ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ

ИНФОРМАЦИОННЫХ СИСТЕМ

Курсовая работа

Программная реализация ультилиты кодирования и декодирования формата BASE 64

студента дневного отделения 2 курса группы 141103

Дихтяренко Александра Анатольевича

Научный руководитель:

доцент В.В. Румбешт

БЕЛГОРОД 2013

Содержание

 

Введение

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

1.1 Что такое кодирования/декодирование формата BASE64, его применение

1.2 Структура BASE64

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

2.1 Алгоритм кодирования/декодирования

2.2 Реализация программы

2.3 Апробация приложения

Заключение

Список используемой литературы

Приложения

Введение

Необходимо разработать утилиту кодирования/декодирования формата BASE64. Разработка ведется в программной среде Linux, используя компилятор gcc. Программа будет писаться на языке С++.

Для того что бы выполнить поставленную задачу необходимо составить план для изучения данной темы и ее реализации, а конкретно:

·        Сбор и изучение материалов по теме кодирования/декодирования формата BASE64;

·        Разобраться с алгоритмом кодирования/декодирования;

·        Реализовать алгоритм, используя полученные знания;

·        Сделать вывод из проведенной работы

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


1.1 Что такое кодирования/декодирование формата BASE64, его применение


Дело в том, что изначально для передачи электронной почты в Интернет использовался только текст (RFC822). Затем, с развитием компьютерных технологий, потребовалась возможность передачи нетекстовой информации: аудио, видео, графических файлов, файлов приложений и т.д. Однако почтовые сервера понимают только текст. Именно поэтому появилась необходимость каким-то образом преобразовать двоичный файл в текстовый для этого и был придуман BASE64. Этот способ используется в спецификации MIME.это стандарт описания заголовков e-mail сообщений. Используя этот стандарт, в одном письме можно отправить сразу несколько различных вложений. Например, можно положить в письмо архив, видео, картинки или другие файлы. И все это отправить получателю. Почтовая программа-получатель, понимающая MIME, достанет из сообщения все, что было переданно.

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

утилита кодирование декодирование программный

Рисунок.1.1 ASCII символы

1.2 Структура BASE64


Так как в BASE64 используется алфавит из 64 символов, то для кодировки нам хватит вместо стандартных 8 байт шесть. При этом изменении, мы можем кодировать любые цифры с помощью нашего алфавита.

Преобразование происходит по принципу:

Берутся три последовательных байта по восемь бит (всего 24 бита), и побитно делятся на четыре 6-ти битных байта (всего 24 бита). Замечу, что используется только 6 битов, а 2 остаются "не использованными"

Схематично такое преобразование можно представить:

Рисунок. 1.2 Преобразование в 6 битный вариант

Так кодируется любая информация, но существует еще один важный момент, дело в том, что не обязательно всегда будет 3 байта, именно по этому отсутствующие байты заменяют символом "=”

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


2.1 Алгоритм кодирования/декодирования


Кодирование Для начала взять 8-ой (старший) бит исходного байта и поместить его в начало 6-ти битового байта. Затем на место 8-го бита исходного байта поместить 7-й бит, а в 6-ти битовом байте первый бит (младший) переместить на место 2-го бита. После такого перемещения освобождается первый (младший) бит 6-ти битного числа. В него и поместим старший (бывший седьмой) бит исходного байта. Затем еще раз пердвинем биты в обоих байтах, после чего повторяем процедуру

Пример:

Рисунок 2.1 Пример

Рассмотрим шаг 1.

Для проверки установки старшего бита исходного 8-ми битного байта наложим на него так называемую "маску". Т.е. применим к нему побитовую операцию AND с числом 128 (10000000).

Рисунок 2.2 Наложение "маски-1"

 

Как видно из приведенной схемы, проверить установку старшего бита совсем несложно. Если результатом операции получается число 128, значит бит установлен, а если в результате получаем 0, значит старший бит не установлен. Далее в зависимости от полученного результата применим к 6-ти битовому байту битовую операцию OR с числом 1, которая в любом случае применения устанавливает первый (младший) байт в 1.

Рисунок 2.3 Наложение "маски-2"

 

Здесь необходимо учитывать то, что перед применением побитовой операции OR с числом 1 младший бит 6-ти битового байта всегда 0. В случае для первых двух шагов потому, что мы сами обнуляем его при инициализации, для последующих шагов, потому что применяем операцию SHR.

Шаг 2.

Сместим первый бит 6-ти битного байта на вторую позицию, одновременно обнуляя его первый бит. Сместим седьмой байт 8-ми битного байта на 8-е (старшее) место.

Повторяем шаги 1 и 2 шесть раз для каждого бита 6-ти битного байта. Одновременно необходимо следить за тем, что если мы обработали восемь бит байта-источника, следует перейти к новому байту. И последнее - если обработаны все три байта-источники, следует выйти из функции кодирования.

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

Декодирование ничем не отличается от кодирования. Делаем тоже самое, только источник и приемник меняются местами. Все операции происходят в обратном порядке: проверяем установку первого бита 6-ти битного байта (маску в этом случае надо накладывать с числом 32 (0010000) и в зависимости от результата устанавливаем (или не устанавливаем) младший байт 8-ми битного байта. Затем делаем побитовый сдвиг влево.

После того как мы разобрали весь алгоритм, стоит подготовиться к реализации программы, для этого изобразим блок схемы:

)        Всего алгоритма целиком см. Рисунок.2.4 Блок-схема №1 (Вся программа в целом)

2)      Алгоритм кодирования см. Рисунок.2.5 Блок-схема №2 (Кодирование)

)        Алгоритм декодирования см. Рисунок.2.6 Блок-схема №3 (Декодирование)

Рисунок 2.4 Блок-схема №1 (Вся программа в целом)

Рисунок 2.5 Блок-схема №2 (Кодирование)

Рисунок 2.6 Блок-схема №3 (Декодирование)

2.2 Реализация программы


Программа реализована таким образом, что состоит из 3 файлов: kyrsov. cpp;

base64. h;

test. cpp.

Начнем по порядку:

kyrsov. cpp (Созданы функции кодирования/декодирования текста)

Любая программа, написанная на языке программирования С++ прежде всего начинается с подключения заголовочных файлов, или, другими словами, с директив препроцессора (include) Директива препроцессора - это, иными словами, сообщение препроцессору. Нам потребуется всего четыре библиотеки для работы нашей программы

Здесь мы используем директиву include, которая через заголовочные файлы подключает к коду программы необходимые библиотеки. Некоторые заголовочные файлы требуют расширения". h”, так как являются более старыми и унаследовали такой стиль подключения от языка-основателя С.

В представленном в приложении к курсовой работе программном коде, имеют место быть следующие строки:

Листинг 1.

#include "base64. h" // Написанный в ручную заголовочный файл (описан класс string)

#include <iostream> // Стандартная директива потокового ввода/вывода

Операции ввода/вывода выполняются с помощью классов istream (потоковый ввод) и ostream (потоковый вывод). Третий класс, iostream, является производным от них и поддерживает двунаправленный ввод/вывод. Для удобства в библиотеке определены три стандартных объекта-потока:

·              cin - объект класса istream, соответствующий стандартному вводу. В общем случае он позволяет читать данные с терминала пользователя;

·              cout - объект класса ostream, соответствующий стандартному выводу. В общем случае он позволяет выводить данные на терминал пользователя;

·              cerr - объект класса ostream, соответствующий стандартному выводу для ошибок. В этот поток мы направляем сообщения об ошибках программы.

Вывод осуществляется, как правило, с помощью перегруженного оператора сдвига влево (<<), а ввод - с помощью оператора сдвига вправо (>>):

Любая программа также должна содержать функции - основную (обязательно) и дополнительные (опционально). В языке С++ содержится два типа функций:

·        Функции возвращающие значение;

·        Функции, не возвращающие значений.

Для начала рассмотрим пример функции, которая не возвращает значений./*имя функции*/ (/*параметры функции*/) // заголовок функции

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

Это был пример дополнительной функции, которая значений не возвращает, так как тип ее данных - void.

Далее мы создаем две функции, для кодирования текста и для декодирования текста: base64_encode и base64_decode соответственно.

Разберем их по отдельности.

Листинг 2.

{ret;i = 0;j = 0;char char_array_3 [3];char char_array_4 [4];

……………}

Здесь мы описываем переменные.

Класс String

Строки - это объекты, которые представляют

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

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

После этого действия, мы циклично модифицируем из 8 битного вида в 6 битный вид нашу строку. Начиная с конца

Листнг 3.(in_len--) {_array_3 [i++] = * (bytes_to_encode++);(i == 3) {_array_4 [0] = (char_array_3 [0] & 0xfc) >> 2;_array_4 [1] = ( (char_array_3 [0] & 0x03) << 4) + ( (char_array_3 [1] & 0xf0) >> 4);_array_4 [2] = ( (char_array_3 [1] & 0x0f) << 2) + ( (char_array_3 [2] & 0xc0) >> 6);_array_4 [3] = char_array_3 [2] & 0x3f;

………………………………}

<< - знак побитового смещения

& - знак побитового "и”

Как рассказано и показано в теории здесь специально используется побитовое умножение для проверки установки старших битов с последующим смещение.

Далее повторяется эта же операция, но при условии наличия еще необработанных байтов.

И в конце если не хватает байтов, тоесть их меньше 3, то мы просто заменяем в комбинации отсутствующие байты на знак "=" b дописываем в строку результат.

Листинг 4( (i++ < 3))+= '=';

}

Вторая функия base64_decode, ведет и состоит аналогично только что описанной, но с измененным порядком действий (в обратном) и поменянными входом и выходом программы местами.

Теперь рассмотрим заголовочный файл base64. h

В нем описан класс стринг

Листинг 6

#include <string> // заголовочный файл подключающий возможности класса string

using namespace std; // подключаемое пространство имен std

string base64_encode (unsigned char const*, unsigned int len); // инициализация функции base64_encodebase64_decode (string const& s); // инициализация функции base64_encode

Теперь рассмотрим файл test. cpp (Файл в котором задается). Так же как и в первом файле используются подключаемые модули:

Стандартная библиотека ввода/вывода <iostream> и заголовочный файл "base64. h"

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

При создании нового консольного приложения в языке программирования С++, автоматически создается таккая строка: int main (int argc, char* argv [])

Это - заголовок главной функции main (), в скобочках которого объявлены параметры argс и argv. Так вот, если программу запускать через командную строку, то существует возможность передать какую-либо информацию этой программе через параметры argc и argv []. Первый имеет тип данных int, и содержит количество параметров, передаваемых в функцию main. Причем argc никогда не меньше 1, даже когда мы не передаем никакой информации, потому как первым параметром считается имя функции. Второй параметр - это массив указателей на строки. Через командную строку можно передать только данные строкового типа и именно через параметр argv [] и передается какая-либо информация.

Рисунок 3.1 Схема обьявлений функциив с++

Листинг 7

int main () {

const string s = "kot begit po doroge i myrchit"; // присваиваем переменной s текст который хотели бы закодировать.

string encoded = base64_encode (reinterpret_cast<const unsigned char*> (s. c_str ()), s. length ());decoded = base64_decode (encoded);<< "encoded: " << encoded << endl;<< "decoded: " << decoded << endl;

return 0;

}

В этом коде мы присваиваем переменным string, то значение которое получил функции из файла kyrsov. cpp, при этов в функции мы передаем аргументы

После этого воспользовавшись командой вывода cout. Показываем результат на экран

И после возврщаем 0, командой return 0

Так же здесь присутствуют функции для работы с строковыми данными

s. c_str ()

s. length ()

Свойство Length возвращает число объектов Char <#"656317.files/image010.gif">

 

Скриншот №2 (Пример работы2)


Так как выполнялся запуск программы на операционной системе Linux, то и компилирование и сборка происходит с помощью консоля.

1 команда. g++ - c kyrsov. cpp test. cpp

Команда благодаря ключу - с создает 2 отдельных объектных файла, заголовочный файл base64. h,разместим в том же каталоге, что и другие файлы, его мы подключили внутри программы.

2 команда. g++ kyrsov. o test. o - o result

Команда собирает вместе 2 объектных файла и создает файл запуск для нашей программы.

команда. /result

Эта команда запускает нашу программу, после чего мы видим результат на наших скриншотах

На апробации выяснилось, что программа рабочая, выводы верны, декодирование и кодирование прошли успешно

Заключение


В ходе данной курсовой работы были изучены различные аспекты языка программирования С++. Так же был разобран алгоритм кодирования декодирования формата BASE64 и после чего реализован.

Апробация прошла успешно, скриншоты это подтверждают.

Для себя же, я улучшил свои знания и владения языком С++. Конкретно, работа с классом типа string и функциями, разобрался в компиляции и сборке программы состоящей из нескольких файлов. Научился создавать собственные заголовочные файлы и включать их в программу.

Могу сделать окончательный вывод, данная курсовая работа повысила мое знания и я лучше стал разбираться в программировании, так же освоил алгоритм кодирования/декодирования формата BASE64.

Список используемой литературы


1.      Холзнер С. Visual C++6: Учебный курс - СПб: Питер, 2001. - 576 с.

2.      Андрей Александреску, Современное проектирование на С++ - СПб.: Вильямс, 2002. - 335с.

.        Брюс Эккель, Философия С++ - К.: Питер, 2004, - 575с.

.        Е.Л. Романов, Практикум по программированию на С++. СПб: БВХ-Петербург, 2004. - 425 с.

.        Страуструп Б. Программирование: принципы и практика использования C++, исправленное издание = Programming: Principles and Practice Using C++. - М.: "Вильямс", 2011. - С.1248. - ISBN 978-5-8459-1705-8

6.      <http://www.cppstudio.com/obuchenie_cpp>

.        Р. Лафоре, Объектно-ориентированное программирование в С++. К.: Питер, 2004, - 920с.

.        <http://brucha.ru/category/spp/>

Приложения

Приложение 1. Программная реализация ультилиты кодирования декодирования формата Base64

 

1)      kyrsov. cpp

#include "base64. h"

#include <iostream>namespace std;

// Использование 64 ьитного алфавита base64const string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// Проверка вводимых значенийinline bool is_base64 (unsigned char c) {(isalnum (c) || (c == '+') || (c == '/'));

}

// Кодирум наш текстbase64_encode (unsigned char const* bytes_to_encode, unsigned int in_len) {ret;i = 0;j = 0;char char_array_3 [3];char char_array_4 [4];

// Запускаем цикл в котором выбираем по 3 байта и модифицируем их, как бы из 8 битного байта в 6 битный байт

while (in_len--) {_array_3 [i++] = * (bytes_to_encode++);(i == 3) {_array_4 [0] = (char_array_3 [0] & 0xfc) >> 2;_array_4 [1] = ( (char_array_3 [0] & 0x03) << 4) + ( (char_array_3 [1] & 0xf0) >> 4);_array_4 [2] = ( (char_array_3 [1] & 0x0f) << 2) + ( (char_array_3 [2] & 0xc0) >> 6);_array_4 [3] = char_array_3 [2] & 0x3f;

// То что получилось запишем в переменную ret

for (i = 0; (i <4); i++)+= base64_chars [char_array_4 [i]]; = 0;

}

}

// Продолжаем, если отправили не пустое сообщение

if (i)

{(j = i; j < 3; j++)

// лобавляем в конце ноль, что бы сделать сишную строку

char_array_3 [j] = '\0';_array_4 [0] = (char_array_3 [0] & 0xfc) >> 2;_array_4 [1] = ( (char_array_3 [0] & 0x03) << 4) + ( (char_array_3 [1] & 0xf0) >> 4);_array_4 [2] = ( (char_array_3 [1] & 0x0f) << 2) + ( (char_array_3 [2] & 0xc0) >> 6);_array_4 [3] = char_array_3 [2] & 0x3f;(j = 0; (j < i + 1); j++)+= base64_chars [char_array_4 [j]];

// Если байтов меньше 3, то вместо них записывается знак "=", сколько отсутствует столько и "="

while ( (i++ < 3))+= '=';

}ret;

}base64_decode (string const& encoded_string) {in_len = encoded_string. size ();i = 0;j = 0;in_ = 0;char char_array_4 [4], char_array_3 [3]; ret;

// берем наш закодированную строку, идем обратном порядке и смотрим наличи пустых байтов

while (in_len - && (encoded_string [in_]! = '=') && is_base64 (encoded_string [in_])) {_array_4 [i++] = encoded_string [in_]; in_++;

// аналогичные действия в обратном порядке

if (i ==4) {

for (i = 0; i <4; i++)_array_4 [i] = base64_chars. find (char_array_4 [i]);_array_3 [0] = (char_array_4 [0] << 2) + ( (char_array_4 [1] & 0x30) >> 4);_array_3 [1] = ( (char_array_4 [1] & 0xf) << 4) + ( (char_array_4 [2] & 0x3c) >> 2);_array_3 [2] = ( (char_array_4 [2] & 0x3) << 6) + char_array_4 [3];(i = 0; (i < 3); i++)+= char_array_3 [i];= 0;

}

}(i) {(j = i; j <4; j++)_array_4 [j] = 0;(j = 0; j <4; j++)_array_4 [j] = base64_chars. find (char_array_4 [j]);_array_3 [0] = (char_array_4 [0] << 2) + ( (char_array_4 [1] & 0x30) >> 4);_array_3 [1] = ( (char_array_4 [1] & 0xf) << 4) + ( (char_array_4 [2] & 0x3c) >> 2);_array_3 [2] = ( (char_array_4 [2] & 0x3) << 6) + char_array_4 [3];(j = 0; (j < i - 1); j++) ret += char_array_3 [j];

}ret;

}

2) base64. h

#include <string>namespace std;base64_encode (unsigned char const*, unsigned int len);base64_decode (string const& s);

) test. cpp

#include "base64. h"

#include <iostream>namespace std;main () {string s = "kot begit po doroge i myrchit";encoded = base64_encode (reinterpret_cast<const unsigned char*> (s. c_str ()), s. length ());decoded = base64_decode (encoded);<< "encoded: " << encoded << endl;<< "decoded: " << decoded << endl; 0;

}

Программная реализация утилиты кодирования декодирования формата Base64


Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!