Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

sum += delta;

z += (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3];

}

w[0]=y; w[1]=z;

}

}

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

<<
и
>>
), исключительного “или” (
^
) и побитовой операции “и” (
&
) наряду с обычным сложением (без знака). Этот код написан специально для машины, в которой тип long занимает четыре байта. Код замусорен “магическими” константами (например, он предполагает, что значение
sizeof(long)
равно
4
). Обычно так поступать не рекомендуется, но в данном конкретном коде все это ограничено одной страницей, которую программист с хорошей памятью должен запомнить как математическую формулу. Дэвид Уиллер хотел шифровать свои тексты, путешествуя без ноутбуков и других устройств. Программа кодирования и декодирования должна быть не только маленькой, но и быстрой. Переменная
n
определяет количество итераций: чем больше количество итераций, тем сильнее шифр. Насколько нам известно, при условии
n==32
алгоритм TEA никогда не был взломан.

Приведем соответствующую функцию декодирования.

void decipher(

const unsigned long *const v,

unsigned long *const w,

const unsigned long * const k)

{

unsigned long y = v[0];

unsigned long z = v[1];

unsigned long sum = 0xC6EF3720;

unsigned long delta = 0x9E3779B9;

unsigned long n = 32;

// sum = delta<<5, в целом sum = delta * n

while(n–– > 0) {

z –= (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3];

sum –= delta;

y –= (z << 4 ^ z >> 5) + z ^ sum + k[sum&3];

}

w[0]=y; w[1]=z;

}

}

Мы можем использовать алгоритм TEA для того, чтобы создать файл, который можно передавать по незащищенной линии связи.

int main // отправитель

{

const int nchar = 2*sizeof(long); // 64 бита

const int kchar = 2*nchar; // 128 битов

string op;

string key;

string infile;

string outfile;

cout << "введите имя файлов для ввода, для вывода и ключ:\n";

cin >> infile >> outfile >> key;

while (key.size<kchar) key += '0'; // заполнение ключа

ifstream inf(infile.c_str);

ofstream outf(outfile.c_str);

if (!inf || !outf) error("Неправильное имя файла");

const unsigned long* k =

reinterpret_cast<const unsigned long*>(key.data);

unsigned long outptr[2];

char inbuf[nchar];

unsigned long* inptr = reinterpret_cast<unsigned

long*>(inbuf);

int count = 0;

while (inf.get(inbuf[count])) {

outf << hex; // используется шестнадцатеричный вывод

if (++count == nchar) {

encipher(inptr,outptr,k);

// заполнение ведущими нулями:

outf << setw(8) << setfill('0') << outptr[0] << ' '

<< setw(8) << setfill('0') << outptr[1] << ' ';

count = 0;

}

}

if (count) { // заполнение

while(count != nchar) inbuf[count++] = '0';

encipher(inptr,outptr,k);

outf << outptr[0] << ' ' << outptr[1] << ' ';

}

}

Основной частью кода является цикл

while
; остальная часть носит вспомогательный характер. Цикл
while
считывает символы в буфер ввода
inbuf
и каждый раз, когда алгоритму TEA нужны очередные восемь символов, передает их функции
encipher
. Алгоритм TEA не проверяет символы; фактически он не имеет представления об информации, которая шифруется. Например, вы можете зашифровать фотографию или телефонный разговор. Алгоритму TEA требуется лишь, чтобы на его вход поступало 64 бита (два числа типа
long
без знака), которые он будет преобразовывать. Итак, берем указатель на строку
inbuf
, превращаем его в указатель типа
unsigned long*
без знака и передаем его алгоритму TEA. То же самое мы делаем с ключом; алгоритм TEA использует первые 128 битов (четыре числа типа
unsigned long
), поэтому мы дополняем вводную информацию, чтобы она занимала 128 битов. Последняя инструкция дополняет текст нулями, чтобы его длина была кратной 64 битам (8 байтов) в соответствии с требованием алгоритма TEA.

Как передать зашифрованный текст? Здесь у нас есть выбор, но поскольку текст представляет собой простой набор битов, а не символы кодировки ASCII или Unicode, то мы не можем рассматривать его как обычный текст. Можно было бы использовать двоичный ввод-вывод (см. раздел 11.3.2), но мы решили выводить числа в шестнадцатеричном виде.

ПОПРОБУЙТЕ

Ключом было слово

bs
; что представляет собой текст?

  • Читать дальше
  • 1
  • ...
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: