Язык программирования Си
МИНОБРНАУКИ
РОССИИ
Федеральное
государственное бюджетное образовательное учреждение
высшего
профессионального образования
«САНКТ-ПЕТЕРБУРГСКИЙ
ГОСУДАРСТВЕННЫЙ ЭКОНОМИЧЕСКИЙ УНИВЕРСИТЕТ»
КАФЕДРА
ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМ И ПРОГРАММИРОВАНИЯ
ОТЧЕТ ПО
ЛАБОРАТОРНОЙ РАБОТЕ №1
по
дисциплине: «Информационные технологии»
Выполнил:
Воробьев В.С.
г.
1. Постановка задачи
Цель лабораторной работы: знакомство с
возможностями языка программирования Си и средой разработки приложений в ОС
Linux.
Работа выполняется под ОС Linux
(Kali): <#"787061.files/image001.gif"> по степеням
сходится в
некоторой окрестности точки и притом к самой функции . Если это
имеет место, то
,
т.е. функция есть сумма
ее ряда Тейлора в некоторой окрестности точки , иначе говоря, для любого значения В этом
случае говорят, что функция разлагается в ряд Тейлора по
степеням , сходящийся
к ней.
Выражение формулы Тейлора для
многочлена в
окрестности точки а, где а - это х0:
,
Для функции exp(x), где экспонента -
показательная функция с основанием, равным иррациональному числу e, т. е.
f(x)=ex, P(a)=ea.
Производная первого порядка:
Производная второго порядка:
Производная третьего порядка:
Тогда разложение функции exp(x) в
ряд Тейлора в окрестности точки а следующее:
,
Исходными данными в программе задания 1 будут
значение x (по заданию), принадлежащее интервалу ;
сигма обозначим t; n -
количество слагаемых ряда Тейлора. Найдем х0 как х=х±t/2.
С помощью функции strcmp сравниваем полученный
результат разложения в ряд Тейлора с результатом, полученным встроенной
функцией.
Функция strcmp():
#include strcmp(const char *strl, const char
*str2);
Описание функции. Заголовочный файл: string.h
Описание
Эта функция сравнивает символы двух строк,
string1 и string2. Начиная с первых символов функция strcmp сравнивает
поочередно каждую пару символов, и продолжается это до тех пор, пока не будут
найдены различные символы или не будет достигнут конец строки.
Параметры:Первая сравниваемая Си-строка.Вторая
сравниваемая Си-строка.
Возвращаемое значение
Функция возвращает несколько значений, которые указывают
на отношение строк: Нулевое значение говорит о том, что обе строки равны.
Значение больше нуля указывает на то, что строка string1 больше строки string2,
значение меньше нуля свидетельствует об обратном.
Функция strcmp начинает сравнивать по одному
символу и как только будут найдены первые неодинаковые символы, функция
проанализирует числовые коды этих символов. Чей код окажется больше, та строка
и будет считаться большей.
. XOR - это функция булевой алгебры, носящей
название «исключающее или», данная функция используется для работы с данными
представленными в двоичной системе исчисления. Основным достоинством,
позволяющим использовать эту функцию в шифровальных алгоритмах является ее
обратимость, при отсутствии потери информации.шифрование является самым простым
и одним из самых эффективных (при правильном использовании) алгоритмов.
Как известно из булевой алгебры, операция
логического сложения «» по основанию 2
(или логического исключаещего ИЛИ - XOR, eXclusive OR) имеет следующую
семантику [3, стр.186]:
То есть, операция z = x y
по сути поразрядная (побитовая - результат не зависит от соседних битов). Если
только один из соответствующих битов равен 1, то результат 1. А если оба 0 или
оба 1, то результат 0.
Задача сводится к обеспечению генерации ключа в
соответствии с требованиями выбранного алгоритма. Отечественный ГОСТ 28147/89 -
им официально разрешено шифрование на территории РФ.
Ключ, имеющий размер 256 двоичных ячеек (битов),
представляется как массив из восьми 32-разрядных элементов. Элементы ключа в
порядке, определяемом базовым циклом, используются основным шагом.
Ключ нужно вводить вручную.
Алгоритм ГОСТ 28147-89 имеет четыре режима
работы.
- Режим простой замены принимает на
вход данные, размер которых кратен 64-м битам. Результатом шифрования является
входной текст, преобразованный блоками по 64 бита в случае зашифрования циклом
«32-З», а в случае расшифрования - циклом «32-Р».
- Режим гаммирования принимает на вход
данные любого размера, а также дополнительный 64-разрядный параметр -
синхропосылку. В ходе работы синхропосылка преобразуется в цикле «32-З»,
результат делится на две части. Первая часть складывается по модулю 232 с
постоянным значением 101010116. Если вторая часть равна 232-1, то её значение
не меняется, иначе она складывается по модулю 232-1 с постоянным значением
101010416. Полученное объединением обеих преобразованных частей значение,
называемое гаммой шифра, поступает в цикл «32-З», его результат порязрядно
складывается по модулю 2 с 64-разрядным блоком входных данных. Если последний
меньше 64-х разрядов, то лишние разряды полученного значения отбрасываются.
Полученное значение подаётся на выход. Если ещё имеются входящие данные, то
действие повторяется: составленный из 32-разрядных частей блок преобразуется по
частям и так далее.
- Режим гаммирования с обратной связью
также принимает на вход данные любого размера и синхропосылку. Блок входных
данных поразрядно складывается по модулю 2 с результатом преобразования в цикле
«32-З» синхропосылки. Полученное значение подаётся на выход. Значение
синхропосылки заменяется в случае зашифрования выходным блоком, а в случае расшифрования
- входным, то есть зашифрованным. Если последний блок входящих данных меньше 64
разрядов, то лишние разряды гаммы (выхода цикла «32-З») отбрасываются. Если ещё
имеются входящие данные, то действие повторяется: из результата зашифрования
заменённого значения образуется гамма шифра и т.д.
- Режим выработки имитовставки
принимает на вход данные, размер которых составляет не меньше двух полных
64-разрядных блоков, а возвращает 64-разрядный блок данных, называемый
имитовставкой. Временное 64-разрядное значение устанавливается в 0, далее, пока
имеются входные данные, оно поразрядно складывается по модулю 2 с результатом
выполнения цикла «16-З», на вход которого подаётся блок входных данных. После
окончания входных данных временное значение возвращается как результат.
. Выполненная работа (Исходный текст программ с
комментариями)
Задание 1
Программа на Си.
С комментариями
#include <stdio.h>// Стандартная
библиотека ввода-вывода
#include <math.h> //Стандартная библиотека
математических функций
#include <stdlib.h> //Стандартная биб-ка
для функции rnd()
#include <string.h> //Стандартная биб-ка
для функции strcmp()stepen (float x, int y); //возведение основания х в степень
у
long int fact(int n);// вычисление
факториала
int main(){
x0, i, n; //начальное значение значение х0,
вспомогательная переменная //для цикла, количество слагаемых ряда Тейлора,
Целочисленные переменные float t, s, x, s1; //сигма для интервала от x0-t lj
x0+t, сумма ряда, из //интервала х, число е в степени х0, переменные двойной
точностиmaxVal, minVal; //диапазон для определения значения х*str1, *str2; //
для сравненияr,p; //дробная и целая часть числаdecpnt, sign, ndig; //для
преобразования числа в строкуchar * filename =
"d:\\number.txt";//файл, в который запишем //полученный результат суммы
рядаchar * mode = "w";//режим записи в файл* file;//файловая
переменная("Введите начальное значение x0, сигма t, количество слагаемых в
ряду n:"); // пояснение для следующей
строки("%d%e%d",&x0,&t,&n); //ввели
// найдем х принадлежащее интервалу от х0-t до
х0+t
maxVal=x0+t;=x0-t;
x=rand()%((int)maxVal-(int)minVal+1)+(int)minVal;//вычисление
х генератором случайных чисел
printf("maxVal= %f minVal = %f
x= %f\n", maxVal, minVal,x); //
printf("x0= %d t = %f n= %d\n", x0,
t,n); // Форматный вывод %d или %i - //вывод значения как целого со знаком в
формате DEC;=0; // обнулили сумму ряда=stepen(exp(1),x0); // чтобы не вывызать
функцию для //каждого слагаемого(i=0; i<=n; i++) // открываем цикл для
вычисления суммы ряда+=s1/fact(i)*stepen(x-x0,i); // вычисление очередного
слагаемого //ряда Тейлора по формуле (3) отчета("число е в степени 1
=%g\n",exp(1));// проверяем //полученные результаты("число е в
степени х0 соответственно =%g\n", s1);
printf("сумма
ряда
s=%g\n",s);
printf("Введите точность вычисления");("%d",&ndig);//ввели
// преобразуем число в строку функцией
ecvt=ecvt(s1, ndig, &decpnt, &sign);// s1 в строку из ndig цифр; в
//параметре decpt хранится отрицательное значение;указывает адресный
//указатель sign
str2=ecvt(s, ndig, &decpnt,
&sign);("s1= %s\n, s= %s\n",str1, str2);(strcmp(str1,str2)==0)// сравниваем
числа
функцией
strcmp
printf("Строки идентичны\n");printf
("Строки отличаются\n"); // возвращает отрицательное число, //нуль
или положительное число для s < t, s == t или s > t, соответственно
fclose(file);0; // успешное завершение
}stepen (float x, int y) //возведение числа х в
степень у
{ int i;p;=1;(i=1; i<=y;
i++)=p*x;p;
}int fact(int n)
{if (n<0)// если n меньше 00;// возвращаем
0(n==0)// если n равен 0
return 1;// возращаем
1return n*fact(n-1); // делаем рекурсию
}
Результат выполнения:
Задание 2
#include <stdio.h>// Стандартная
библиотека ввода-вывода
#define N 10stack[N];// для хранения двоичного
представления целой части числаin_stack = 0; // сколько элементов в стеке
dr_arr[N];// массив для хранения двоичного //представления части вещественного
числа после запятой до шифрованияarr[N];// массив для хранения двоичного
представления //мантиссы вещественного числа до шифрованияi_arr;// количество
цифр целой части числа в двоичном
//представленииkey[N]={1,0,1,0,1,0,1,0,1,0};//ключ
шифрованияResult[N];//результат шифрования двоичного //представления мантиссы
вещественного числаResult1[N];//результат шифрования двоичного представления
//части вещественного числа после запятойDecToBin(int n);//перевод из
десятичной в двоичную сс //мантиссы (целой части числа)Dr_DecToBin(float
n);//перевод из десятичной в двоичную сс части //числа после мантиссыstepen
(float x, int y); //возведение основания х в степень уBinToDec(int arr_arr[],
int l);//перевод из двоичной в //десятичную сс мантиссы (целой части
числа)Dr_BinToDec();//перевод из двоичной в десятичную сс части //числа после
мантиссыCode_(int arr_arr[], int l);//объявление функции шифрования main(){x,
x1,i; // Целочисленные переменныеy, y1; // вещественное число и его часть после
мантиссы
int in_arr = 0;// Индекс
массива
arr[10]
int t;//работа НА СЕРВЕРЕ или на клиентеchar *
filename = "d:\\number.txt";//Спецификация файла (т.е. имя //файла и
путь к нему)char * mode = "r";//Способ использования файла r -
открыть //существующий файл для чтения;* file;//Логическое имя - указатель на
требуемый файлchar * filename1 = "d:\\code1.txt";//файл, в который запишем
//полученный результат закодированной целой части суммы рядаchar * filename2 =
"d:\\code2.txt";//файл, в который запишем //полученный результат
закодированной дробной части суммы рядаchar * filename3 =
"d:\\code3.txt";//файл, в который запишем //количество цифр целой
части числа в двоичном представленииchar * mode1 = "w";//режим записи
в файл("Обработка на клиенте - ввести 1, ввести 2 -на сервере: ");
scanf("%d",&t);//ввели
(t)
{1:{=fopen (filename, mode); //открываю файл для
считывания числа, //полученного по формуле ряда Тейлора(fscanf(file,
"%10f", &y)!=EOF) // пока не конец файла считываю //число в
переменную y(file);//закрыли файл= (int)y;//выделили целую часть числа,
мантиссу
printf("Число %f получено при разложении в
ряд Тейлора exp(x) имеет //целую часть =%d\n", y,x); // Форматный вывод
DecToBin(x);//вызов функции перевода целой части
числа в //двоичную СС ("Двоичное представление целой части числа
:");_arr=in_stack;// количество цифр целой части числа в //двоичном
представлении(in_stack > 0){("%d", pop());// чтение из стека
двоичного представления //целой части числа
}
printf("\n");=y-x;//выделение
вещественной части числа("часть после мантиссы
=%f\n",y1);_DecToBin(y1);("Двоичное представление дробной части числа
после мантиссы :"); (in_arr <N){("%d",
dr_arr[in_arr]);//вывод Двоичного представления //вещественной части
числа_arr++;
}
printf("\n");
//шифрование мантиссы
//printf("Зашифрованая целая часть
числа:\n");_(arr,1);//Зашифрованая целая часть числа
// запись результата шифрования в файл=fopen
(filename1, mode1);//открытие файла(i=0;i<i_arr; i++)//цикл для записи целой
части числа в файл
{(file, "%d\n", Result[i]);//запись
целой части числа в файл
}
//fprintf(file, "\n");//перевод
строки(file);//закрытие файла
//шифрование части следующей за мантиссой, т.е.
дробной части числа=fopen (filename2, mode1);//открытие файла на
запись_(dr_arr, 2);//Зашифрованая дробная часть числа
// запись результата шифрования в
файл(i=0;i<10; i++)//цикл для записи дробной части числа в файл
{(file, "%d\n", Result1[i]);//запись
дробной части числа в файл
}(file);//закрытие файла=fopen (filename3,
mode1); //открываю файл для записи количество цифр //целой части числа в
двоичном представлении(file, "%d\n", i_arr);//запись количество цифр
целой части числа в //двоичном представлении(file);//закрытие
файла("запись результата шифрования в файл\n");;
//завершение работы на клиенте
}2:{
//считывание информации на
сервере("считывание из файла закодированного числа\n");
//считывание из файла целой части закодированного
числа
i=0;=fopen (filename1,
mode);(fscanf(file, "%d", &x)!=EOF)
{[i]=x;++;
}(file);
//считывание из файла дробной части
закодированного числа
i=0;=fopen (filename2,
mode);(fscanf(file, "%d", &x)!=EOF)
{[i]=x;++;
}(file);
//считывание из файла количества цифр целой
части числа в двоичном //представлении=0;=fopen (filename3, mode); //открываю
файл для считывания количества //цифр целой части числа в двоичном
представлении
while (fscanf(file, "%d",
&i_arr)!=EOF)
{++;
}(file);("проверка считывания закодированной
целой части числа \n");(i=0;i<i_arr; i++)//вывод на экран
раскодированной целой части числа
{("%d",Result[i]);
}("\n");
printf("проверка считывания закодированной
дробной части числа\n");(i=0;i<10; i++)//вывод на экран раскодированной
целой части числа
{("%d",Result1[i]);
}("\n");
//раскодирование дробной части
числа("раскодирование дробной части
числа:\n");_(Result1,2);(i=0;i<10; i++)//вывод на экран раскодированной
дробной части числа
{("%d",Result1[i]);
}("\n");
//раскодирование целой части("раскодирование
целой части числа:\n");_(Result,1);(i=0;i<i_arr; i++)//вывод на экран
раскодированной целой части числа
{("%d",Result[i]);
}("\n");
//Перевод из двоичной СС в 10-ую СС
printf("Перевод целой части из 2-ого в
10-ое представление %d\n",BinToDec(Result,i_arr));
printf("Перевод части следующей за
мантиссой из 2-ого в 10-ое представление %f\n",Dr_BinToDec(Result1));0; //
успешное завершение
}DecToBin(int n)//перевод из десятичной в
двоичную сс мантиссы (целой части числа)
{ (n >0)
{[in_stack] = n%2;_stack++;(n/2);
}0;
}BinToDec(int arr_arr[], int l)//перевод из
двоичной в десятичную сс //мантиссы (целой части числа)
{ summ=0,i;(i=l;i>=0;i--)
{
summ+=arr_arr[i] * stepen(2,i);
}summ;
/* Снять значение со стека */
int pop(){(in_stack == 0){
printf("Стек пуст, ошибка.\n");
return (-1);
}_stack--;[in_stack]=stack[in_stack];
//printf("%d",arr[in_stack]);stack[in_stack];
}
Dr_DecToBin(float
n)//перевод
вещественной части числа в //двоичную систему счисления
{
int i = 0;((i<10)||(n==0))
{*=2;(n <1)
{_arr[i] = 0;
}
{_arr[i] = 1;
n-=1;
}++;
}0;
}Dr_BinToDec(int arr_arr[])//перевод
вещественной части числа в 10-//ую систему счисления
{ i;summ1=0;(i=0;i<10;i++)
{+=arr_arr[i]/stepen (2,i);
}summ1;
}stepen (float x, int y) //возведение числа х в
степень у
{ int i;p;=1;(i=1; i<=y;
i++)*=x;p;
}Code_(int arr_arr[], int l)
{i;
{(i=0;i<10; i++)
{(l)
{1: //целой части числа
{Result[i]=key[i]^arr_arr[i];
};2: //дробной
части
числа
{Result1[i]=key[i]^arr_arr[i];
};
//#"787061.files/image021.gif">
Выводы
) Результаты, полученные выполнением
программы, говорят о том, что вычисления встроенной функцией и по разложению в
ряд Тейлора идентичны. Т.е. при соблюдении правил преобразования типов
результаты остаются достоверны.
Таким образом, при преобразовании числа с
большей точностью к числу с меньшей (c большей разрядностью к меньшей, длинного
числа к короткому), возможна потеря точности.
При преобразовании от малого к большим, к числу
просто дописываются нули и точность не теряется.
) К достоинствам XOR-шифрования относятся
его простота и «естественность» реализации на ЭВМ, однако этот метод обладает
слабой стойкостью (в случае, если ключи не являются абсолютно случайными).
Интересно, что в свое время данный алгоритм
использовался Microsoft для шифрования содержимого документов в Office 95.
) Вычисления, производимые над вещественными
числами, не точны, т.к. компилятор использует всю память, отведенную для числа,
а не только те цифры, которые получены. Демонстрационный пример ниже.
В строке 5 число, которое надо перевести в
двоичную СС. В строке 8 выводим его значение на экран. Оно отличается от
предыдущего. Поэтому значение, полученное при переводе вещественной части числа
из 2-ой СС в 10-ую отличается. Попытка перевести вещественную часть числа в
строку также этот же результат.
Основная литература
1. Дэвид Гриффитс, Дон Гриффитс
- Head First C / Изучаем программирование на C.
. Учебное пособие Высшая
математика для экономистов Практикум Под редакцией Наума Шевелевича Кремера
. Васильева И.Н.
Информационные технологии и защита информации : учеб. пособие / И.Н. Васильева.
Е.В. Стельмаиюнок - СПб -СПбГИЭУ. 2011.-271 с.
. Шапошникова С. В.
Особенности языка С./ Учебное пособие - Лаборатория юного линуксоида, май 2012
5. http://dfe.petrsu.ru/koi/posob/c/c.htm#g1.2
6. http://www.helloworld.ru/texts/comp/lang/c/c6/index2.htm
. http://citforum.ru/programming/c/dir.shtml