45723 (762114), страница 2

Файл №762114 45723 (Работа с бинарными данными и реестром Windows на платформе .NET) 2 страница45723 (762114) страница 22016-08-02СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 2)

Позволяет сохранять разнотипные данные в массиве байт, длина которого динамически увеличивается по мере добавления в него данных. Затем эти данные представляются в виде массива типа System.Byte[], который, кроме самих данных, содержит их контрольную сумму и, возможно, значение цифровой сигнатуры. Возвращаемый массив может быть упакован для экономии места и зашифрован для ограничения доступа к информации.

При создании экземпляра класса AcedMemoryWriter можно указать предполагаемое число байт, которое будет помещено в бинарный поток. Таким образом удается избежать лишнего перераспределения памяти под внутренний массив. В AcedMemoryWriter есть методы, названия которых начинаются с "Write", предназначенные для помещения в поток значений следующих типов: Boolean, Byte, Byte[], Char, DateTime, Decimal, Single, Double, Guid, Int16, Int32, Int64, SByte, String, TimeSpan, UInt16, UInt32, UInt64. Кроме того, можно добавлять сразу фрагменты массивов с элементами стандартных value-типов с помощью перегруженных методов Write(). При этом указывается индекс первого сохраняемого элемента массива и число записываемых элементов. Общее число байт, помещенное в бинарный поток, возвращается свойством Length класса AcedWriter. Метод Reset() обнуляет длину потока, позволяя заполнить его новыми данными без пересоздания экземпляра класса AcedMemoryWriter.

Текущая длина внутреннего массива возвращается и устанавливается свойством Capacity. Ссылку на внутренний массив можно получить вызовом функции GetBuffer(). Правда, эта ссылка изменяется при каждом перераспределении памяти, т.е. при каждом изменении свойства Capacity. В некоторых случаях, например, при чтении данных из файла с помощью FileStream.Read(), удобнее передать ссылку на внутренний массив непосредственно в метод FileStream.Read(), вместо того, чтобы считывать данные в промежуточный массив, а затем переписывать их в поток методом Write(). Чтобы сделать это быстрее, нужно сохранить во временной переменной текущую длину потока, т.е. значение свойства Length, затем вызвать метод Skip(), передавая в него число байт, которое будет прочитано из файла. При этом длина потока увеличится на указанное число байт без фактического заполнения их данными. Теперь можно получить ссылку на внутренний массив из функции GetBuffer(), а затем вызвать метод FileStream.Read(), передавая в него полученную ссылку на массив и значение, сохраненное во временной переменной, в качестве смещения в массиве.

Когда все необходимые данные записаны в бинарный поток, вызывается функция ToArray(), возвращающая результирующий массив данных. Имеется несколько вариантов этой функции, которые отличаются набором принимаемых параметров. Наиболее функциональным является вариант, принимающий два параметра: compressionMode типа AcedCompressionMode и keyGuid типа System.Guid. Вызов функции ToArray() с одним параметром эквивалентен передаче значения Guid.Empty в параметре keyGuid. Вызов этой функции без параметров эквивалентен передаче значения NoCompression в параметре compressionMode и значения Guid.Empty в параметре keyGuid. Рассмотрим подробнее, чем управляют эти параметры и как они влияют на сохраняемый формат данных.

Параметр типа AcedCompressionMode выбирает режим сжатия данных. Его значение соответствует одной из констант, рассмотренных выше при описании класса AcedDeflator. Если этот параметр равен значению NoCompression, данные бинарного потока не сжимаются. Параметр keyGuid задает ключ шифрования для выходного массива байт. Если этот параметр равен Guid.Empty, шифрование не выполняется. Значение типа System.Guid используется в качестве ключа шифра по нескольким причинам. Во-первых, легко сгенерировать новое уникальное значение ключа вызовом функции Guid.NewGuid(). Во-вторых, значения такого типа имеют общепринятое строковое представление. В-третьих, Guid легко получить из значения односторонней хеш-функции RipeMD-160. Если ключ шифра вводится пользователем с клавиатуры в виде строки символов, необходимо преобразовать эту строку в цифровую сигнатуру вызовом AcedRipeMD.Compute(), а затем в значение типа System.Guid вызовом метода ToGuid() класса AcedRipeMD. Шифрование данных выполняется методами классом AcedCast5. Но прежде, чем шифровать данные, для них вычисляется значение 20-байтной сигнатуры RipeMD-160, которое помещается в выходной массив вместе с данными и используется при последующем чтении из потока для проверки того, что данные в потоке расшифрованы с правильным ключом и что они не были повреждены.

Последовательность действий при вызове метода ToArray() класса AcedMemoryWriter следующая. Сначала выполняется упаковка данных классом AcedDeflator. Затем для полученного массива рассчитывается значение односторонней хеш-функции RipeMD-160 методами класса AcedRipeMD. Это значение помещается в выходной массив перед данными. Потом данные шифруются методами класса AcedCast5. Значение цифровой сигнатуры не шифруется. На заключительном этапе для всего содержимого выходного массива рассчитывается контрольная сумма Адлера вызовом метода AcedBinary.Adler32(), которая размещается в первых 4-х байтах выходного массива. Заполненный таким образом массив возвращается как результат функции ToArray(). В зависимости от параметров, могут опускаться этапы упаковки и/или расчета цифровой сигнатуры и шифрования данных.

Пример использования класса AcedMemoryWriter:

private byte[] PutData()

{

AcedMemoryWriter w = new AcedMemoryWriter();

w.WriteByteArray(new byte[] {5, 6, 7, 8, 9});

w.WriteInt16(10000);

int[] otherValues = new int[120];

for (int i = 0; i < 120; i += 3)

{

otherValues[i] = 1;

otherValues[i + 1] = 2;

otherValues[i + 2] = 3;

}

w.Write(otherValues, 10, 100);

w.WriteString("Hello world!");

//////////////////////////////////////////////////////

// Вариант 1: данные возвращаются как есть с

// добавлением контрольной суммы Адлера.

//////////////////////////////////////////////////////

return w.ToArray();

/*

//////////////////////////////////////////////////////

// Вариант 2: данные сжимаются и защищаются

// контрольной суммой Адлера.

//////////////////////////////////////////////////////

return w.ToArray(AcedCompressionMode.Fast);

*/

/*

//////////////////////////////////////////////////////

// Вариант 3: данные сжимаются, шифруются и защищаются

// цифровой сигнатурой RipeMD-160.

//////////////////////////////////////////////////////

return w.ToArray(AcedCompressionMode.Fast,

new Guid("CA761232-ED42-11CE-BACD-00AA0057B223"));

*/

}

В данном примере функция PutData() помещает в бинарный поток массив байт как целый объект, потом значение типа Int16, затем фрагмент массива элементов типа Int32, а в конце – строку символов. Результатом функции может быть просто массив байт, содержащий данные, записанные в поток, защищенные контрольной суммой Адлера. Размер этого массива составляет 443 байта. Если передать в функцию AcedMemoryWriter.ToArray() параметр compressionMode со значением AcedCompression.Fast, данные бинарного потока будут упакованы и размер полученного массива составит 51 байт. Если, кроме того, передать некоторое непустое значение типа Guid в параметре keyGuid, сжатые данные будут защищены цифровой сигнатурой RipeMD-160 и зашифрованы методом CAST-128. За счет добавления сигнатуры размер выходного массива увеличится при этом на 20 байт и составит 71 байт.

Класс AcedMemoryReader

Предназначен для чтения данных из массива байт, созданного экземпляром класса AcedMemoryWriter. В конструктор класса AcedMemoryReader передается ссылка на массив байт с указанием фрагмента, содержащего данные бинарного потока. Если данные зашифрованы, в последнем параметре конструктора необходимо передать значение типа System.Guid, соответствующее ключу шифра, который использовался при вызове метода ToArray() класса AcedMemoryWriter. Отдельные значения могут быть прочитаны из потока методами, названия которых состоят из префикса "Read" и наименования типа читаемого значения. Фрагменты массивов, состоящих из элементов стандартных value-типов, считываются методом Read(). Для возвращения текущей позиции на начало потока, чтобы заново прочитать данные, используется метод Reset(). Чтобы пропустить некоторое количество байт во входном потоке вызывается метод Skip(). При попытке чтения данных за пределами потока возникает исключение типа AcedReadBeyondTheEndException.

Свойство Position класса AcedMemoryReader возвращает индекс следующего считываемого байта во внутреннем массиве, ссылка на который возвращается функцией GetBuffer(). Размер внутреннего массива определяется свойством Size. Смещение во внутреннем массиве, с которого начинаются данные потока – свойством Offset. Если исходный массив байт, переданный в конструктор класса, является упакованным, в памяти создается новый массив для распакованных данных. Тогда функция GetBuffer() возвращает ссылку на этот временный массив, а свойство Offset всегда равно нулю. Если же исходный массив не является упакованным, функция GetBuffer() возвращает ссылку на массив, переданный параметром bytes в конструктор класса AcedMemoryReader. Если данные потока зашифрованы, массив байт, передаваемый в конструктор этого класса, расшифровывается на месте. Это означает, что один и тот же зашифрованный массив байт нельзя использовать для инициализации нескольких экземпляров класса AcedMemoryReader.

Если при создании экземпляра класса AcedMemoryReader в конструктор передан массив недостаточной длины или рассчитанная для него контрольная сумма Адлера не совпадает с сохраненным в потоке значением контрольной суммы, возникает исключение AcedDataCorruptedException. Если после дешифрования данных оказывается, что рассчитанное значение цифровой сигнатуры RipeMD-160 для данных потока не совпадает со значением сигнатуры, сохраненным в начале массива данных, возникает исключение AcedWrongDecryptionKeyException, которое является потомком от класса AcedDataCorruptedException.

Пример использования класса AcedMemoryReader:

private void GetData(byte[] dataBytes, out byte[] bytes,

out short n, out string s, out int[] otherValues)

{

AcedMemoryReader r = new AcedMemoryReader(dataBytes,

0, dataBytes.Length);

/*

AcedMemoryReader r = new AcedMemoryReader(dataBytes,

0, dataBytes.Length,

new Guid("CA761232-ED42-11CE-BACD-00AA0057B223"));

*/

bytes = r.ReadByteArray();

n = r.ReadInt16();

otherValues = new int[120];

r.Read(otherValues, 10, 100);

s = r.ReadString();

}

Предполагается, что массив байт, передаваемый параметром dataBytes в функцию GetData(), получен как результат функции PutData(), код которой приведен выше в разделе, описывающем класс AcedMemoryWriter. Используемый здесь конструктор класса AcedMemoryReader предполагает, что данные в бинарном потоке не зашифрованы. Закомментированный фрагмент кода содержит вызов конструктора с передачей в него ключа шифра, соответствующего варианту 3 функции PutData().

Классы AcedStreamWriter, AcedStreamReader

Эти классы аналогичны описанным выше классам AcedMemoryWriter, AcedMemoryReader. При их использовании, однако, данные помещаются не в массив байт, а в поток типа System.IO.Stream, ассоциированный с экземпляром класса AcedStreamWriter, и читаются не из массива байт, а из потока типа System.IO.Stream, ассоциированного с классом AcedStreamReader.

При работе с классом AcedStreamWriter в памяти создается буфер размером 2МБ, который постепенно заполняется данными. При достижении конца буфера, вызове методов Flush() или Close() класса AcedStreamWriter содержимое буфера упаковывается методом Compress() класса AcedDeflator. Сжатые данные сохраняются в другом буфере, размер которого также составляет 2МБ. Для упакованных данных вычисляется цифровая сигнатура RipeMD-160, после чего данные шифруются методом CAST-128. Длина фрагмента данных, контрольная сумма Адлера, цифровая сигнатура RipeMD-160 и сами сжатые и зашифрованные данные записываются в выходной поток типа System.IO.Stream. После этого содержимое буфера очищается и в него можно записывать следующие данные. При вызове метода Close() класса AcedStreamWriter, если ассоциированный с ним поток поддерживает операцию Seek, поток позиционируется на начало записанных данных и в потоке сохраняется общая длина (в байтах) данных, помещенных в поток классом AcedStreamWriter. Этот размер представляется значением типа System.Int64. Если операция Seek не поддерживается потоком типа System.IO.Stream, длина остается равной значению -1, записанному в поток при его ассоциации с классом AcedStreamWriter. Метод AssignStream класса AcedStreamWriter используется, чтобы связать данный экземпляр класса с потоком System.IO.Stream. Кроме ссылки на поток в этот метод передается константа, выбирающая режим сжатия данных, а также значение типа System.Guid, которое, если оно отлично от Guid.Empty, задает ключ для шифрования данных. Таким образом, в зависимости от параметров, переданных в метод AssignStream, этапы сжатия данных, расчета цифровой сигнатуры и шифрования данных могут опускаться.

Характеристики

Тип файла
Документ
Размер
1008,58 Kb
Тип материала
Учебное заведение
Неизвестно

Список файлов статьи

Свежие статьи
Популярно сейчас
Зачем заказывать выполнение своего задания, если оно уже было выполнено много много раз? Его можно просто купить или даже скачать бесплатно на СтудИзбе. Найдите нужный учебный материал у нас!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7027
Авторов
на СтудИзбе
260
Средний доход
с одного платного файла
Обучение Подробнее