Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Основные правила работы с функциями: примеры и ограничения использования функций в различных языках программирования (Языки программирования высокого уровня)

Содержание:

Введение

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

Объектно-ориентированный язык программирования - язык, построенный на принципах объектно-ориентированного программирования. В основе концепции объектно-ориентированного программирования лежит понятие объекта - некой сущности, которая объединяет в себе поля и методы.

В современных объектно-ориентированных языках используются механизмы: наследование. Создание нового класса объектов путём добавления новых элементов. Некоторые языки позволяют выполнять множественное наследование, то есть объединять в одном классе возможности нескольких других классов; инкапсуляция.

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

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

Объект исследования – языки программирования.

Предмет исследования – основные правила работы с функциями.

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

В соответствии с целью была определена необходимость постановки и решения следующих задач:

– изучить основные сведения о языках программирования;

– описать отличия языков программирования;

– определить объектные средства языков программирования;

– изучить правила работу с функциями в языках программирования;

– разработать программу демонстрации приемов работы с функциями.

Глава 1. Языки программирования высокого уровня

1.1. Основные сведения о языках программирования

Язык программирования C# представляет собой объектно-ориентированный язык программирования, который был разработан в 1998-2001 годах группой инженеров при постоянном руководстве Андерса Хейлсберга в компании Microsoft как язык программирования для выполнения разработки приложений под платформу от корпорации Microsoft .NET Framework и впоследствии был стандартизирован как ECMA-334 и стандарт ISO/IEC 23270.

Объектно-ориентированный язык программирования C# можно отнести к семейству языков программирования которые имеют C-подобный синтаксис, из них его внутренний синтаксис является наиболее приближенным к языку программирования C++ и Java. Язык программирования C# включает полиморфизм, поддерживает механизм статической типизации, перегрузку используемых операторов, атрибуты, свойства, делегаты, итераторы, обобщённые типы и методы, анонимные функции, поддерживающие замыкания, LINQ, различные исключения, комментарии в формате XML [8].

Переняв многое от своих предшественников - языков C++, Pascal, Модула, Smalltalk и, в особенности, Java - С#, опираясь на практику их практического использования, исключает некоторые модели, зарекомендовавшие себя как проблематичные при разработке программных систем, например, C# в отличие от C++ не поддерживает множественное наследование классов.

C# был разработан в качестве языка программирования прикладного уровня для CLR и, который зависит от возможностей самой CLR. Это касается системы использования типов данных языка программирования C#, которая отражает BCL. Отсутствие или присутствие тех или иных особенностей языка программирования диктуется тем, что может ли языковая особенность языка программирования быть транслирована в конструкции CLR.

Таким образом, с развитием CLR от версии 1.1 к версии 2.0 достаточно сильно обогатился и сам язык программирования C#; подобного взаимодействия можно было ожидать и в дальнейших версиях языка программирования (однако, эта закономерность была нарушена с выходом языка C# 3.0, который представляет собой расширение языка, которое не опирается на расширения платформы технологии .NET) [10]. CLR предоставляет языку программирования C#, как и всем другим .NET-ориентированным языкам, большинство возможностей, которых не имеют «классические» языки программирования.

Например, выполнение сборка мусора не была реализована в самом языке программирования C#, а выполняется CLR для программ, которые написаны на языке C# точно так же, как это выполняется для программ на языке VB.NET, J# и др.

Существует несколько реализаций объектно-ориентированного языка программирования C#:

– проект Mono включает в себя реализацию языка программирования C# с открытым исходным кодом;

– проект DotGNU также включает компилятор языка программирования C# с открытым кодом;

– реализация языка программирования C# в виде компилятора csc.exe была включена в состав платформы .NET Framework (включая .NET Micro Framework, .NET Compact Framework);

– в составе проекта Rotor компании Microsoft;

– проект dotNetAnywhere ориентирован на встраиваемые системы, реализация CLR, выполняется поддержку практически всех спецификаций языка программирования C# 2.0 [6].

Таким образом, объектно-ориентированный язык программирования С# имеет множество особенностей, однако он во многом схож с языком программирования Java.

Языковые конструкции языка программирования С++ и С# очень схожи, однако существенные различия можно найти в некоторых деталях. Синтаксис языка программирования С# можно назвать упрощенной версией языка С++, таким образом С#, как и любое упрощение, одновременно несет и позитивный и негативный эффекты для разработки высокопроизводительных программ [1].

Также, необходимо отметить, что более сложный код часто легче пишется и в последующем анализируется, если написан более простым языком. С этой позиции, используя язык программирования С#, меньше шансов допустить ошибку в принципиально сложном коде и больше шансов написать чистый код, обладая теми же ресурсами. Это может быть полезно при решении достаточно сложных, но не требовательных к производительности задач. Однако при этом большее количество «синтетики» в С# делает меньше оценку производительности кода по его «внешнему виду».

1.2. Отличия языков программирования

Языки программирования C# и Java используют в качестве синтаксической основы язык программирования C. В частности, от него были унаследованы без каких-либо серьезных изменений:

– использование синтаксиса описания и последующего использования внутренних переменных и специальных функций (порядок «тип имя», использование специализированных модификаторов, обязательным условием является наличие скобок для всех функций, описания формальных параметров);

– использование обозначений начала и конца блоков разрабатываемого программного кода фигурными скобками;

– использование различных обозначений, ассоциативности и приоритетности основных встроенных операций, к которым можно отнести побитовые операции, логические операции, присвоение, арифметические операции, операции декремента и инкремента, тернарная условная операция «?:»);

– синтаксис всех основных конструкций языка программирования: циклов, встроенных операторов множественного выбора, условного оператора выбора [7].

Механизм работы с динамическими данными и сборка мусора в языке программирования.

В рассматриваемых языках программирования реализована одна схожая модель работы с динамическими данными: динамическое создания различных объектов при помощи специальной конструкции new, среда исполнения выполняет отслеживание наличия внутренних ссылок на них, а сборщик мусора используется для периодического очищения используемой памяти от обработанных объектов, различных ссылок на которые не существует [4].

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

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

В языке программирования Java и в C# есть сильные и слабые ссылки на объекты. Оба языка поддерживают методы-финализаторы. Из-за неопределённости момента удаления объекта финализаторы не могут использоваться для освобождения системных ресурсов, занятых объектом, что вынуждает создавать дополнительные методы для «очистки» объекта и вызывать их явно.

Язык программирования Java позволяет выполнить регистрацию слушателей (listener), которые будут получать определенные информационные сообщения, когда ссылка будет подвергнута операции сборки мусора, что обеспечивает улучшение производительности WeakHashMaps [2].

Язык программирования C# позволяет выполнить отмену использования различных специальных финализаторов для некоторых обрабатываемых объектов специализированным методом GC.SuppressFinalizes(obj) (например, выполнение конструирования запросов SQL на файловом потоке).

Это может понадобиться для выполнения процессов финализации и считается довольно дорогой операцией в процессе непосредственного выполнения сборки мусора. Язык программирования C# в стандартной библиотеке содержит интерфейс IDisposables и специальную конструкцию using, которая гарантирует выполнение своевременного вызова необходимых метода очистки [9].

Очевидным является факт того, что возможности по оптимизации unmanaged кода куда шире, чем возможности по оптимизации managed кода. Таким образом, пиковая производительность кода достижима только в unmanaged исполнении, т.е. в пределе, почти любая задача на С++ может быть решена с меньшими требованиями к ресурсам. Поэтому в тяжелых задачах, которые связаны с обработкой достаточно большого количества оперативных данных, С++ имеет сильные преимущества перед языком программирования С#.

В тоже время необходимо понимать, что при выборе неправильного подхода, на С++ вполне можно написать код, который будет работать медленнее кода на C#, выполняющего туже задачу.

Если говорить о совокупности субъективных «простоты разработки», «красоты кода» и объективной производительности, то используя C# проще написать код, удовлетворяющий этим критериям одновременно. Однако это не значит, что производительный код на С++ обязательно будет страшным или сложным для восприятия, просто при его написании потребуется более «творческий» подход для удовлетворения перечисленных критериев одновременно.

1.3. Объектные средства языков программирования

Объектные средства языков программирования C# и Java можно обозначить по следующим основным характеристикам: инкапсуляция; внутренние классы; методы. Рассмотрим более подробно каждую характеристику.

Инкапсуляция.

В языке программирования Java специальный модификатор protected в описании, помимо выполнения операций доступа из классов-потомков, разрешается доступ из всех классов, которые входят в тот же пакет, что и класс-владелец [5].

В C# для объектов, которые должны быть видны в пределах сборки введён специальный модификатор internal (аналог default в языке программирования Java), а protected позволяет сохранить свой изначальный смысл, который был взят из языка программирования C++ - доступ выполняется только из классов-потомков.

Допускается выполнять некоторую комбинацию методов доступа к членам класса protected и internal в этом случае получается область доступа, которая соответствует типу доступа protected в языке программирования Java.

Внутренние классы.

Оба языка программирования обеспечивают определение класса внутри пользовательского класса. В объектно-ориентированном языке программирования Java внутренние классы могут быть использованы для эмуляции замыканий. Внутренние классы языка программирования Java имеют доступ к нестатическим членам родительского класса, то есть «знают о this».

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

На данном механизме в Java-программе мжет быть выполнена обработка различных событий (событие позволяет сгенерировать вызовы методов, в исходном классе-обработчике который является абстрактным; там, где нужен определенный обработчик для событий, программисты создают экземпляры анонимного локального класса, который является наследником базового класса-обработчика и непосредственно может быть использован) [3].

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

В языке программирования C# есть лямбды и замыкания. Подход C# более напоминает язык программирования C++: внутренние классы в C# могут получить специальный доступ только к статическим членам внешних классов, а для выполнения доступа к нестатическим членам необходимо выполнить явное указание на экземпляр внешнего класса [18]. В тоже время, внутренние локальные классы в языке программирование C# и не поддерживаются.

В языке программирования Java начиная с 8 версии также появились лямбда выражения.

Методы.

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

В языке программирования C# представлены механизмы явной реализации методов интерфейса, что обеспечивает классам реализовывать методы интерфейса отдельно от собственных методов или давать разные реализации одноимённых методов, которые принадлежат различным интерфейсам [12].

В объектно-ориентированном языке программирования Java базовые типы (byte, int, double, float, bool и пр.) могут быть переданы по значению, а для остальных (объектные) по значению может быть передана ссылка на необходимый объект.

В C# запрещено давать методам название, которое совпадает с названием некоторого класса, что позволяет устранить ошибки (в Java программисты могут определять конструктор, который будет на самом деле являться методом).

В языке программирования C# в дополнение к примитивным типам можно передавать по значению структуры (struct), остальные типы могут быть переданы по средствам использования технологии ссылок. В объектно-ориентированном языке программирования C# поддерживается явное описание выполнения передачи необходимых параметров по ссылке с использованием ключевых слов out и ref.

В процессе практического использования оператора out компилятор выполняет необходимые вычислительные операции контроля наличия в программном методе присваивания определенных значений. Использовать их необходимо в процессе непосредственной работы с неуправляемым программным кодом, который это требует (например, Winapi), так как это нарушает основополагающую концепцию объектно-ориентированного программирования.

Язык программирования C# спроектирован в полной пере кросплатформенным, однако его развитие не пошло в этом направлении. Поэтому под управлением операционной системы Windows образовалась достаточно полная .net информационная инфраструктура; на других же вычислительных платформах равноценной инфраструктуры впоследствии не появилось [13].

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

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

И хотя язык программирования С# возможно использовать для построения прикладных программных приложений под не-Windows платформы, проблемы, вызываемые использованием технологии .net в не-Windows окружении, сводят на нет многие преимущества выбора языка программирования C#. Поэтому рекомендовать его для кроссплатформенного использования можно разве что если код на C# уже написан. При этом надо четко понимать, что в перспективе это будет приносить дополнительные затраты на поддержку.

Глава 2. Функции в языках программирования

2.1. Функции в языке программирования С++

Функции представляют собой блоки кода, которые выполняют определенные вычислительные операции. Если возникает необходимость, функция может определять входные параметры, которые позволяют вызывающим объектам выполнять передачу ей аргументы. При возникновении необходимости функции также могут возвращать выходное значение. Функции являются достаточно полезными для инкапсуляции базовых операций в едином блоке, который может быть в последствии многократно использован [10]. В идеальном случае имя такого блока должно четко описывать функциональное назначение функции.

Следующая функция принимает от вызывающего ее объекта два целых числа и возвращает их сумму. Переменные a и b являются параметрами целого типа int.

int summ(int a, int b)

{

return a + b;

}

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

int main()

{

int i = summ(11, 33);

int j = summ(i, 67);

cout << "Значение j составляет " << j << endl;

}

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

Функции, которые определены в области видимости пользовательского класса, называют функциями-членами. В языке программирования C++, в отличие от других языков программирования, функции можно также определять непосредственно в области видимости пространства имен (включая неявное глобальное пространство имен) [15]. Подобные функции принято называть свободными или функциями, которые не являются членами. Такие функции часто используются в стандартной библиотеке языка программирования.

При объявлении функции, как минимум, необходимо указать возвращаемый тип и имя функции, а также задать список параметров (в тоже время список параметров может быть пустым) и, при возникновении необходимости, ключевые слова, которые сообщают дополнительные инструкции компилятору [16]. Определение функции включает в себя код ее непосредственного объявления, а также тело, которое представляет собой весь программный код, который находится между фигурными скобками.

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

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

У функции имеется список параметров, в котором через запятую перечислено необходимое (возможно, нулевое) число типов. Каждому параметру присваивается имя, по которому к нему можно получить доступ в теле функции. В шаблоне функции могут указываться дополнительные типы или значения параметров. Вызывающий объект передает аргументы, представляющие собой конкретные значения, типы которых совместимы со списком параметров.

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

Функция не может возвращать другие функции и встроенные массивы. Однако возможен возврат указателей на эти типы, а также лямбда-выражений, создающих объект-функцию. За исключением этих случаев функция может вернуть значение любого типа, входящего в ее область видимости, а также не возвращать никакого значения [11]. В последнем случае возвращаемый тип – void.

В C++14 можно использовать auto, чтобы дать компилятору команду получения возвращаемого типа из тела функции без использования завершающего возвращаемого типа. Обратите внимание, что auto всегда сводится к возвращению по значению. Используйте auto&&, чтобы дать компилятору команду выведения ссылки.

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

Локальные статические объекты удаляются во время завершения, определенного директивой atexit. Если статический объект не был создан из-за того, что поток кода программы обошел соответствующее объявление, попытка удаления этого объект не предпринимается.

В C++ локальные переменные можно объявлять как статические. Переменная является видимой только в теле функции, однако для всех экземпляров функции существует только одна копия переменной.

2.2. Функции в языке программирования С#

Функция являет собой небольшую подпрограмму. Если просто программа - это решение какой-то прикладной задачи, то функция – это тоже решение, только уже в рамках программы и, соответственно, она выполняет задачу «попроще». Функции позволяют уменьшить размер программы за счет того, что не нужно повторно писать какой-то фрагмент кода - просто необходимо вызвать сколько угодно и где нужно объявленную функцию [20].

Функции в С# также называют методами, которые определяются в классах. Весь программный код пишется в функции main. Функция main является главной функцией приложения и точкой входа программы. Любая функция в С# может быть объявлена только в рамках класса, так как C# - полностью объектно-ориентированный язык программирования (ООП). Объявление пользовательской функции внутри другой функции (например main) недопустимо. Объявление функции имеет следующую структуру:

[модификатор доступа] [тип возвращаемого значения] [имя функции] ([аргументы])

{

// тело функции

}

Модификатор доступа (области видимости) может быть public, private, protected, internal.

Между модификатором и типом может стоять ключевое слово static, что означает, что функция будет статичной. Из статичной функции можно вызывать другие функции, если они тоже статичные. Главная функция main – всегда static, поэтому все представленные функции будут статичными [19].

Функция может возвращать значение или не возвращать. Если функция, например, возвращает целое число, то нужно указать тип int. Если функция не возвращает никакого значения, то для этого необходимо использовать ключевое слово void. Также, необходимо отметить, что функции, которые не возвращают значение, еще называют процедурами.

Называть функции стоит так, чтобы имя отображало суть функции. Для чего можно использовать глаголы или словосочетания с глаголами. Например: GetAges(), Sorts(), SetVisibilitys().

Аргументы – это те данные, которые необходимы для выполнения функции. Аргументы записываются в формате [тип] [идентификатор]. Если аргументов несколько, они отделяются запятой. В тоже время аргументы могут отсутствовать.

Первая строка функции, где указываются тип, имя, аргументы и т.д. называется заголовком функции.

В качестве примера можно описать простую функцию, которая будет заменять в массиве строк указанное имя на другое. Данная функция будет принимать три аргумента: массив строк, имя, которое необходимо заменить и новое имя. Так как функция не будет возвращать значение, указываем тип void перед именем функции.

public static void ReplaceNames(string[] names, string names, string newNames)

{

for (int i=0; i < names.Length; i++)

{

if (names[i] == names)

names[i] = newNames;

}

}

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

Функция написана, и теперь используем ее:

class Program

{

public static void ReplaceNames(string[] names, string names, string newNames)

{

for (int i=0; i < names.Length; i++)

{

if (names[i] == names)

names[i] = newNames;

}

}

static void Main(string[] args)

{

string[] names = { "Sergey", "Maxim", "Andrey", "Oleg", "Andrey", "Ivan", "Sergey" };

ReplaceNames(names, "Andrey", "Nikolay"); // вызов функции. Все строки "Andrey" в массиве будут заменены на "Nikolay"

ReplaceNames(names, "Ivan", "Vladimir");

}

}

После вызова функции два раза в этой программе, массив будет выглядеть так: "Sergey", "Maxim", " Nikolay ", "Oleg", " Nikolay ", " Vladimir ", "Sergey".

Когда встречается оператор return, происходит выход из функции и код ниже (если он есть) выполняться не будет (например, в функцию передан такой аргумент, при котором нет смысла выполнять функцию). Он похож на оператор break, который используется для выхода из циклов. Этот оператор также можно использовать и в функциях, которые не возвращают значение. Оператор return допустимо использовать несколько раз в функции, но этого делать не рекомендуется.

2.3. Функции в языке программирования Java

Функция в языке программирования Java состоит из некоторого набора команд, выполняющиеся при ее непосредственном вызове [14].

Сигнатура функции имеет следующую конструкцию:

ТипВозвращаемогоЗначенияФункцией имяПользовательскойФункции( параметры функции){

тело некоторой функции;

}

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

Имя функции подчиняется таким же правилам, как и имена переменных.

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

Тело функции представляет собой набор команд, выполняемые функцией.

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

В качестве примера можно реализовать функцию, которая будет возводить некоторое число a в степень b:

int pow(int a, int b) {

int result = 1;//переменная в которой будет содержаться результат

for (int i = 0; i < b; i++) { result *= a; } return result;// возвращаем его }

Для того, чтобы возвести числа a в степень b достаточно написать:

int temp = pow(3,4);

Если попытаться вызвать функцию pow из метода с main ничего не получится, необходимо, чтобы модификаторы полностью совпадали. В данном случае необходимо дописать public static вначале разрабатываемой функции:

public class test {

public static int pow(int a, int b) {

int result = 1;

for (int i = 0; i < b; i++) { result *= a; } return result; } public static void main(String[] args) { int temp = pow(3+2,4*1)+5;//использование функций! } }

Как можно заметить использована функция pow внутри выражения. Таким образом, функции можно комбинировать с другими вычислительными операциями.

Компоненты заголовка main:

public static void main(String[] args)

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

Также, в качестве примера можно написать следующую функцию readArray(), которая будет возвращать массив целых чисел, считанный с клавиатуры:

public class test {

public static int[] readArray() {

int[] a;//массив целых чисел

int n;//количество элементов в массиве

Scanner in = new Scanner(System.in);

n = in.nextInt();

a = new int[n];

for(int i = 0; i < n; i++) { a[i] = in.nextInt(); } return a; } public static void main(String[] args) { int[] array = readArray(); } }

Еще можно написать функцию printArray, которая будет распечатывать массив в консоль:

import java.util.Scanner;

public class test {

public static int[] readArray() {

int[] a;//массив целых чисел

int n;//количество элементов в массиве

Scanner in = new Scanner(System.in);

n = in.nextInt();

a = new int[n];

for (int i = 0; i < n; i++) { a[i] = in.nextInt(); } return a; } public static void printArray(int[] a) { for (int i = 0; i < a.length; i++) { System.out.println(a[i]); } } public static void main(String[] args) { int[] array = readArray(); printArray(array); } }

Очевидно, что функция printArray() не должна возвращать никакого значения и должна принимать на вход единственный параметр массив, который следует распечатать.

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

public static int factorial(int n) {

if(n==0)

return 1;

return n*factorial(n-1);

}

После возвращения результата функции, т.е после выполнения операции return остальные команды не выполнятся. Как можно заметить факториал от 0 это 1, а факториал любого другого значения можно посчитать как это число умноженное на факториал предыдущего числа. Например факториал 7 это 7 * факториал 6, а 6 в свою очередь это 6 * факториал 5 и так далее вплоть до 0, а факториал нуля уже известен.

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

Глава 3. Программная разработка

3.1. Характеристика RC4

Алгоритм шифрования RC4 представляет собой широко используемый потоковый шифр, применяемый в протоколах TLS (защита Internet-трафика) и WEP (защита WLAN-сетей). Несмотря на высокую скорость работы и простоту реализации, алгоритм шифрования RC4 обладает некоторыми слабостями, из-за которых в целях информационной безопасности не рекомендуется его использовать. Общая схема алгоритма RC4 представлена на рис. 1.

При некоторых условиях данный шифр является очень уязвимым на взлом. Например, когда не выполняется отброс начальных байтов гаммирующей последовательности или когда используются связанные или неслучайные ключи. Компания Microsoft рекомендует при возможности отключать RC4 [17].

Алгоритм шифрования RC4 позволяет сгенерировать псевдослучайный поток битов, называемый гаммирующей последовательностью или гаммой. Как и в любом другом потоковом шифре, шифрование в RC4 выполняется при помощи использования специализированной операции XOR над открытым текстом и гаммой.

Расшифровка выполняется при помощи операции XOR над шифротекстом и гаммой. Таким образом, самым принципиальным моментом в алгоритме шифрования RC4 является то, каким образом будет генерироваться гамма.

В самую первую очередь пользователь должен создать секретный ключ, длина которого, обычно, должна находиться в пределах от 5 до 32 байт. Затем происходит непосредственная инициализация S-блока (Key-scheduling algorithm).

Рисунок 1 – Общая схема алгоритма RC4

Сначала берётся массив из 256 байтов (S-блок) и последовательно выполняется заполнение целыми числами от 0 до 255. Потом выполняется перемешивание данного массива. Причем, перемешивание зависит только от используемого ключа в том смысле, что результат будет перемешиваться и всегда жёстко детерминирован после выбора ключа.

3.2. Описание алгоритма

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

Дешифрация состоит из регенерации этого ключевого потока и суммирования его с шифрограммой по модулю два, восстанавливая исходный текст.

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

Алгоритм шифрования:

1) Функция генерирует последовательность битов (ki).

2) Затем последовательность битов посредством операции «суммирование по модулю два» (xor) объединяется с открытым текстом (mi). В результате получается шифрограмма (ci): ci=mi+ki.

Алгоритм расшифровки:

1) Повторно создаётся (регенерируется) поток битов ключа (ключевой поток) (ki).

2) Поток битов ключа складывается с шифрограммой (ci) операцией «xor». В силу свойств операции «xor» на выходе получается исходный (не зашифрованный) текст (mi): mi=ci+ki=(mi+ki)+ki

RC4 – фактически класс алгоритмов, определяемых размером его блока. Этот параметр n является размером слова для алгоритма. Обычно, n = 8. Для повышения безопасности необходимо увеличить эту величину. Внутреннее состояние RC4 состоит из массива размером 2n слов и двух счетчиков, каждый размером в одно слово [23]. Массив обозначается как S-бокс. Он всегда содержит перестановку 2n возможных значений слова. Два счетчика обозначены через i и j.

Внутреннее состояние RC4 представляется в виде массива размером 2n и двух счётчиков. Массив известен как S-блок, и далее будет обозначаться как S. Он всегда содержит перестановку 2n возможных значений слова. Два счётчика обозначены через i и j.

Инициализация RC4 состоит из двух частей:

– инициализация S-блока;

– генерация псевдо-случайного слова K.

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

Практическая реализация алгоритма шифрования была выполнена по средствам использования средств языка программирования С++. Для практической реализации алгоритма шифрования RC4 был создан соответствующий класс программный class RC4_CRYPTS{}

class RC4_CRYPTS{

byte LINE[256];

unsigned int i,j;

inline void Swaps(int, int);

public:

byte GetXors();

void Inits(byte *key, int len);

void Crypts(byte *data, int size);

};

Процедура инициализации входного массива данных представлена следующей функцией

void RC4_CRYPTS::Inits(byte *key,int len)

{

if(!len) len=strlen((char*)key);

for(i=0; i<256; i++) LINE[i]=i;

for(i=j=0; i<256; i++) {

j=(j+LINE[i]+key[i%len])&255;

Swaps(i,j);

}

i=j=0;

}

Непосредственная перестановка реализована в виде функции Swaps()

void RC4_CRYPTS::Swaps(int i,int j)

{

byte t=LINE[i]; LINE[i]=LINE[j]; LINE[j]=t;

}

Полный текст разработанной программы представлен в Приложении А. Результат выполнения программы представлен на рис. 2.

Рисунок 2 – Результат выполнения программы

Исходный файл представлен на рис. 3. Зашифрованный файл представлен на рис. 4.

Рисунок 3 – Исходный файл

Рисунок 4 – Зашифрованный файл

Заключение

В процессе выполнения данной работы были получены следующие результаты. Изучены основные сведения о нескольких языках программирования. Язык программирования C# представляет собой объектно-ориентированный язык программирования, который был разработан группой инженеров Microsoft как язык программирования для выполнения разработки приложений под платформу .NET Framework. Объектно-ориентированный язык программирования C# можно отнести к семейству языков программирования которые имеют C-подобный синтаксис, из них его внутренний синтаксис является наиболее приближенным к языку программирования C++ и Java.

Объектные средства языков программирования C# и Java можно обозначить по следующим основным характеристикам: инкапсуляция; внутренние классы; методы. В обоих языках программирования методы могут быть определены через внутренние функции классов. Тело используемого метода может быть расположено внутри описания определенного класса. Также, поддерживаются языками программирования C# и Java абстрактные методы и статические методы.

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

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

Также, была представлена программа демонстрации работы с функциями в языке программирования С++. Алгоритм шифрования RC4 представляет собой широко используемый потоковый шифр, применяемый в протоколах TLS и WEP. Несмотря на высокую скорость работы и простоту реализации, алгоритм шифрования RC4 обладает некоторыми слабостями, из-за которых в целях информационной безопасности не рекомендуется его использовать.

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

  1. Брайан У. Керниган, Роб Пайк. Практика программирования. – И.: «Вильямс», 2015. – 287 с.
  2. Валитов Ш.М. Современные системные технологии в отраслях экономики: Учебное пособие / Ш.М. Валитов, Ю.И. Азимов, В.А. Павлова. - М.: Проспект, 2016. – 504 c.
  3. Васильев А.В. Java. Объектно-ориентированное программирование: Учебное пособие. – СПб.: Питер, 2013. – 400 с.
  4. Венделева М.А. Информационные технологии в управлении.: Учебное пособие для бакалавров / М.А. Венделева, Ю.В. Вертакова. - Люберцы: Юрайт, 2016. – 462 c.
  5. Гаврилов М.В. Информатика и информационные технологии: Учебник / М.В. Гаврилов, В.А. Климов. - Люберцы: Юрайт, 2016. – 383 c.
  6. Городняя Л.В. Парадигмы программирования – 2-е изд. – И.: «НОУ «Интуит», 2016. – 178 с.
  7. Дарков А.В. Информационные технологии: теоретические основы: Учебное пособие / А.В. Дарков, Н.Н. Шапошников. - СПб.: Лань, 2016. – 448 c.
  8. Дейтел Х. М., Дейтел П. Дж.. Как программировать на С: Четвертое издание. Пер. с англ. – М.: ООО «Бином-Пресс», 2010. – 1248 с.
  9. Довек Ж. Введение в теорию языков программирования / Ж. Довек, Ж.-Ж. Леви. - М.: ДМК, 2016. – 134 c.
  10. Информационные технологии: Учебное пособие / Л.Г. Гагарина, Я.О. Теплова, Е.Л. Румянцева и др.; Под ред. Л.Г. Гагариной - М.: ИД ФОРУМ: НИЦ ИНФРА-М, 2015. – 320 c.
  11. Информационные системы и технологии: Научное издание. / Под ред. Ю.Ф. Тельнова. - М.: ЮНИТИ, 2016. – 303 c.
  12. Клейнберг Дж., Е. Тардос. Алгоритмы разработка и применение. Классика Computers Science. – И.: «Питер», 2016. – 800 с.
  13. Комлев Н. Полезное программирование. Уникальное руководство к действию. – И.: «Солон-Пресс», 2016. – 256 с.
  14. Кулямин В.В. Технологии программирования. Компонентный подход / В.В. Кулямин. - М.: Интуит, 2014. – 463 c.
  15. Лафоре Р. Объектно-ориентированное программирование в С++. Классика Computer Science. 4-е изд. – СПб.: Питер, 2013. – 928 с.
  16. Машнин Т.С. Web-сервисы Java. – СПб.: БХВ – Петербург, 2012. – 560 с.
  17. Роганов Е.А. Основы информатики и программирования – 2-е изд. – И.: «НОУ «Интуит», 2016. – 392 с.
  18. Сальникова Л.С. Современные коммуникационные технологии в бизнесе: Учебник / Л.С. Сальникова. - М.: Аспект-Пресс, 2015. – 296 c.
  19. Страуструп Бьярне. Программирование: принципы и практика использования С++, испр. изд.: Пер. с англ. – М.: ООО «И.Д. Вильямс», 2013. – 1248 с.
  20. Тюгашев А.А. Основы программирования. Часть 1. – СПб.: «Университет ИТМО», 2016. –160 с.

Приложения

Приложение А

Исходный код программы

#include "stdafx.h"

#include <iostream>

#include <stdio.h>

#include <string.h>

#include <fstream>

using namespace std;

typedef unsigned char byte;

class RC4_CRYPTS{

byte LINE[256];

unsigned int i,j;

inline void Swaps(int, int);

public:

byte GetXors();

void Inits(byte *key, int len);

void Crypts(byte *data, int size);

};

void RC4_CRYPTS::Inits(byte *key,int len)

{

if(!len) len=strlen((char*)key);

for(i=0; i<256; i++) LINE[i]=i;

for(i=j=0; i<256; i++) {

j=(j+LINE[i]+key[i%len])&255;

Swaps(i,j);

}

i=j=0;

}

byte RC4_CRYPTS::GetXors()

{

i=(i+1)&255; j=(j+LINE[i])&255; Swaps(i,j);

return LINE[(LINE[i]+LINE[j])&255];

}

void RC4_CRYPTS::Swaps(int i,int j)

{

byte t=LINE[i]; LINE[i]=LINE[j]; LINE[j]=t;

}

void RC4_CRYPTS::Crypts(byte *data,int size)

{

int n;

for(n=0; n<size; n++) data[n]^=GetXors();

}

int _tmain(int argc, _TCHAR* argv[])

{

ifstream fin("1.txt"); // открываем файл для чтения исходного текста

ofstream fout("2.txt"); // открываем файл для записи зашифрованного текста

setlocale(LC_ALL,"Russian");

char L[255];

//char L[]={0}; //ввод с консоли

//cout<<"Введите текст для шифрования"<<endl;

//cin.getline(L,256);

fin.getline(L,256); // считываем данные из файла

cout<<"Исходный текст"<<endl;

cout<<L<<endl; // выводим исходный текст

int size = strlen(L);

if(sizeof(byte)!=1) printf("type error\n\a"),getchar();

RC4_CRYPTS RC4_Crypts;

byte data[256];

for(int i = 0; i < 256; i++)

{

data[i] = ((char*)&L)[i];

}

RC4_Crypts.Inits((byte*)"Initskey",0);

RC4_Crypts.Crypts(data,size);

cout<<"Текст зашифрован"<<endl;

cout<<data<<endl; // выводим зашифрованный текст

fout<<data; // записываем зашифрованный текст в файл

fin.close(); // закрываем файлы

fout.close();

system("pause");

return 0;

}

lТема: «Основные правила работы с функциями: примеры и ограничения использования функций в различных языках программирования»

Содержание

Введение 2

Глава 1. Языки программирования высокого уровня 4

1.1. Основные сведения о языках программирования 4

1.2. Отличия языков программирования 6

1.3. Объектные средства языков программирования 9

Глава 2. Функции в языках программирования 14

2.1. Функции в языке программирования С++ 14

2.2. Функции в языке программирования С# 17

2.3. Функции в языке программирования Java 20

Глава 3. Программная разработка 25

3.1. Характеристика RC4 25

3.2. Описание алгоритма 26

3.3. Реализация программы 27

Заключение 31

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

Приложения 34

Введение

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

Объектно-ориентированный язык программирования - язык, построенный на принципах объектно-ориентированного программирования. В основе концепции объектно-ориентированного программирования лежит понятие объекта - некой сущности, которая объединяет в себе поля и методы.

В современных объектно-ориентированных языках используются механизмы: наследование. Создание нового класса объектов путём добавления новых элементов. Некоторые языки позволяют выполнять множественное наследование, то есть объединять в одном классе возможности нескольких других классов; инкапсуляция.

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

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

Объект исследования – языки программирования.

Предмет исследования – основные правила работы с функциями.

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

В соответствии с целью была определена необходимость постановки и решения следующих задач:

– изучить основные сведения о языках программирования;

– описать отличия языков программирования;

– определить объектные средства языков программирования;

– изучить правила работу с функциями в языках программирования;

– разработать программу демонстрации приемов работы с функциями.

Глава 1. Языки программирования высокого уровня

1.1. Основные сведения о языках программирования

Язык программирования C# представляет собой объектно-ориентированный язык программирования, который был разработан в 1998-2001 годах группой инженеров при постоянном руководстве Андерса Хейлсберга в компании Microsoft как язык программирования для выполнения разработки приложений под платформу от корпорации Microsoft .NET Framework и впоследствии был стандартизирован как ECMA-334 и стандарт ISO/IEC 23270.

Объектно-ориентированный язык программирования C# можно отнести к семейству языков программирования которые имеют C-подобный синтаксис, из них его внутренний синтаксис является наиболее приближенным к языку программирования C++ и Java. Язык программирования C# включает полиморфизм, поддерживает механизм статической типизации, перегрузку используемых операторов, атрибуты, свойства, делегаты, итераторы, обобщённые типы и методы, анонимные функции, поддерживающие замыкания, LINQ, различные исключения, комментарии в формате XML [8].

Переняв многое от своих предшественников - языков C++, Pascal, Модула, Smalltalk и, в особенности, Java - С#, опираясь на практику их практического использования, исключает некоторые модели, зарекомендовавшие себя как проблематичные при разработке программных систем, например, C# в отличие от C++ не поддерживает множественное наследование классов.

C# был разработан в качестве языка программирования прикладного уровня для CLR и, который зависит от возможностей самой CLR. Это касается системы использования типов данных языка программирования C#, которая отражает BCL. Отсутствие или присутствие тех или иных особенностей языка программирования диктуется тем, что может ли языковая особенность языка программирования быть транслирована в конструкции CLR.

Таким образом, с развитием CLR от версии 1.1 к версии 2.0 достаточно сильно обогатился и сам язык программирования C#; подобного взаимодействия можно было ожидать и в дальнейших версиях языка программирования (однако, эта закономерность была нарушена с выходом языка C# 3.0, который представляет собой расширение языка, которое не опирается на расширения платформы технологии .NET) [10]. CLR предоставляет языку программирования C#, как и всем другим .NET-ориентированным языкам, большинство возможностей, которых не имеют «классические» языки программирования.

Например, выполнение сборка мусора не была реализована в самом языке программирования C#, а выполняется CLR для программ, которые написаны на языке C# точно так же, как это выполняется для программ на языке VB.NET, J# и др.

Существует несколько реализаций объектно-ориентированного языка программирования C#:

– проект Mono включает в себя реализацию языка программирования C# с открытым исходным кодом;

– проект DotGNU также включает компилятор языка программирования C# с открытым кодом;

– реализация языка программирования C# в виде компилятора csc.exe была включена в состав платформы .NET Framework (включая .NET Micro Framework, .NET Compact Framework);

– в составе проекта Rotor компании Microsoft;

– проект dotNetAnywhere ориентирован на встраиваемые системы, реализация CLR, выполняется поддержку практически всех спецификаций языка программирования C# 2.0 [6].

Таким образом, объектно-ориентированный язык программирования С# имеет множество особенностей, однако он во многом схож с языком программирования Java.

Языковые конструкции языка программирования С++ и С# очень схожи, однако существенные различия можно найти в некоторых деталях. Синтаксис языка программирования С# можно назвать упрощенной версией языка С++, таким образом С#, как и любое упрощение, одновременно несет и позитивный и негативный эффекты для разработки высокопроизводительных программ [1].

Также, необходимо отметить, что более сложный код часто легче пишется и в последующем анализируется, если написан более простым языком. С этой позиции, используя язык программирования С#, меньше шансов допустить ошибку в принципиально сложном коде и больше шансов написать чистый код, обладая теми же ресурсами. Это может быть полезно при решении достаточно сложных, но не требовательных к производительности задач. Однако при этом большее количество «синтетики» в С# делает меньше оценку производительности кода по его «внешнему виду».

1.2. Отличия языков программирования

Языки программирования C# и Java используют в качестве синтаксической основы язык программирования C. В частности, от него были унаследованы без каких-либо серьезных изменений:

– использование синтаксиса описания и последующего использования внутренних переменных и специальных функций (порядок «тип имя», использование специализированных модификаторов, обязательным условием является наличие скобок для всех функций, описания формальных параметров);

– использование обозначений начала и конца блоков разрабатываемого программного кода фигурными скобками;

– использование различных обозначений, ассоциативности и приоритетности основных встроенных операций, к которым можно отнести побитовые операции, логические операции, присвоение, арифметические операции, операции декремента и инкремента, тернарная условная операция «?:»);

– синтаксис всех основных конструкций языка программирования: циклов, встроенных операторов множественного выбора, условного оператора выбора [7].

Механизм работы с динамическими данными и сборка мусора в языке программирования.

В рассматриваемых языках программирования реализована одна схожая модель работы с динамическими данными: динамическое создания различных объектов при помощи специальной конструкции new, среда исполнения выполняет отслеживание наличия внутренних ссылок на них, а сборщик мусора используется для периодического очищения используемой памяти от обработанных объектов, различных ссылок на которые не существует [4].

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

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

В языке программирования Java и в C# есть сильные и слабые ссылки на объекты. Оба языка поддерживают методы-финализаторы. Из-за неопределённости момента удаления объекта финализаторы не могут использоваться для освобождения системных ресурсов, занятых объектом, что вынуждает создавать дополнительные методы для «очистки» объекта и вызывать их явно.

Язык программирования Java позволяет выполнить регистрацию слушателей (listener), которые будут получать определенные информационные сообщения, когда ссылка будет подвергнута операции сборки мусора, что обеспечивает улучшение производительности WeakHashMaps [2].

Язык программирования C# позволяет выполнить отмену использования различных специальных финализаторов для некоторых обрабатываемых объектов специализированным методом GC.SuppressFinalizes(obj) (напр., выполнение конструирования запросов SQL на файловом потоке).

Это может понадобиться для выполнения процессов финализации и считается довольно дорогой операцией в процессе непосредственного выполнения сборки мусора. Язык программирования C# в стандартной библиотеке содержит интерфейс IDisposables и специальную конструкцию using, которая гарантирует выполнение своевременного вызова необходимых метода очистки [9].

Очевидным является факт того, что возможности по оптимизации unmanaged кода куда шире, чем возможности по оптимизации managed кода. Таким образом, пиковая производительность кода достижима только в unmanaged исполнении, т.е. в пределе, почти любая задача на С++ может быть решена с меньшими требованиями к ресурсам. Поэтому в тяжелых задачах, которые связаны с обработкой достаточно большого количества оперативных данных, С++ имеет сильные преимущества перед языком программирования С#.

В тоже время необходимо понимать, что при выборе неправильного подхода, на С++ вполне можно написать код, который будет работать медленнее кода на C#, выполняющего туже задачу.

Если говорить о совокупности субъективных «простоты разработки», «красоты кода» и объективной производительности, то используя C# проще написать код, удовлетворяющий этим критериям одновременно. Однако это не значит, что производительный код на С++ обязательно будет страшным или сложным для восприятия, просто при его написании потребуется более «творческий» подход для удовлетворения перечисленных критериев одновременно.

1.3. Объектные средства языков программирования

Объектные средства языков программирования C# и Java можно обозначить по следующим основным характеристикам: инкапсуляция; внутренние классы; методы. Рассмотрим более подробно каждую характеристику.

Инкапсуляция.

В языке программирования Java специальный модификатор protected в описании, помимо выполнения операций доступа из классов-потомков, разрешается доступ из всех классов, которые входят в тот же пакет, что и класс-владелец [5].

В C# для объектов, которые должны быть видны в пределах сборки введён специальный модификатор internal (аналог default в языке программирования Java), а protected позволяет сохранить свой изначальный смысл, который был взят из языка программирования C++ - доступ выполняется только из классов-потомков.

Допускается выполнять некоторую комбинацию методов доступа к членам класса protected и internal в этом случае получается область доступа, которая соответствует типу доступа protected в языке программирования Java.

Внутренние классы.

Оба языка обеспечивают определение класса внутри пользовательского класса. В языке программирования Java внутренние классы могут быть использованы для эмуляции замыканий. Внутренние классы языка программирования Java имеют доступ к нестатическим членам родительского класса, то есть «знают о this».

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

На данном механизме в Java-программе мжет быть выполнена обработка различных событий (событие позволяет сгенерировать вызовы методов, в исходном классе-обработчике который является абстрактным; там, где нужен определенный обработчик для событий, программисты создают экземпляры анонимного локального класса, который является наследником базового класса-обработчика и непосредственно может быть использован) [3].

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

В языке программирования C# есть лямбды и замыкания. Подход C# более напоминает язык программирования C++: внутренние классы в C# могут получить специальный доступ только к статическим членам внешних классов, а для выполнения доступа к нестатическим членам необходимо выполнить явное указание на экземпляр внешнего класса [18]. В тоже время, внутренние локальные классы в языке программирование C# и не поддерживаются.

В языке программирования Java начиная с 8 версии также появились лямбда выражения.

Методы.

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

В языке программирования C# представлены механизмы явной реализации методов интерфейса, что обеспечивает классам реализовывать методы интерфейса отдельно от собственных методов или давать разные реализации одноимённых методов, которые принадлежат различным интерфейсам [12].

В объектно-ориентированном языке программирования Java базовые типы (byte, int, double, float, bool и пр.) могут быть переданы по значению, а для остальных (объектные) по значению может быть передана ссылка на необходимый объект.

В C# запрещено давать методам название, которое совпадает с названием некоторого класса, что позволяет устранить ошибки (в Java программисты могут определять конструктор, который будет на самом деле являться методом).

В языке программирования C# в дополнение к примитивным типам можно передавать по значению структуры (struct), остальные типы могут быть переданы по средствам использования технологии ссылок. В объектно-ориентированном языке программирования C# поддерживается явное описание выполнения передачи необходимых параметров по ссылке с использованием ключевых слов out и ref.

В процессе практического использования оператора out компилятор выполняет необходимые операции контроля наличия в методе присваивания определенных значений. Использовать их необходимо в процессе непосредственной работы с неуправляемым кодом, который это требует (например, Winapi), так как это нарушает концепцию объектно-ориентированного программирования.

C# спроектирован быть кросплатформенным, однако его развитие не пошло в этом направлении. Поэтому под управлением операционной системы Windows образовалась достаточно полная .net информационная инфраструктура; на других же платформах равноценной инфраструктуры не появилось [13].

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

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

И хотя язык программирования С# возможно использовать для построения приложений под не-Windows платформы, проблемы, вызываемые использованием .net в не-Windows окружении, сводят на нет многие преимущества выбора C#. Поэтому рекомендовать его для кроссплатформенного использования можно разве что если код на C# уже написан. При этом надо четко понимать, что в перспективе это будет приносить дополнительные затраты на поддержку.

Глава 2. Функции в языках программирования

2.1. Функции в языке программирования С++

Функции представляют собой блоки кода, которые выполняют определенные вычислительные операции. Если возникает необходимость, функция может определять входные параметры, которые позволяют вызывающим объектам выполнять передачу ей аргументы. При возникновении необходимости функции также могут возвращать выходное значение. Функции являются достаточно полезными для инкапсуляции базовых операций в едином блоке, который может быть в последствии многократно использован [10]. В идеальном случае имя такого блока должно четко описывать функциональное назначение функции.

Следующая функция принимает от вызывающего ее объекта два целых числа и возвращает их сумму. Переменные a и b являются параметрами целого типа int.

int summ(int a, int b)

{

return a + b;

}

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

int main()

{

int i = summ(11, 33);

int j = summ(i, 67);

cout << "Значение j составляет " << j << endl;

}

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

Функции, которые определены в области видимости пользовательского класса, называют функциями-членами. В языке программирования C++, в отличие от других языков программирования, функции можно также определять непосредственно в области видимости пространства имен (включая неявное глобальное пространство имен) [15]. Подобные функции принято называть свободными или функциями, которые не являются членами. Такие функции часто используются в стандартной библиотеке языка программирования.

При объявлении функции, как минимум, необходимо указать возвращаемый тип и имя функции, а также задать список параметров (в тоже время список параметров может быть пустым) и, при возникновении необходимости, ключевые слова, которые сообщают дополнительные инструкции компилятору [16]. Определение функции включает в себя код ее непосредственного объявления, а также тело, которое представляет собой весь программный код, который находится между фигурными скобками.

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

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

У функции имеется список параметров, в котором через запятую перечислено необходимое (возможно, нулевое) число типов. Каждому параметру присваивается имя, по которому к нему можно получить доступ в теле функции. В шаблоне функции могут указываться дополнительные типы или значения параметров. Вызывающий объект передает аргументы, представляющие собой конкретные значения, типы которых совместимы со списком параметров.

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

Функция не может возвращать другие функции и встроенные массивы. Однако возможен возврат указателей на эти типы, а также лямбда-выражений, создающих объект-функцию. За исключением этих случаев функция может вернуть значение любого типа, входящего в ее область видимости, а также не возвращать никакого значения [11]. В последнем случае возвращаемый тип – void.

В C++14 можно использовать auto, чтобы дать компилятору команду получения возвращаемого типа из тела функции без использования завершающего возвращаемого типа. Обратите внимание, что auto всегда сводится к возвращению по значению. Используйте auto&&, чтобы дать компилятору команду выведения ссылки.

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

Локальные статические объекты удаляются во время завершения, определенного директивой atexit. Если статический объект не был создан из-за того, что поток кода программы обошел соответствующее объявление, попытка удаления этого объект не предпринимается.

В C++ локальные переменные можно объявлять как статические. Переменная является видимой только в теле функции, однако для всех экземпляров функции существует только одна копия переменной.

2.2. Функции в языке программирования С#

Функция являет собой небольшую подпрограмму. Если просто программа - это решение какой-то прикладной задачи, то функция – это тоже решение, только уже в рамках программы и, соответственно, она выполняет задачу «попроще». Функции позволяют уменьшить размер программы за счет того, что не нужно повторно писать какой-то фрагмент кода - просто необходимо вызвать сколько угодно и где нужно объявленную функцию [20].

Функции в С# также называют методами, которые определяются в классах. Весь программный код пишется в функции main. Функция main является главной функцией приложения и точкой входа программы. Любая функция в С# может быть объявлена только в рамках класса, так как C# - полностью объектно-ориентированный язык программирования (ООП). Объявление пользовательской функции внутри другой функции (например main) недопустимо. Объявление функции имеет следующую структуру:

[модификатор доступа] [тип возвращаемого значения] [имя функции] ([аргументы])

{

// тело функции

}

Модификатор доступа (области видимости) может быть public, private, protected, internal.

Между модификатором и типом может стоять ключевое слово static, что означает, что функция будет статичной. Из статичной функции можно вызывать другие функции, если они тоже статичные. Главная функция main – всегда static, поэтому все представленные функции будут статичными [19].

Функция может возвращать значение или не возвращать. Если функция, например, возвращает целое число, то нужно указать тип int. Если функция не возвращает никакого значения, то для этого необходимо использовать ключевое слово void. Также, необходимо отметить, что функции, которые не возвращают значение, еще называют процедурами.

Называть функции стоит так, чтобы имя отображало суть функции. Для чего можно использовать глаголы или словосочетания с глаголами. Например: GetAges(), Sorts(), SetVisibilitys().

Аргументы – это те данные, которые необходимы для выполнения функции. Аргументы записываются в формате [тип] [идентификатор]. Если аргументов несколько, они отделяются запятой. В тоже время аргументы могут отсутствовать.

Первая строка функции, где указываются тип, имя, аргументы и т.д. называется заголовком функции.

В качестве примера можно описать простую функцию, которая будет заменять в массиве строк указанное имя на другое. Данная функция будет принимать три аргумента: массив строк, имя, которое необходимо заменить и новое имя. Так как функция не будет возвращать значение, указываем тип void перед именем функции.

public static void ReplaceNames(string[] names, string names, string newNames)

{

for (int i=0; i < names.Length; i++)

{

if (names[i] == names)

names[i] = newNames;

}

}

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

Функция написана, и теперь используем ее:

class Program

{

public static void ReplaceNames(string[] names, string names, string newNames)

{

for (int i=0; i < names.Length; i++)

{

if (names[i] == names)

names[i] = newNames;

}

}

static void Main(string[] args)

{

string[] names = { "Sergey", "Maxim", "Andrey", "Oleg", "Andrey", "Ivan", "Sergey" };

ReplaceNames(names, "Andrey", "Nikolay"); // вызов функции. Все строки "Andrey" в массиве будут заменены на "Nikolay"

ReplaceNames(names, "Ivan", "Vladimir");

}

}

После вызова функции два раза в этой программе, массив будет выглядеть так: "Sergey", "Maxim", " Nikolay ", "Oleg", " Nikolay ", " Vladimir ", "Sergey".

Когда встречается оператор return, происходит выход из функции и код ниже (если он есть) выполняться не будет (например, в функцию передан такой аргумент, при котором нет смысла выполнять функцию). Он похож на оператор break, который используется для выхода из циклов. Этот оператор также можно использовать и в функциях, которые не возвращают значение. Оператор return допустимо использовать несколько раз в функции, но этого делать не рекомендуется.

2.3. Функции в языке программирования Java

Функция в языке программирования Java состоит из некоторого набора команд, выполняющиеся при ее непосредственном вызове [14].

Сигнатура функции имеет следующую конструкцию:

ТипВозвращаемогоЗначенияФункцией имяПользовательскойФункции( параметры функции){

тело некоторой функции;

}

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

Имя функции подчиняется таким же правилам, как и имена переменных.

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

Тело функции представляет собой набор команд, выполняемые функцией.

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

В качестве примера можно реализовать функцию, которая будет возводить некоторое число a в степень b:

int pow(int a, int b) {

int result = 1;//переменная в которой будет содержаться результат

for (int i = 0; i < b; i++) { result *= a; } return result;// возвращаем его }

Для того, чтобы возвести числа a в степень b достаточно написать:

int temp = pow(3,4);

Если попытаться вызвать функцию pow из метода с main ничего не получится, необходимо, чтобы модификаторы полностью совпадали. В данном случае необходимо дописать public static вначале разрабатываемой функции:

public class test {

public static int pow(int a, int b) {

int result = 1;

for (int i = 0; i < b; i++) { result *= a; } return result; } public static void main(String[] args) { int temp = pow(3+2,4*1)+5;//использование функций! } }

Как можно заметить использована функция pow внутри выражения. Таким образом, функции можно комбинировать с другими вычислительными операциями.

Компоненты заголовка main:

public static void main(String[] args)

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

Также, в качестве примера можно написать следующую функцию readArray(), которая будет возвращать массив целых чисел, считанный с клавиатуры:

public class test {

public static int[] readArray() {

int[] a;//массив целых чисел

int n;//количество элементов в массиве

Scanner in = new Scanner(System.in);

n = in.nextInt();

a = new int[n];

for(int i = 0; i < n; i++) { a[i] = in.nextInt(); } return a; } public static void main(String[] args) { int[] array = readArray(); } }

Еще можно написать функцию printArray, которая будет распечатывать массив в консоль:

import java.util.Scanner;

public class test {

public static int[] readArray() {

int[] a;//массив целых чисел

int n;//количество элементов в массиве

Scanner in = new Scanner(System.in);

n = in.nextInt();

a = new int[n];

for (int i = 0; i < n; i++) { a[i] = in.nextInt(); } return a; } public static void printArray(int[] a) { for (int i = 0; i < a.length; i++) { System.out.println(a[i]); } } public static void main(String[] args) { int[] array = readArray(); printArray(array); } }

Очевидно, что функция printArray() не должна возвращать никакого значения и должна принимать на вход единственный параметр массив, который следует распечатать.

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

public static int factorial(int n) {

if(n==0)

return 1;

return n*factorial(n-1);

}

После возвращения результата функции, т.е после выполнения операции return остальные команды не выполнятся. Как можно заметить факториал от 0 это 1, а факториал любого другого значения можно посчитать как это число умноженное на факториал предыдущего числа. Например факториал 7 это 7 * факториал 6, а 6 в свою очередь это 6 * факториал 5 и так далее вплоть до 0, а факториал нуля уже известен.

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

Глава 3. Программная разработка

3.1. Характеристика RC4

Алгоритм шифрования RC4 представляет собой широко используемый потоковый шифр, применяемый в протоколах TLS (защита Internet-трафика) и WEP (защита WLAN-сетей). Несмотря на высокую скорость работы и простоту реализации, алгоритм шифрования RC4 обладает некоторыми слабостями, из-за которых в целях информационной безопасности не рекомендуется его использовать. Общая схема алгоритма RC4 представлена на рис. 1.

При некоторых условиях данный шифр является очень уязвимым на взлом. Например, когда не выполняется отброс начальных байтов гаммирующей последовательности или когда используются связанные или неслучайные ключи. Компания Microsoft рекомендует при возможности отключать RC4 [17].

Алгоритм шифрования RC4 позволяет сгенерировать псевдослучайный поток битов, называемый гаммирующей последовательностью или гаммой. Как и в любом другом потоковом шифре, шифрование в RC4 выполняется при помощи использования специализированной операции XOR над открытым текстом и гаммой.

Расшифровка выполняется при помощи операции XOR над шифротекстом и гаммой. Таким образом, самым принципиальным моментом в алгоритме шифрования RC4 является то, каким образом будет генерироваться гамма.

В самую первую очередь пользователь должен создать секретный ключ, длина которого, обычно, должна находиться в пределах от 5 до 32 байт. Затем происходит непосредственная инициализация S-блока (Key-scheduling algorithm).

Рисунок 1 – Общая схема алгоритма RC4

Сначала берётся массив из 256 байтов (S-блок) и последовательно выполняется заполнение целыми числами от 0 до 255. Потом выполняется перемешивание данного массива. Причем, перемешивание зависит только от используемого ключа в том смысле, что результат будет перемешиваться и всегда жёстко детерминирован после выбора ключа.

3.2. Описание алгоритма

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

Дешифрация состоит из регенерации этого ключевого потока и суммирования его с шифрограммой по модулю два, восстанавливая исходный текст.

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

Алгоритм шифрования:

1) Функция генерирует последовательность битов (ki).

2) Затем последовательность битов посредством операции «суммирование по модулю два» (xor) объединяется с открытым текстом (mi). В результате получается шифрограмма (ci): ci=mi+ki.

Алгоритм расшифровки:

1) Повторно создаётся (регенерируется) поток битов ключа (ключевой поток) (ki).

2) Поток битов ключа складывается с шифрограммой (ci) операцией «xor». В силу свойств операции «xor» на выходе получается исходный (не зашифрованный) текст (mi): mi=ci+ki=(mi+ki)+ki

RC4 – фактически класс алгоритмов, определяемых размером его блока. Этот параметр n является размером слова для алгоритма. Обычно, n = 8. Для повышения безопасности необходимо увеличить эту величину. Внутреннее состояние RC4 состоит из массива размером 2n слов и двух счетчиков, каждый размером в одно слово [23]. Массив обозначается как S-бокс. Он всегда содержит перестановку 2n возможных значений слова. Два счетчика обозначены через i и j.

Внутреннее состояние RC4 представляется в виде массива размером 2n и двух счётчиков. Массив известен как S-блок, и далее будет обозначаться как S. Он всегда содержит перестановку 2n возможных значений слова. Два счётчика обозначены через i и j.

Инициализация RC4 состоит из двух частей:

– инициализация S-блока;

– генерация псевдо-случайного слова K.

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

Практическая реализация алгоритма шифрования была выполнена по средствам использования средств языка программирования С++. Для практической реализации алгоритма шифрования RC4 был создан соответствующий класс программный class RC4_CRYPTS{}

class RC4_CRYPTS{

byte LINE[256];

unsigned int i,j;

inline void Swaps(int, int);

public:

byte GetXors();

void Inits(byte *key, int len);

void Crypts(byte *data, int size);

};

Процедура инициализации входного массива данных представлена следующей функцией

void RC4_CRYPTS::Inits(byte *key,int len)

{

if(!len) len=strlen((char*)key);

for(i=0; i<256; i++) LINE[i]=i;

for(i=j=0; i<256; i++) {

j=(j+LINE[i]+key[i%len])&255;

Swaps(i,j);

}

i=j=0;

}

Непосредственная перестановка реализована в виде функции Swaps()

void RC4_CRYPTS::Swaps(int i,int j)

{

byte t=LINE[i]; LINE[i]=LINE[j]; LINE[j]=t;

}

Полный текст разработанной программы представлен в Приложении А.

Результат выполнения программы представлен на рис. 2.

Рисунок 2 – Результат выполнения программы

Исходный файл представлен на рис. 3. Зашифрованный файл представлен на рис. 4.

Рисунок 3 – Исходный файл

Рисунок 4 – Зашифрованный файл

Заключение

В процессе выполнения данной работы были получены следующие результаты. Изучены основные сведения о нескольких языках программирования. Язык программирования C# представляет собой объектно-ориентированный язык программирования, который был разработан группой инженеров Microsoft как язык программирования для выполнения разработки приложений под платформу .NET Framework. Объектно-ориентированный язык программирования C# можно отнести к семейству языков программирования которые имеют C-подобный синтаксис, из них его внутренний синтаксис является наиболее приближенным к языку программирования C++ и Java.

Объектные средства языков программирования C# и Java можно обозначить по следующим основным характеристикам: инкапсуляция; внутренние классы; методы. В обоих языках программирования методы могут быть определены через внутренние функции классов. Тело используемого метода может быть расположено внутри описания определенного класса. Также, поддерживаются языками программирования C# и Java абстрактные методы и статические методы.

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

Также, была представлена программа демонстрации работы с функциями в языке программирования С++.

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

1. Брайан У. Керниган, Роб Пайк. Практика программирования. – И.: «Вильямс», 2015. – 287 с.

2. Валитов Ш.М. Современные системные технологии в отраслях экономики: Учебное пособие / Ш.М. Валитов, Ю.И. Азимов, В.А. Павлова. - М.: Проспект, 2016. – 504 c.

3. Васильев А.В. Java. Объектно-ориентированное программирование: Учебное пособие. – СПб.: Питер, 2013. – 400 с.

4. Венделева М.А. Информационные технологии в управлении.: Учебное пособие для бакалавров / М.А. Венделева, Ю.В. Вертакова. - Люберцы: Юрайт, 2016. – 462 c.

5. Гаврилов М.В. Информатика и информационные технологии: Учебник / М.В. Гаврилов, В.А. Климов. - Люберцы: Юрайт, 2016. – 383 c.

6. Городняя Л.В. Парадигмы программирования – 2-е изд. – И.: «НОУ «Интуит», 2016. – 178 с.

7. Дарков А.В. Информационные технологии: теоретические основы: Учебное пособие / А.В. Дарков, Н.Н. Шапошников. - СПб.: Лань, 2016. – 448 c.

8. Дейтел Х. М., Дейтел П. Дж.. Как программировать на С: Четвертое издание. Пер. с англ. – М.: ООО «Бином-Пресс», 2010. – 1248 с.

9. Довек Ж. Введение в теорию языков программирования / Ж. Довек, Ж.-Ж. Леви. - М.: ДМК, 2016. – 134 c.

10. Информационные технологии: Учебное пособие / Л.Г. Гагарина, Я.О. Теплова, Е.Л. Румянцева и др.; Под ред. Л.Г. Гагариной - М.: ИД ФОРУМ: НИЦ ИНФРА-М, 2015. – 320 c.

11. Информационные системы и технологии: Научное издание. / Под ред. Ю.Ф. Тельнова. - М.: ЮНИТИ, 2016. – 303 c.

12. Клейнберг Дж., Е. Тардос. Алгоритмы разработка и применение. Классика Computers Science. – И.: «Питер», 2016. – 800 с.

13. Комлев Н. Полезное программирование. Уникальное руководство к действию. – И.: «Солон-Пресс», 2016. – 256 с.

14. Кулямин В.В. Технологии программирования. Компонентный подход / В.В. Кулямин. - М.: Интуит, 2014. – 463 c.

15. Лафоре Р. Объектно-ориентированное программирование в С++. Классика Computer Science. 4-е изд. – СПб.: Питер, 2013. – 928 с.

16. Машнин Т.С. Web-сервисы Java. – СПб.: БХВ – Петербург, 2012. – 560 с.

17. Роганов Е.А. Основы информатики и программирования – 2-е изд. – И.: «НОУ «Интуит», 2016. – 392 с.

18. Сальникова Л.С. Современные коммуникационные технологии в бизнесе: Учебник / Л.С. Сальникова. - М.: Аспект-Пресс, 2015. – 296 c.

19. Страуструп Бьярне. Программирование: принципы и практика использования С++, испр. изд.: Пер. с англ. – М.: ООО «И.Д. Вильямс», 2013. – 1248 с.

20. Тюгашев А.А. Основы программирования. Часть 1. – СПб.: «Университет ИТМО», 2016. –160 с.

Приложения

Приложение А

Исходный код программы

#include "stdafx.h"

#include <iostream>

#include <stdio.h>

#include <string.h>

#include <fstream>

using namespace std;

typedef unsigned char byte;

class RC4_CRYPTS{

byte LINE[256];

unsigned int i,j;

inline void Swaps(int, int);

public:

byte GetXors();

void Inits(byte *key, int len);

void Crypts(byte *data, int size);

};

void RC4_CRYPTS::Inits(byte *key,int len)

{

if(!len) len=strlen((char*)key);

for(i=0; i<256; i++) LINE[i]=i;

for(i=j=0; i<256; i++) {

j=(j+LINE[i]+key[i%len])&255;

Swaps(i,j);

}

i=j=0;

}

byte RC4_CRYPTS::GetXors()

{

i=(i+1)&255; j=(j+LINE[i])&255; Swaps(i,j);

return LINE[(LINE[i]+LINE[j])&255];

}

void RC4_CRYPTS::Swaps(int i,int j)

{

byte t=LINE[i]; LINE[i]=LINE[j]; LINE[j]=t;

}

void RC4_CRYPTS::Crypts(byte *data,int size)

{

int n;

for(n=0; n<size; n++) data[n]^=GetXors();

}

int _tmain(int argc, _TCHAR* argv[])

{

ifstream fin("1.txt"); // открываем файл для чтения исходного текста

ofstream fout("2.txt"); // открываем файл для записи зашифрованного текста

setlocale(LC_ALL,"Russian");

char L[255];

//char L[]={0}; //ввод с консоли

//cout<<"Введите текст для шифрования"<<endl;

//cin.getline(L,256);

fin.getline(L,256); // считываем данные из файла

cout<<"Исходный текст"<<endl;

cout<<L<<endl; // выводим исходный текст

int size = strlen(L);

if(sizeof(byte)!=1) printf("type error\n\a"),getchar();

RC4_CRYPTS RC4_Crypts;

byte data[256];

for(int i = 0; i < 256; i++)

{

data[i] = ((char*)&L)[i];

}

RC4_Crypts.Inits((byte*)"Initskey",0);

RC4_Crypts.Crypts(data,size);

cout<<"Текст зашифрован"<<endl;

cout<<data<<endl; // выводим зашифрованный текст

fout<<data; // записываем зашифрованный текст в файл

fin.close(); // закрываем файлы

fout.close();

system("pause");

return 0;

}