- •Предисловие
- •Введение
- •1Архитектура эвм
- •1.1 Биты и их хранение
- •1.1.1Вентили и триггеры
- •1.1.2Другие способы хранения битов
- •1.1.3Шестнадцатеричная система счисления
- •1.2 Оперативная память
- •1.2.1Структура памяти
- •1.2.2Измерение емкости памяти
- •1.3 Устройства хранения данных
- •1.3.1Магнитные диски
- •1.3.2Компакт-диски
- •1.3.3Магнитные ленты
- •1.3.4Хранение и поиск файлов
- •1.4 Представление информации в виде двоичного кода
- •1.4.1Представление текста
- •1.4.2Американский национальный институт стандартов
- •1.4.3Iso - международная организация по стандартизации
- •1.4.4Представление числовых значений
- •1.4.5Представление изображений
- •1.4.6Представление звука
- •1.5 Двоичная система счисления
- •1.5.1Альтернатива двоичной системе счисления
- •1.5.2Дроби в двоичной системе счисления
- •1.5.3Аналоговые и цифровые устройства
- •1.6 Хранение целых чисел
- •1.6.1Представление в двоичном дополнительном коде
- •1.6.2Сложение в двоичном дополнительном коде
- •1.6.3Проблема переполнения
- •1.6.4Представление с избытком
- •1.7 Хранение дробей
- •1.7.1Представление с плавающей точкой
- •1.7.2Ошибка усечения
- •1.8 Сжатие данных
- •1.8.1Общие методы сжатия данных
- •1.8.2Сжатие звука
- •1.8.3Сжатие изображений
- •1.9 Ошибки передачи данных
- •1.9.1Контрольный разряд четности
- •1.9.2Коды с исправлением ошибок
- •2Манипулирование данными
- •2.1 Архитектура эвм
- •2.1.1Сложение двух чисел, хранящихся в оперативной памяти
- •2.1.2Кто и что изобрел?
- •2.2 Машинный язык
- •2.2.1Система команд
- •2.2.2Кэш-память
- •2.2.3Арифметико-логические команды
- •2.2.4Команды управления
- •2.2.5Деление двух значений, хранящихся в памяти
- •2.3 Выполнение программы
- •2.3.1Пример выполнения программы
- •2.3.2Команды переменной длины
- •2.3.3Программы и данные
- •2.4 Арифметические и логические операции
- •2.4.1Логические операции
- •2.4.2Сравнение вычислительной мощности эвм
- •2.4.3Операции сдвига
- •2.4.4Арифметические операции
- •2.5 Связь с другими устройствами
- •2.5.1Связь через контроллер
- •2.5.2Строение шины
- •2.5.3Скорость передачи данных
- •2.6 Другие архитектуры
- •2.6.1Конвейерная обработка
- •3Операционные системы и организация сетей
- •3.13.1. Эволюция операционных систем
- •3.1.1Однопроцессорные системы
- •3.1.2Многопроцессорные системы
- •3.2 Архитектура операционной системы
- •3.2.1Программное обеспечение
- •3.2.2Полезное единообразие или вредная монополия?
- •3.2.3Компоненты операционной системы
- •3.2.4Операционная система linux
- •3.2.5Начало работы операционной системы
- •3.3 Координирование действий машины
- •3.3.1Понятие процесса
- •3.3.2Управление процессами
- •3.3.3Модель «клиент-сервер»
- •3.4 Обработка конкуренции между процессами
- •3.4.1Семафор
- •3.4.2Взаимная блокировка
- •3.5 Сети
- •3.5.1Основы организации сетей
- •3.5.2Интернет
- •3.5.3Топология сети Интернет
- •3.5.4Система адресов Интернета
- •3.5.5Электронная почта
- •3.5.6Всемирная паутина
- •3.6 Сетевые протоколы
- •3.6.1Управление правом отправки сообщений
- •3.6.2Сеть ethernet
- •3.6.3Javascript, апплеты, cgi и сервлеты
- •3.6.4Многоуровневый принцип программного обеспечения Интернета
- •3.6.5Комплект протоколов tcp/ip
- •3.6.6Протоколы рорз и imap
- •3.7 Безопасность
- •3.7.1Протокол защищенных сокетов
- •3.7.2Группа компьютерной «скорой помощи»
- •4Алгоритмы
- •4.1 Понятие алгоритма
- •4.1.1Предварительные замечания
- •4.1.2Формальное определение алгоритма
- •4.1.3Определение алгоритма
- •4.1.4Абстрактная природа алгоритма
- •4.2 Представление алгоритма
- •4.2.1Примитивы
- •4.2.2Псевдокод
- •4.3 Создание алгоритма
- •4.3.1Искусство решения задач
- •4.3.2Итеративные структуры в музыке
- •4.3.3Первый шаг в решении задачи
- •4.4 Итеративные структуры
- •4.4.1Алгоритм последовательного поиска
- •4.4.2Управление циклом
- •4.4.3Алгоритм сортировки методом вставок
- •4.5Рекурсивные структуры
- •4.5.1Поиск и сортировка
- •4.5.2Алгоритм двоичного поиска
- •4.5.3Управление рекурсивными структурами
- •4.6 Эффективность и правильность
- •4.6.1Эффективность алгоритма
- •4.6.2Проверка правильности программного обеспечения
- •4.6.3По ту сторону проверки правильности программ
- •5Языки программирования
- •5.1 Исторический обзор
- •5.1.1Ранние поколения
- •5.1.2Интерплатформенное программное обеспечение
- •5.1.3Независимость от машины
- •5.1.4Парадигмы программирования
- •5.2 Основные понятия традиционного программирования
- •5.2.1Культуры языков программирования
- •5.2.2Переменные и типы данных
- •5.2.3Структуры данных
- •5.2.4Константы и литералы
- •5.2.5Операторы присваивания
- •5.2.6Управляющие операторы
- •5.2.7Комментарии
- •5.3 Процедурные единицы
- •5.3.1Процедуры
- •5.3.2Событийно-управляемые программные системы
- •5.3.3Параметры
- •5.3.4Функции
- •5.3.5Операторы ввода-вывода
- •5.4 Реализация языка программирования
- •5.4.1Процесс трансляции программы
- •5.4.2Реализация java
- •5.4.3Компоновка и загрузка
- •5.4.4Пакеты разработки программного обеспечения
- •5.5 Объектно-ориентированное программирование
- •5.5.1Классы и объекты
- •5.5.3Конструкторы
- •5.5.4Дополнительные возможности
- •5.6 Параллельные операции
- •5.7 Декларативное программирование
- •5.7.1Логическая дедукция
- •5.7.2Язык программирования Prolog
- •6Разработка программного обеспечения
- •6.1 Разработка программного обеспечения
- •6.1.1Ассоциация по вычислительной технике
- •6.1.2Институт инженеров по электротехнике и электронике
- •6.2 Жизненный цикл программы
- •6.2.1Цикл как единое целое
- •6.2.2Разработка программного обеспечения на практике
- •6.2.3Этапы разработки программного обеспечения
- •6.2.4Анализ
- •6.2.5Проектирование
- •6.2.6Реализация
- •6.2.7Тестирование
- •6.2.8Современные тенденции
- •6.3 Модульность
- •6.3.1Модульная реализация программы
- •6.3.2Связь модулей системы
- •6.3.3Связность модуля
- •6.4 Методики проектирования
- •6.4.1Нисходящее и восходящее проектирование
- •6.4.2Модели проектирования
- •6.4.3Разработка открытых программных продуктов
- •6.5 Инструменты проектирования
- •6.6 Тестирование
- •6.7 Документация
- •6.8 Право собственности на программное обеспечение и ответственность
- •Часть 3 организация данных
- •7Структуры данных
- •7.1 Основы структур данных
- •7.1.1Опять абстракция
- •7.1.2Статические и динамические структуры
- •7.1.3Указатели
- •7.2 Массивы
- •7.3 Списки
- •7.3.1Непрерывные списки
- •7.3.2Реализация непрерывных списков
- •7.3.3Связные списки
- •7.3.4Поддержка абстрактного списка
- •7.4 Стеки
- •7.4.1Откат
- •7.4.2Реализация стека
- •7.5 Очереди
- •7.5.1Проблема указателей
- •7.6 Деревья
- •7.6.1Реализация дерева
- •7.6.2Сбор мусора
- •7.6.3Пакет бинарного дерева
- •7.7 Пользовательские типы данных
- •7.7.1Пользовательские типы
- •7.7.2Классы
- •7.7.3Описательное и процедурное знание
- •7.7.4Стандартная библиотека шаблонов
- •7.8 Указатели в машинном языке
- •8Файловые структуры
- •8.1 Роль операционной системы
- •8.1.1Таблицы размещения файлов
- •8.2 Последовательные файлы
- •8.2.1Обработка последовательных файлов
- •8.2.2Консорциум производителей программного обеспечения для www
- •8.2.3Текстовые файлы
- •8.2.4Текстовые и двоичные файлы
- •8.2.5Вопросы программирования
- •8.2.6Семантическая сеть
- •8.3 Индексация
- •8.3.1Основные положения индексации
- •8.3.2Вопросы программирования
- •8.3.3Расположение файлов на дисках
- •8.4 Хэширование
- •8.4.1Хэш-система
- •8.4.2Проблемы распределения
- •8.4.3Аутентификация посредством хэширования
- •8.4.4Вопросы программирования
- •9Структуры баз данных
- •9.1 Общие вопросы
- •9.2 Многоуровневый подход к реализации базы данных
- •9.2.1Система управления базой данных
- •9.2.2Распределенные базы данных
- •9.2.3Модели баз данных
- •9.3 Реляционная модель баз данных
- •9.3.1Вопросы реляционного проектирования
- •9.3.2Системы баз данных для персональных компьютеров
- •9.3.3Хронологические базы данных
- •9.3.4Реляционные операции
- •9.3.5Вопросы реализации
- •9.3.6Язык sql
- •9.4 Объектно-ориентированные базы данных
- •9.5 Поддержка целостности базы данных
- •9.5.1Пространственные базы данных
- •9.5.2Протоколы фиксации/отката изменений
- •9.5.3Блокировка
- •9.6 Воздействие технологий баз данных на общество
- •10Искусственный интеллект
- •10.1 Интеллект и машины
- •10.1.1Конечный результат или имитация
- •10.1.2Истоки искусственного интеллекта
- •10.1.3Тест Тьюринга
- •10.1.4Машина для решения головоломки из восьми фишек
- •10.2 Распознавание образов
- •10.3 Мышление
- •10.3.1Продукционные системы
- •10.3.2Интеллект, основанный на поведении
- •10.3.3Деревья поиска
- •10.3.4Эвристика
- •10.4 Искусственные нейронные сети
- •10.4.1Основные свойства
- •10.4.2Приложение теории
- •10.4.3Ассоциативная память
- •10.5 Генетические алгоритмы
- •10.6 Прочие области исследования
- •10.6.1Обработка лингвистической информации
- •10.6.2Рекурсия в естественных языках
- •10.6.3Роботы
- •10.6.4Системы баз данных
- •10.6.5Экспертные системы
- •10.7 Обдумывая последствия
- •10.7.1Сильный искусственный интеллект против слабого
- •11Теория вычислений
- •11.1 Функции и их вычисление
- •11.1.1Теория рекурсивных функций
- •11.2 Машины Тьюринга
- •11.2.1Основы машины Тьюринга
- •11.2.2Истоки машины Тьюринга
- •11.2.3Тезис Черча-Тьюринга
- •11.3 Универсальные языки программирования
- •11.3.1Скелетный язык
- •11.3.2Существуют ли инопланетяне?
- •11.3.3Универсальность скелетного языка
- •11.4 Невычислимая функция
- •11.4.1Проблема останова
- •11.4.2Неразрешимость проблемы останова
- •11.5 Сложность задач
- •11.5.1Измерение сложности задачи
- •11.5.2Пространственная сложность
- •11.5.3Полиномиальные и не полиномиальные задачи
- •11.5.5Детерминированность против недетерминированности
- •11.6Шифрование с открытым ключом
- •11.6.1Шифрование при помощи задачи о ранце
- •11.6.2Популярные системы шифрования
- •11.6.3Модульная арифметика
- •11.6.4Обратно к шифрованию
11.6Шифрование с открытым ключом
Тот факт, что для NP-полных задач пока что не найдено эффективных решений, приводит ко многим интересным приложениям, например к обработке зашифрованной информации. В этом разделе мы познакомимся с такой техникой шифрования. Она использует значения, называемые ключами, для шифрования и дешифровки данных. Однако ключи шифрования, которые применяются для шифрования данных, отличаются от ключей декодирования, при помощи которых зашифрованная информация дешифруется. Люди, которым известны ключи шифрования, могут зашифровать сообщения, но не смогут дешифровать сообщения, зашифрованные другими людьми, даже если те применяли те же ключи шифрования. Поэтому ключи шифрования можно не прятать, и это не поставит под угрозу безопасность системы. В такой системе шифрования множество людей могут отправлять зашифрованные сообщения на один и тот же адрес, где их сможет прочитать единственный человек, знающий ключи декодирования. Подобные техники шифрования образуют область изучения, известную как криптография с открытым ключом; этот термин отображает тот факт, что ключи, при помощи которых зашифрованы сообщения, могут быть известны неограниченному количеству людей.
11.6.1Шифрование при помощи задачи о ранце
Описание определенной системы шифрования с открытым ключом мы начнем с NP-полной задачи, известной как задача о ранце. Это задача выбора чисел из набора таким образом, чтобы сумма выбранных чисел равнялась определенному значению. Она называется задачей о ранце, так как аналогична проблеме выбора набора предметов, которые точно заполняют ранец. Например, возьмем такую задачу о ранце: выбрать набор значений из списка:
191 691 573 337 365 730 651 493 177 354
так, чтобы их сумма была равна 2063.
Наиболее известный способ решения задачи о ранце заключается в последовательной проверке всех возможных комбинаций чисел, пока не будет найдено решение. Но если в списке п значений, проверить придется 2" комбинаций. Поэтому, если только нам не посчастливится найти правильную комбинацию в начале поиска, время, необходимое для решения, будет очень большим. Чтобы самостоятельно понять эту особенность, попробуйте решить приведенную ранее задачу о ранце. Вы обнаружите, что это займет много времени, хотя список состоит всего из 10 значений. Представьте свое замешательство, если вам будет дано 20 значений, то есть более миллиона комбинаций для проверки.
11.6.2Популярные системы шифрования
Одна из наиболее популярных систем шифрования, используемая для безопасной передачи данных в Интернете, — это PGP (Pretty Good Privacy), которую разработал Филипп Циммерман в 1991 году. PGP — простая в использовании система шифрования общего назначения с открытым ключом, бесплатно распространяемая в Интернете для некоммерческого использования. Алгоритм, на основе которого разработана PGP, — это RSA, названный в честь его создателей: Рона Райвеста (Ron Rivest), Ади Шамира (Adi Shamir) и Леонарда Адлемана (Leonard Adleman). В отличие от систем шифрования, основанных на сложности решения задачи о ранце, которые мы обсуждаем в этом разделе, RSA основана на сложности поиска множителей больших целых чисел.
RSA является примером того, как патентное право и государственное регулирование влияют на распространение программного обеспечения. Действительно, за RSA велось множество патентных битв, и правительство США продолжает ограничивать ее распространение. Подробнее об этой грандиозной эпопее вы можете узнать, найдя соответствующие документы в Сети. Для начала советую вам поискать узлы, посвященные PGP и RSA.
Задачу о ранце на основе приведенного выше списка можно применять для шифрования сообщений следующим образом: сначала представим сообщение в виде строки битов, возможно, используя ASCII или Unicode. Затем разобьем эту строку на сегменты по 10 битов и представим каждый 10-битовый сегмент в виде одного числа. Это число получается путем сложения значений из списка, занимающих места, соответствующие позициям единиц в 10-битовом сегменте. Например, 10-битовый сегмент 1ОО11О0ОО1 будет представлен числом 1247 (рис. 11.8): единицы в сегменте находятся на первой, четвертой, пятой и десятой позиции, а сумма соответствующих значений в списке (191, 337, 365 и 354) равна 1247. Аналогично, комбинация 0010011010 будет представлена числом 2131 (573 + 730 + + 651 + 177). Сообщение 1001100001001О011010 будет зашифровано последовательностью из двух чисел: 1247 и 2131.
Предположим, что кто-то перехватил это зашифрованное сообщение, более того, предположим, что этот человек знает список значений, который использовался для шифрования. Теперь для декодирования сообщения злоумышленнику понадобится решить две задачи о ранце, что потребует существенных затрат времени. Если же размер списка, применяемого для шифрования сообщения, будет намного больше 10, задачу декодирования перехваченных сообщений будет совершенно невозможно решить — то есть содержание сообщения останется в тайне.
Проблема в этом простом примере заключается в том, что никто не сможет декодировать это сообщение быстро — даже адресат. Нам необходима хитрость, которая позволит адресату быстро решить задачу о ранце, тогда как все остальные столкнутся с требующей исключительно больших временных затрат задачей.
Чтобы получить эту хитрость, заметим, что некоторые задачи о ранце решаются легко. Предположим, что список состоит из следующих значений: 1 4 6 12 24 51 105 210 421 850
Каждое число в списке больше суммы всех предшествующих чисел. Поэтому, если нам необходимо выбрать набор значений, сумма которых равна 995, мы будем точно знать, что одно из требуемых значений — это 850, так как сумма всех остальных значений будет слишком мала. Сделав этот выбор, мы сократим задачу до выбора чисел, сумма которых равна 995 - 850, то есть 145. Но это означает, что нужно обязательно выбрать 105, так как это самое близкое к искомому меньшее значение. Продолжая размышлять подобным образом, мы быстро сделаем вывод, что нужные нам значения — это 850, 105, 24, 12 и 4.
А теперь финальный аккорд: существует способ преобразования подобных простых задач о ранце в сложные задачи и обратно. Рассмотрим процесс преобразования в терминах трех «волшебных» чисел. Позже мы узнаем, откуда берутся эти волшебные числа и как построить собственную систему шифрования. Наши волшебные числа — это 642, 2311 и 18.
Первый шаг — преобразовать список
1 4 6 12 25 51 105 210 421 850
при помощи которого конструируется простая задача о ранце, в другой список, соответствующий более сложной задаче. Мы сделаем это, умножив каждое число из списка на 642 (первое магическое число) и записав остатки от деления произведений на 2311 (второе магическое число). В итоге получим список
642 257 1541 771 2184 388 391 782 2206 304
В частности, вместо значения 4 из исходного списка теперь стоит 257, так как 4 х 642 = 2568, а остаток от деления 2568 на 2311 равен 257.
Заметим, что задача о ранце в терминах нового списка будет сложнее, так как процесс преобразования разрушил отношения, существовавшие между значениями исходного списка. Но, зная волшебные числа, мы можем быстро решить новую задачу. Умножим целевую сумму на 18 (третье волшебное число), разделим результат на 2311 (второе волшебное число) и запишем остаток от деления. Затем будем считать этот остаток суммой нужных значений задачи о ранце с исходным «простым» списком. После того как эта простая задача будет решена, значения первого списка, решающие исходную задачу о ранце, будут значениями, которые занимают позиции, соответствующие решению простой задачи о ранце.
Например, наша задача — выбрать значения из списка
642 257 1541 771 2184 388 391 782 2206 304
сумма которых равна 4895. Сначала умножаем 4895 х 18 = 88 ПО, затем делим 88 110 на 2311, остаток равен 292. Затем определяем, что значения 6, 25, 51 и 210 — это значения из списка
1 4 6 12 25 51 105 210 421 850
дающие в сумме 292. Так как это третье, пятое, шестое и восьмое значения в соответствующем списке, делаем вывод, что третье, пятое, шестое и восьмое числа в списке
642 257 1541 771 2184 388 391 782 2206 304
дают в сумме 4895. Действительно, 1541 + 2184 + 388 + 782 - 4895, что и требовалось.
Полная система шифрования с открытым ключом работает следующим образом: мы свободно распространяем список
642 257 1541 771 2184 388 391 782 2206 304
и позволяем людям шифровать сообщения в терминах задачи о ранце, основанной на этом списке. Однако мы храним исходный список и три волшебных числа в тайне. Получив зашифрованные сообщения, мы быстро декодируем их, преобразовав в простую задачу о ранце, что не сможет сделать никто другой. Следовательно, сообщения, отправленные нам, останутся в безопасности (рис. 11.9).
