541
Base64 кодирование
Курсовая
Информатика, кибернетика и программирование
Base64 - это схема кодирования символьной строки любого набора байт в последовательность только печатных ASCII символов. Программа, осуществляющая Base64 кодирование/декодирование.
Русский
2013-01-06
81.5 KB
43 чел.
Министерство образования и науки РФ
Государственное образовательное учреждение высшего профессионального образования
Ивановский государственный энергетический университет имени В.И.Ленина
Кафедра программного обеспечения компьютерных систем
ОТЧЕТ
по курсовой работе
по курсу «Структуры и алгоритмы обработки данных»
Base64 кодирование
Выполнил:
студент группы 3-42хх Чуенков И.Е.
Проверил:
Второв А.В.
Иваново 2011
Оглавление
1. Задание 3
2. Теоретическая часть 4
3. Код программы 5
Написать программу, осуществляющую Base64 кодирование/декодирование.
Base64 - это схема кодирования символьной строки любого набора байт в последовательность только печатных ASCII символов. Т.е. тех символов, которые легко можно передать по любым каналам связи.
Длина результирующего потока символов будет равна
ИСХОДНАЯ_ДЛИНА * 4 / 3 + 6
А если применяется перенос по строкам, то
ИСХОДНАЯ_ДЛИНА * 4 / 3 + len * 4 / (3 * 72) + 7
В общем случае длина исходно сообщения увеличивается примерно на 30%.
Основное правило кодирования - умышленное сокращение диапазона символов, которые мы имеем на выходе. Но из-за этого надо поступиться частью входной информацией или интерпретировать ее несколько иначе, чем поток байт.
Байт состоит из 8 бит. Если представить входную информацию как цепочку битов, то это будет цепочка длиной N * 8. Разделив эту цепочку на “минибайты” длиной по 6 бит мы получаем следующее:
Действительно. Этих символов уже хватит, т.к. 26 это 64. Нам всего лишь надо отыскать эти 64 символа. В base64 используются символы a..z A..Z 0..9 + / и специальный символ =. Для преобразования нужно разбить поток байт на куски по 6 бит, и каждый кусок будет соответствовать одному из представленных выше символов. И в результате любой поток бит можно преобразовать в печатный вид.
Применение такая схема кодирования нашла в электронной почте. Ведь не секрет, что иногда по почте надо передать какой-нибудь архив, а архив это не простой текст, а бинарные данные. Вот и получается, что немного проиграв в размере мы сможем легко передать этот файл как кусок текста.
Наименьший общий делитель числа 8 и 6 - 24 (3 байта) является и тем самым числом байт на который должна быть выровнена исходная строка, что бы ее можно было кодировать. Если же байт до 3х кратного количества не хватает, то в конце результирующей строки base64 дописывается знак =. Если не хватает 1 байта - один знак =, если двух - два символа ==.
#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 );
}
А также другие работы, которые могут Вас заинтересовать | |||
62915. | Детская полька | 1.7 MB | |
Цель занятия: Найчить дтей танцевать Детскую польку Задачи занятия: 1 Образовательная: Расширить представление и получить знания о Чешских танцах 2 Развивающая: Способствовать... | |||
62917. | Вода. Властивості, використання | 38.44 KB | |
Мета: вивчити будову молекули води фізичні та хімічні властивості. Зясувати роль води у природі та її значення для живих організмів. Виховувати екологічне мислення бережливе ставлення до використання води відповідальність за свої вчинки... | |||