- •Аннотация
- •Условия использования
- •Оглавление
- •Содержание
- •Только для взрослых
- •Десять лет спустя
- •Чему нас учат семья и школа?
- •Крошка сын к отцу пришел
- •Азбучные истины
- •Что я могу ещё сказать?
- •Благодарности
- •Детям до 16-ти
- •Глава 1 Путь далек у нас с тобою…
- •Компьютер
- •Компилятор
- •Личный багаж
- •Компьютерная литература
- •В здоровом теле – здоровый дух
- •Вместе весело шагать по просторам!
- •Повторение – мать учения
- •Соглашения
- •Итоги
- •Глава 2 Вместо теории
- •Миф о думающих машинах
- •Загадочные коды
- •Языки программирования и компиляторы
- •Следующий шаг –
- •Итоги
- •Глава 3 Консольный интерфейс
- •Что такое интерфейс?
- •Консольный интерфейс
- •Прикосновение к консольному интерфейсу
- •А почему не «окна»?
- •Итоги
- •Глава 4 Оружие – к бою!
- •Оружейный прилавок
- •Free Pascal
- •Настройка ярлыка
- •Free Pascal
- •Установка справочной системы
- •Обновление версий Free Pascal
- •Итоги
- •Глава 5 Программа номер один
- •Постановка задачи
- •Создание файла
- •Наполнение файла
- •Компиляция
- •Процедура вывода (печати)
- •Запуск программы
- •Итоги
- •Глава 6 Подготовка к следующему штурму
- •Ещё об исходных файлах
- •Управление окном редактора
- •Борьба с ошибками
- •Итоги
- •Глава 7 Развиваем успех
- •Операторы и разделители
- •Программа, стой!
- •Алгоритмы
- •Блок-схемы
- •Итоги
- •Глава 8 Постоянные и переменные
- •Константы
- •Идентификаторы
- •Переменные
- •Ввод и вывод данных
- •Итоги
- •А слабо?
- •Глава 9 Переменные: продолжение знакомства
- •Представьтесь, пожалуйста!
- •Из пустого в порожнее
- •Сцепление строк
- •Инициализация переменных
- •Типизированные константы
- •Итоги
- •А слабо?
- •Глава 10 Условный оператор
- •Стой! Кто идет?
- •Вопрос ребром
- •Пост номер один
- •Неполный условный оператор
- •Пост номер два
- •Итоги
- •А слабо?
- •Глава 11 Операторный блок
- •Операторные скобки
- •Красиво жить не запретишь
- •Комментарии
- •Итоги
- •Глава 12 Цикл с проверкой в конце
- •Подтянем дисциплину
- •Нанимаем репетитора
- •Вежливый часовой
- •Досрочный выход из цикла
- •Итоги
- •Глава 13 Правда и кривда
- •Есть ли жизнь на Марсе?
- •Информация и её мерило
- •Булевы переменные
- •Ввод и вывод булевых данных
- •Логические выражения
- •С высоты птичьего полета
- •Парад логических операций
- •Итоги
- •А слабо?
- •Глава 14 Дважды два – четыре
- •Поможем братьям нашим меньшим
- •Числа и действия с ними
- •Алгоритм экзаменатора
- •Экзаменатор, первый вариант
- •Итоги
- •А слабо?
- •Глава 15 Айда в Монте-Карло!
- •Куда ни глянь – то процедура, то функция!
- •Госпожа удача
- •Итоги
- •А слабо?
- •Глава 16 Делу время, а потехе час
- •Потемкинская лестница
- •Итоги
- •А слабо?
- •Глава 17 И вновь за парту
- •Цикл со счетчиком
- •Итоги
- •Глава 18 Аз, Буки
- •Символьный тип данных
- •Индексация
- •Длина строки
- •Распечатка строки
- •Итоги
- •Глава 19 Процедуры и функции: разделяй и властвуй
- •Снежный ком
- •Описание процедур
- •Процедуры с параметрами
- •Итоги
- •Глава 20 Процедуры: первый опыт
- •Мухи – налево, котлеты – направо!
- •Сверху вниз
- •Первые раны
- •Глобальные и локальные
- •Локально – это разумно!
- •Неподдающаяся строка
- •Итоги
- •Глава 21 Отладка
- •Отладчик
- •Жучки, вылезайте!
- •Ссылка на переменную
- •Итоги
- •Глава 22 О передаче параметров
- •Процедура обмена
- •Замена символов в строке
- •О передаче строк
- •Итоги
- •Глава 23 Функции
- •Объявление функции
- •Пример функции
- •Подсчет символов в строке
- •Возврат строк
- •Когда результат не важен
- •Неявная переменная Result
- •Итоги
- •Глава 24 Криптография
- •Секреты Юлия Цезаря
- •Суть проблемы
- •О кодировании символов
- •Чудесные превращения
- •Шифрование символа
- •Расшифровка символа
- •Итоги
- •А слабо?
- •Глава 25 Текстовые файлы
- •Файлы хорошие и разные
- •Формат текстовых файлов
- •Доступ к текстовым файлам
- •Чтение из файла
- •Последовательный доступ к файлу
- •Самореклама
- •Цикл с проверкой в начале
- •Итоги
- •Глава 26 Я не читатель, — я писатель!
- •Запись в текстовый файл
- •Пример записи в файл
- •Завершение шпионского проекта
- •Итоги
- •А слабо?
- •Глава 27 Дайте кораблю минутный отдых!
- •Ошибка ошибке рознь
- •Фатальные ошибки
- •«Простительные» ошибки
- •Опции компилятора
- •Обработка ошибок ввода-вывода
- •Директивы компилятора
- •Директиву – в студию!
- •Парад директив
- •Итоги
- •А слабо?
- •Глава 28 Редактор и справочная система
- •Небьющиеся окна
- •Буфер обмена
- •Справочная система
- •Итоги
- •Глава 29 Читайте по-новому
- •Полицейская база данных, версия 1
- •Полицейская база данных, версия 2
- •Итоги
- •Глава 30 Журнальная история
- •Статистика знает всё?
- •Строим планы
- •Барабаним по клавишам
- •Первый блин
- •Блин второй
- •Спецификатор ширины поля
- •«Развесные» числа
- •Итоги
- •Глава 31 Финал журнальной истории
- •Буква за буквой
- •Нелишняя предосторожность
- •Достройка программы
- •Испытание
- •Итоги
- •Глава 32 Порядковые типы данных
- •Типы данных: простые и сложные
- •Целое братство
- •Капля, переполняющая чашу
- •Инкремент и декремент
- •Диапазоны
- •Перечисления
- •Порядковые типы
- •Разумный контроль
- •Итоги
- •Глава 33 Вещественные числа
- •Изображение вещественных чисел
- •Вывод вещественных чисел
- •Типы вещественных чисел
- •Сравнение вещественных чисел
- •Типы данных пользователя
- •Совместимость и преобразование типов
- •Размеры переменных и типов данных
- •Итоги
- •Глава 34 Структура программы
- •Управляющие структуры
- •Структура программы
- •Структура процедур и функций
- •Обмен данными с подпрограммами
- •Встроенные процедуры и функции
- •Что дальше?
- •Итоги
- •А слабо?
- •Глава 35 Множества
- •В директорском кабинете
- •Первым делом, первым делом – оцифровка
- •Множества глазами математика
- •Числовые множества
- •Мощность множества, полные и неполные множества
- •Итоги
- •Глава 36 Множества в Паскале
- •Объявление множеств
- •Присвоение значений множествам
- •Операции с множествами
- •Сравнение множеств
- •Проверка на вхождение элемента в множество (операция IN)
- •Решение директорской задачи
- •Итоги
- •А слабо?
- •Глава 37 Ввод и вывод множеств
- •Вывод множества в текстовый файл
- •Ввод множества из текстового файла.
- •Директорская задача, первый вариант
- •Директорская задача, второй вариант
- •Итоги
- •Глава 38 Множества «в бою»
- •Активисты, шаг вперед!
- •Подвиг контрразведчика
- •В тридевятом царстве
- •Решето Эратосфена
- •Мелочь, а приятно
- •Итоги
- •А слабо?
- •Глава 39 Командная игра (массивы)
- •Снежная лавина
- •А где же волшебная палочка?
- •Массивы вокруг нас
- •Объявление массивов
- •Доступ к элементам (индексация)
- •Ввод и вывод массивов
- •Ошибки индексации
- •Итоги
- •Глава 40 Пристрелка на знакомых мишенях
- •Вопрос-ответ – добиваемся гибкости
- •Полицейская база данных – ускоряем поиск
- •Ещё раз о статистике
- •Итоги
- •Глава 41 По порядку, становись!
- •Пиратская справедливость
- •Пузырьковая сортировка
- •Электронная делёжка
- •Возвращение на футбольное поле
- •Итоги
- •Глава 42 Кто ищет, тот всегда найдет
- •Где эта улица, где этот дом?
- •Последовательный поиск
- •Двоичный поиск
- •Исследование двоичного поиска
- •Ах, время, время!
- •Логарифмы? Это просто!
- •Итоги
- •Глава 43 Сортировка по-взрослому
- •«Фермерская» сортировка
- •Быстрая сортировка
- •Процедура быстрой сортировки
- •О рекурсии и стеке
- •Алгоритмы, на старт!
- •Итоги
- •Глава 44 Строки
- •Строка – особый род массива
- •Укороченные строки
- •Операции со строками
- •Подсчет слов в строке
- •Контекстная замена
- •Итоги
- •Глава 45 Очереди и стеки
- •Вовочка в потоке событий
- •Танцевальный кружок
- •Скитания товарного вагона
- •Сортировочная горка
- •Итоги
- •Глава 46 Огромные числа
- •Сколько звезд на небе?
- •Сложение «в столбик» никто не отменял
- •Великая стройка
- •Длинная арифметика
- •Итоги
- •А слабо?
- •Глава 47 Системы счисления
- •Из тьмы веков
- •Число и его изображение
- •Десятичная система
- •Двоичная система
- •Шестнадцатеричная система
- •Другие системы счисления
- •Изображение числа в заданной системе счисления
- •Обратное преобразование
- •Итоги
- •Глава 48 Железная логика
- •Два взгляда на компьютерные «кирпичики»
- •Логические операции в регистрах
- •Сдвиги влево и вправо
- •Итоги
- •Глава 49 Сложные массивы
- •На поклон к Науке
- •Имперское строительство
- •Крестики-нолики
- •Итоги
- •А слабо?
- •Глава 50 Неспортивные рекорды (записи)
- •Кушать подано!
- •Записи
- •Второй тайм
- •Дополнительное время
- •Итоги
- •Глава 51 Указатели в море памяти
- •Погружение в оперативную память
- •«Планировка» памяти
- •Указатели, первое знакомство
- •Объявление указателей
- •Копирование указателей, пустой указатель
- •Сравнение и проверка указателей
- •Разыменование указателей
- •Нетипичный указатель
- •Примеры с указателями
- •Итоги
- •Глава 52 Динамические переменные
- •Аппетит является к обеду
- •Одолжите памяти немножко!
- •Выделение памяти
- •Освобождение памяти
- •Предупреждён – значит, вооружен
- •Итоги
- •Глава 53 Массив указателей
- •Базу данных – в кучу
- •Сортировка массива указателей
- •Итоги
- •А слабо?
- •Глава 54 Односвязные списки
- •Чудесное сочетание
- •Проблема курицы и яйца
- •Вяжем список
- •Распечатка списка
- •Поиск в несортированном списке
- •Сортированные списки
- •Поиск в сортированном списке
- •Итоги
- •Глава 55 Слова, слова, слова…
- •Частотный анализ текста
- •Слово за слово
- •Структура записи
- •Алгоритм
- •А слабо?
- •Глава 56 И снова очереди, и снова стеки…
- •Шутить изволите?
- •Танцуют все!
- •Итоги
- •Глава 57 Графомания
- •Видимое представление графа
- •Внутреннее представление графа
- •Ввод и вывод графа
- •Итоги
- •Глава 58 По графу шагом марш!
- •Империя номер два
- •Структура узла
- •В рассыпную!
- •Аты-баты
- •Итоги
- •Глава 59 Крупные проекты
- •О модулях и разделении труда
- •Модули
- •Дробление модуля – «смертельный» номер
- •Компиляция проекта
- •Инициализация модуля
- •Структура модуля
- •О совпадении имен
- •Сборочный цех
- •Фирменные библиотеки
- •Динамически загружаемые библиотеки (DLL)
- •Итоги
- •Глава 60 Мелкие хитрости
- •Включаемые файлы
- •Условная компиляция
- •Итоги
- •Глава 61 «Кубики» программиста (ООП)
- •Фокус-покус
- •Вместо паяльника
- •На трех китах
- •Инкапсуляция
- •Наследование
- •Приборостроение
- •Гражданское строительство
- •Динамические объекты
- •Полиморфизм
- •Сокрытие полей и методов
- •Итоги
- •Глава 62 Всё только начинается!
- •Крупицы мастерства
- •Программисты, на старт!
- •Приложение А Установка и настройка IDE Borland Pascal
- •Borland Pascal, состав дистрибутива
- •Borland Pascal
- •Установка
- •Организация рабочей папки
- •Создание и настройка ярлыка
- •Пробный запуск
- •Предварительная настройка
- •Русификация консольного окна
- •Turbo Pascal School Pak
- •Приложение Б Консольная программа в среде Delphi
- •Создание пустого консольного приложения
- •Настройка и сохранение консольного приложения
- •Русификация консольного приложения
- •Приложение В Особенности IDE Pascal ABCNet
- •Приложение Ж Директивы управления компиляцией
- •Приложение З Назначение пунктов меню
- •Приложение И Стандартная кодировка символов MS-DOS
- •Приложение К Некоторые встроенные процедуры и функции
- •Приложение М Пример олимпиадной задачи
- •Библиография
Глава 24 Криптография
Говорят, что хороший разведчик стоит целой дивизии. Ещё бы! Ведь лишенный секретов противник почти безоружен. Но вот умолкли пушки, а разведка не спит, — у мирного времени свои тайны: коммерческие и технические секреты. Впрочем, если секретов нет, их можно придумать, — почему бы нам не поиграть в шпионов? Приятно сознавать, что «отмыленное» приятелю письмо никто, кроме вас двоих, не прочтет, — надо лишь зашифровать его. Придумана уйма способов шифрования, есть даже наука об этом — криптография; сейчас и мы коснемся краешка этой премудрости.
Секреты Юлия Цезаря
Римскому полководцу Юлию Цезарю выпали лихие времена: письмо, отправляемое им с гонцом в отдаленный уголок империи, могло стать добычей недругов, — ведь на дорогах было неспокойно. Это надоумило Юлия шифровать свои письма. В чем заключался метод полководца?
Цезарь просто-напросто заменял одни буквы другими путем кругового сдвига алфавита на несколько позиций. На рис. 54 показано превращение букв при сдвиге алфавита на две позиции. Буква «А» становится буквой «В», буква «Б» — буквой «Г» и так далее. Двум последним уготовано превратиться соответственно в буквы «А» и «Б». Такое шифрование превращает письмо в дикую абракадабру!
А Б В Г . . . Э Ю Я
А Б В Г |
. . . |
Э Ю Я А Б |
Рис. 54 – Принцип шифрования Юлия Цезаря
Как расшифровать её? Очень просто — сдвинуть буквы в обратную сторону. Но надо знать количество сдвигов — это число называют ключом шифра (в примере на рисунке ключ шифра равен двум). Разумеется, что ключ шифра и метод шифрования знали лишь двое: получатель письма и сам Юлий Цезарь.
Пойдем и мы вслед римскому полководцу, — создадим программу для зашифровки текстового файла и его расшифровки. Скажу прямо: задача непростая, а потому решать её будем в два этапа. Вначале освоим шифрование отдельной строки, а уж потом замахнемся на файл. Но начнем с шифрования отдельного символа.
154
Глава 24
Криптография
Суть проблемы
Зашифровать строку — значит зашифровать каждый её символ. Будь у нас готовая функция шифрования символа, задача решалась бы вмиг. Так займемся ею и начнем с заголовка. Дадим нашей функции имя Encrypt — «шифровать», она должна принимать исходный символ и возвращать другой, зашифрованный. Значит, заголовок функции может быть таким:
function Encrypt (X: char): char;
Теперь сосредоточимся на теле функции и рассмотрим известные нам приёмы. Один из них состоит в применении каскада условных операторов:
if X=’А’
then Encrypt:=’В’
else if X=’Б’
then Encrypt:=’Г’
else . . .
Насколько удачно это решение? Прикинем количество вложенных операторов в этой лесенке. В русском алфавите 33 буквы, если взять заглавные и строчные, то получится 66. А если надумаем шифровать ещё и латинские буквы, и цифры и знаки препинания, то наберется около двух сотен символов. Такая лесенка условных операторов растянется на несколько этажей!
Не прибегнуть ли к оператору выбора CASE? Тогда тело функции будет намного проще:
case X of
’А’: Encrypt:=’В’;
’Б’: Encrypt:=’Г’;
. . .
end;
Обратите внимание, что метками оператора CASE здесь служат символы, — скоро вы узнаете, почему такое возможно. Этот вариант очевидно лучше первого, хотя две сотни меток — тоже не подарок. Но главное неудобство в ином: при изменении ключа шифра придется переписать все ветви оператора CASE, а это, согласитесь, скучно. Не поискать ли иного решения, простого и гибкого?
О кодировании символов
Первые компьютеры принесли инженерам массу неудобств. Взять хотя бы ввод и вывод данных. Дисплеи, принтеры и звуковые карты — тогда никто не слышал о них! Результат размышлений цифрового мозга высвечивался лампочками
155
Глава 24
Криптография
на инженерной панели ЭВМ, и в эту двоичную цветомузыку был посвящён лишь узкий круг мудрецов. Со временем изобрели простые принтеры, способные печатать лишь цифры, а затем и более совершенные — для печати букв и других символов. Как действуют подобные устройства?
Процессор компьютера, как известно, оперирует с числами. А людям подавай то текст, то картинку. Как связать одно с другим? Здесь инженеры вспомнили об алфавите. Ведь буквы в нём упорядочены, а значит, каждой букве можно сопоставить число; например, букве «А» — 1, «Б» — 2 и так далее. Такое сопоставление называют кодированием, оно и решает проблему представления символов. Намерившись напечатать некоторый символ, компьютер передает его код на принтер, а уж принтер знает, как поступить с этим числом. При вводе с клавиатуры происходит обратное преобразование: нажатие клавиши заставляет клавиатуру отправить в процессор код соответствующего символа.
Итак, символы внутри компьютера кодируются числами. Мы посчитали, что общее количество букв, цифр и других знаков составляет более двухсот. Инженеры не поскупились и отвели для кодирования символов 256 чисел — от 0 до 255 включительно. Почему именно 256, а не 300 или 500?
Дело в том, что в двоичной системе счисления 256 — это круглое число, оно равно двойке в восьмой степени (если вам знакомо слово «байт», то речь о нём). Так был создан алфавит для компьютеров, он включает буквы, цифры, знаки препинания и управляющие символы, — последние выполняют специальные действия с печатающим устройством, например, перевод на следующую строку.
Понятно, что можно придумать несметное количество вариантов кодирования символов. Желая добиться взаимопонимания между техническими устройствами разных изготовителей, инженеры договорились о единой системе кодирования. Теперь она известна под именем ASCII (читается «аски») — American Standard Code for Information Interchange — американский стандартный код для обмена информацией. Со временем этот стандарт стал международным. Ныне в ходу несколько стандартов кодирования, один из них (для MS-DOS) представлен в приложение И.
Все кодируемые символы разбиты на три группы. Первую составляют управляющие символы с кодами от 0 до 31. Их названия пока вам мало о чем скажут, обратите внимание лишь на символы с кодами 10 и 13, — они служат для разбивки текста на строки.
Вторую группу составляют символы с кодами от 32 до 127, — здесь собран весь латинский алфавит, цифры и основные знаки. Коды латинских букв следуют в порядке латинского алфавита, причем разница между кодами одноименных заглавных и строчных букв составляет 32.
Наконец, в третьей группе собраны русские буквы, символы псевдографики (применяются для рисования таблиц) и редко используемые знаки. Коды
156
Глава 24
Криптография
большинства русских букв тоже следуют в порядке русского алфавита, но некоторые выпадают из этой последовательности. К тому же, разница между кодами заглавных и строчных русских букв не всегда составляет 32.
Заметьте также, что символы русского и латинского алфавитов со схожими начертаниями (такие, как «А», «В», «Р») представлены разными кодами!
Чудесные превращения
Итак, символы в компьютере представлены своими кодами, то есть числами. А с числами работать легко: для превращения кода одного символа в код другого надо лишь прибавить либо вычесть некоторое число — шифрующий ключ.
Но как превратить символ в число и наоборот, — число в символ? Ведь это данные разных типов. Паскаль поможет вам своими встроенными функциями. Преобразовать число в символ можно либо функцией CHR, которая изначально присутствовала в языке, либо её современным аналогом по имени CHAR, которым я иногда буду пользоваться в дальнейшем. Обе функции принимают число, а возвращают символ, вот их объявления:
function Chr(arg : integer) : char;
function Char(arg : integer) : char;
Случайно ли, что имя функции CHAR совпадает с именем типа данных? Нет, ведь на самом деле обе эти функции ничего не делают! Они лишь подсказывают компилятору, что число в скобках — это код символа. И всё! С такими «ненастоящими» функциями мы ещё встретимся, их применяют для преобразования типов данных. Вот как можно напечатать нескольких символов с их кодами.
var n: integer; begin
for n:=40 to 50 do Writeln(n,' ', Chr(n))
end.
Для обратного преобразования — символа в число — применяют другую «ненастоящую» функцию по имени ORD (от ORDER — «порядковый номер»). Cейчас компиляторы предлагают и её аналог по имени Byte. Функция действительно возвращает порядковый номер символа в таблице ASCII, вот её заголовок:
function Ord(arg : char) : integer;
Воспользовавшись ею, мы тоже можем напечатать символы с их кодами.
157