Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Простейшая программа шифрования






Мы рассмотрим основные принципы работы с двоичными файлами на примере программы шифрования файлов. Не надейтесь, что файл, созданный этой программой, не будет взломан хорошим программистом — мы реализуем простейший алгоритм шифрования. Данный пример предназначен лишь для того, чтобы продемонстрировать особенности работы с файлами в двоичном режиме доступа. Шифрование выполняется командой меню Actions > Encrypt, a расшифровка -командой Actions > Decrypt. B обоих случаях вам будет предложено выбрать текстовый файл, с которым будет выполняться операция.

1. Создайте новый проект типа Standard EXE.

2. Активизируйте форму Form1 и задайте ее свойству Name значение frmMain, а свойству Caption — значение Шифрование файлов.

3. Поместите на форму элемент стандартного диалогового окна, задайте его свойству Name значение dlgFile.

4. Откройте редактор меню и создайте в нем следующие объекты:

 

Меню File:

Caption: Name:
& File mnuFile

Команды меню File:

Caption: Name:
& Exit mnuFileExit

Меню Actions:

Caption: Name:
& Actions mnuAct

 

Команды меню Action

Caption: Name:
& Encrypt mnuActEncrypt
& Decrypt mnuActDecrypt

 

У вас получится форма, похожая на рис. 8.5.

 

Рис. 8.5. Форма для программы шифрования

 

(ПРИМЕЧАНИЕ Следующим шагом должно стать добавление кода формы. Не считая меню, на форме присутствует всего один элемент — стандартное диалоговое окно. Элементы стандартных диалоговых окон предназначены для отображения диалоговых окон Open и Save, а также окон для настройки принтера и выбора шрифта. В нашем примере стандартное диалоговое окно используется только для выбора имени файла.

 

5. Откройте окно программы и выберите из раскрывающегося списка Object строку mnuFHeExit.

6. Добавьте в процедуру события mnuFileExit_Click() оператор End.

7. Настало время запрограммировать алгоритм шифрования. Откройте секцию (General)(Declarations) и добавьте в нее следующий фрагмент:

 

Function Encrypt(infile As String) As Boolean

Dim fileno1 As Integer

Dim fileno2 As Integer

Dim outfile As String

Dim xpos As Long

Dim x As Byte

 

'Вывести указатель в виде песочных часов

MousePointer = vbHourglass

 

xpos = 4

 

outfile = " c: \temp.enc"

 

fileno1 = FreeFile

Open infile For Binary As fileno1

fileno2 = FreeFile

Open outfile For Binary As fileno2

Put #fileno2, 1, 0

Put #fileno2, 2, 128

Put #fileno2, 3, 0

Put #fileno2, 4, 128

 

Do While Not EOF(fileno1)

xpos = xpos + 1

Get #fileno1, xpos, x

Get #fileno2, xpos, x + 128

Loop

Close fileno2

Close fileno1

 

'Удалить исходный файл и заменить его шифрованным

Kill infile

FileCopy outfile, infile

Kill outfile.

Encrypt = True

 

' Восстановить указатель мыши

MousePointer = vbNormal

End Function

 

Этот фрагмент стоит рассмотреть подробнее, поскольку именно в нем происходит основная работа программы. Обратите внимание на то, что вместо процедуры Sub используется функция — дело в том, что функция передает вызывающей процедуре код возврата. По нему можно определить, успешно ли произошло шифрование, прежде чем сообщать об этом пользователю или продолжать выполнение программы. Данная функция просто возвращает True, если шифрование прошло успешно, и False в противном случае. Кроме того, функции передается параметр infile. Он содержит полное имя шифруемого файла. Значение infile определяется вызовом функции GetFile().

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

 

ПОДСКАЗКА* Если программа выполняет какую-то длительную операцию, отображайте указатель мыши в виде песочных часов. По нему пользователь поймет, что программа работает, а не «висит». Чтобы отобразить песочные часы, задайте свойству MousePointer формы значение vbHourglass.

 

Как упоминалось ранее, команда FreeFile используется для получения свободного файлового номера. Когда я работал над этим примером, в моей программе рядом стояли два оператора FreeFile. Я поступил так, поскольку стараюсь по возможности группировать логически связанные команды. При запуске программы она постоянно выдавала ошибку «Файл уже открыт». Почему? Я проверил в отладчике значения infile и outfile — они были правильными. Мои файлы не открывались другими приложениями, поэтому они не могли быть заблокированы другой программой. После некоторых размышлений я понял, что файловый номер выделяется программе не в операторе FreeFile, a при открытии файла оператором Open (FreeFile просто сообщает, какие файловые номера доступны в данный момент). В итоге я получал один и тот же номер для fileno1 и fileno2. Как только я переместил команды FreeFile к соответствующим операторам Open, программа заработала. Мораль: старайтесь держать вызов FreeFile как можно ближе к оператору Open, особенно если ваша процедура работает с несколькими файлами. Как видите, даже простейшую программу иногда приходится отлаживать!

 

ПОДСКАЗКА Если ваша процедура работает с несколькими файлами, старайтесь держать команду FreeFile как можно ближе к команде Open. FreeFile не блокирует файловый номер, а лишь сообщает о его наличии. Самый верный путь — выполнять команду Open сразу же после команды FreeFile.

 

Перед тем как приступать к непосредственной обработке данных, мы добавляем в начало шифрованного файла некое подобие «электронной подписи». По ней алгоритм расшифровки определяет, действительно ли файл зашифрован. Подпись должна представлять собой последовательность байтов, которая практически никогда не встречается в файлах. В своем примере я использовал четырехбайтовую подпись 0, 128, 0, 128. Именно эту конкретную последовательность байтов будет искать алгоритм дешифровки. Функции Encrypt и Decrypt можно дополнительно усовершенствовать, чтобы электронная подпись генерировалась прямо в них.

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

В конце функции стоят операторы Kill, которые удаляют файлы с диска. После такой последовательности команд файл infile заменяется файлом outfile. B результате у вас остается зашифрованный файл, а временный файл стирается с диска. Тем не менее перед переименованием файла необходимо позаботиться о том, чтобы имя результирующего файла было уникальным, — именно по этой причине мы удаляем infile перед тем, как переименовывать outfile. После успешного переименования outfile удаляется с диска.

Шифрование завершено, поэтому мы восстанавливаем прежний вид указателя мыши — пользователь должен понять, что программа готова к работе. Функция Encrypt возвращает значение True, чтобы вызывающая процедура могла нормально продолжаться.

1. Основа программы (функция шифровки) готова. Теперь необходимо создать процедуру, из которой она будет вызываться. Для этого мы воспользуемся процедурой события mnuEncrypt_Click():

 

Private Sub mnuActEncrypt_Click()

Dim filename As String

 

filename = GetFile()

If filename < > " " Then

If Encrypt(filename) = False Then

MsgBox " Ошибка при шифровании файла! "

End If

End If

 

End Sub

 

2, Перед вызовом функции Encrypt команда меню должна получить имя файла с помощью функции GetFile():

 

Function GetFile() As String

dlgFile.CancelError = True

On Error GoTo filerr

dlgFile.DialogTitle =" Выберите файл..."

dlgFile.DefaultExt = " *.txt"

dlgFile.Filter = " Текстовые файлы (*.txt)|*, txt* _

Все файлы (*. *)|*.*"

dlgFile.FilterIndex = 1

dlgFile.MaxFileSize = 32767

dlgFile.ShowOpen

GetFile = dlgFile.filename

Exit Function

 

filerr:

GetFile = " "

End Function

 

Функцию GetFile() тоже следует рассмотреть внимательнее. В основе ее лежит элемент стандартного диалогового окна. Он предоставляет все средства, необходимые для получения имени файла. Возможно, вы уже знаете, что встречающееся во многих приложениях окно Open не открывает файл — оно всего лишь получает и возвращает приложению его имя. Затем другая процедура использует это имя и открывает файл для дальнейшей обработки. Наша программа поступает точно так же.

Работа функции GetFile() начинается с того, что свойству CancelError присваивается значение True. В этом случае при нажатии пользователем кнопки Cancel диалоговое окно посылает сообщение об ошибке. Мы перехватываем эту ошибку, чтобы в случае отмены программа не пыталась продолжать шифрование. Процедура шифрования пропускается с помощью команды On Еггог.

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

По умолчанию для файлов в диалоговом окне выбирается расширение *.txt. Читатели, знакомые с командами DOS, поймут, что с данным шаблоном в окне будут отображаться лишь файлы с расширением.txt — это помогает сосредоточить внимание пользователя лишь на интересующих его файлах. Если в ваших приложениях используются стандартные диалоговые окна, старайтесь упростить работу пользователя.

После шаблона задается фильтр (свойство Filter). Он представляет собой строку, в которой описания чередуются с фактическими значениями фильтра, а в качестве разделителя применяется символ «вертикальная черта» (|). В нашем приложении, как и во многих других, задано несколько фильтров. От вас требуется лишь правильно отделять их друг от друга вертикальной чертой. Доступ к различным фильтрам осуществляется с помощью свойства FilterIndex. FilterIndex — индекс текущего фильтра, отображаемого в диалоговом окне. Первый фильтр имеет индекс 1, второй — 2 и т. д. При задании этого свойства устанавливается лишь начальное значение индекса. Текущий фильтр выбирается в диалоговом окне (рис. 8.6).

Рис. 8.6. Стандартное диалоговое окно

 

Обратите внимание — свойству MaxFileSize задается значение 32 767. Если задать это свойство, в диалоговом окне будут отображаться лишь имена файлов размером 32 К и меньше. Данному свойству можно задать произвольное значение, но необходимо позаботиться о том, чтобы открываемые файлы не выходили за пределы возможностей элементов. Впрочем, в выполняемых нами операциях размер файла нигде не ограничивается, так что для этого приложениясвойство MaxFileSize не имеет особого значения.

 

ПОДСКАЗКА С помощью свойства MaxFileSize можно фильтровать файлы в стандартном диалоговом окне по размеру. Эта возможность предохраняет от многих ошибок, если используемые вами элементы имеют ограничения по памяти (это относится к текстовым полям).

 

Наконец, мы задаем свойство ShowOpen, чтобы отобразить диалоговое окно. Если пользователь нажимает кнопку Cancel, диалоговое окно возвращает код ошибки, а работа функции отменяется. В противном случае свойству FileName задается имя файла, выбранного пользователем, и это значение возвращается функцией GetFile(). Если имя файла не выбрано, функция возвращает пустую строку. Давайте напишем алгоритм дешифровки, который будет восстанавливать исходный вид файла:

 

1. Добавьте следующий фрагмент:

Private Function Decrypt(infile As String) As Boolean

Dim fileno1 As Integer

Dim fileno2 As Integer

Dim outfile As String

Dim xpos As Long

Dim x As Byte

Dim t(3) As Byte

 

'Вывести указатель в виде песочных часов

MousePointer = vbHourglass

 

xpos = 4

outfile = " c: \temp.enc"

fileno1 = FreeFile

Open infile For Binary As fileno1

fileno2 = FreeFile

Get #fileno1, 1, t(0)

Get #fileno1, 2, t(1)

Get #fileno1, 3, t(2)

Get #fileno1, 4, t(3)

If (t(0)=0 And t(1)=128 And t(2)=0 And t(3)=128) Then

Open outfile For Binary As fileno2

Do While Not EOF(fileno1)

xpos = xpos + 1

Get #fileno1, xpos, x

Get #fileno2, xpos - 4, x + 128

Loop

Close fileno2

 

Decrypt = True

Else

Decrypt = False

End If

 

Close fileno1

 

'Удалить исходный файл и заменить его шифрованным

If Decrypt Then

Kill infile

FileCopy outfile, infile

Kill outfile

End If

 

'Восстановить указатель мыши

MousePointer = vbNormal

 

End Function

 

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

 

2. Добавьте код для вызова функции Decrypt при выборе из меню соответствующей команды:

 

Private Sub mnuActDecrypt_Click()

Dim filename As String

 

filename = GetFile()

If filename < > " " Then

If Decrypt(filename) = False Then

MsgBox " Ошибка при расшифровке файла! "

End If

End If

End Sub

 

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

 


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.019 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал