Статьи » Получение MD5-хеша строки или файла в Dart
Получение MD5-хеша строки или файла в Dart
MD5 (Message Digest 5) — 128-битный алгоритм хеширования, позволяющий вычислять уникальные "отпечатки" фиксированной длины для данных произвольного объема, и обладающий свойством "лавинного эффекта" (незначительные изменения исходных данных приводят к существенным и непредсказуемым изменениям в хеше).
Алгоритм MD5 - создан профессором Рональдом Л. Ривестом из Массачусетского технологического института в 1991 году, и долгое время являлся одним из самых распространенных методов для проверки целостности файлов, хранения цифровых подписей и паролей. Но в конце 2008 года отдел US-CERT, входящий в одну из структур министерства внутренней безопасности США, призвал разработчиков программного обеспечения, владельцев веб-сайтов и пользователей прекратить использовать MD5 в любых целях, так как исследования продемонстрировали ненадёжность этого алгоритма.
Чтобы вычислить MD5-хеш для собственного набора данных, можно просто воспользоваться классом MD5
, входящим в состав библиотеки Dart API - "dart:crypto". Алгоритм действий достаточно простой - сначала, необходимо получить экземпляр класса с помощью стандартного конструктора:
MD5 md5 = new MD5();
потом задать данные, для которых нужно вычислить хеш, с помощью метода MD5.add()
md5.add([1, 2, 3, 4, 5]);
и на конец, получить хеш с помощью метода MD5.close()
md5.close();
Пример вычисления MD5-хеша для строки
Получить MD5-хеш для произвольной строки достаточно просто необходимо передать строку в виде массива байт (с помощью свойства String.charCodes
в объект класса MD5
и рассчитать хеш.
// подключаем криптографическую библиотеку
import "dart:crypto";
// определяем функцию для получения md5-хеша строки
String md5(String string) {
// получим экземпляр класса MD5
MD5 hash = new MD5();
// добавляем данные строки
hash.add(source.codeUnits);
// вернем MD5-хеш, в качестве строки с шестнадцатеричными символами,
// с помощью вспомогательной функции CryptoUtils.bytesToHex
return CryptoUtils.bytesToHex(hash.close());
}
void main() {
// протестируем использование нашей функции
print( md5("") );
}
Пример вычисления MD5-хеша для файла
Получить MD5-хеш для файла не на много сложнее чем для простой строки, единственно, что дополнительно необходимо - это прочитать данные из файла. Сделать это можно множеством разных способов, здесь же мы остановимся на двух - последовательное чтение данных из файла с помощью метода File.readAsBytesSync
и асинхронное чтение с помощью потоков File.openInputStream
.
Для простоты здесь мы так же пропустим шаги по обработке ошибок ввода-вывода, не существования файла и т.д.
Более подробно про способы работы с файлами можно посмотреть в документации класса File
, а так же в статье "Как прочитать текстовый файл в Dart?"
Получение сигнатуры MD5 для файла при синхронном чтении
// подключаем криптографическую библиотеку
import "dart:crypto";
// подключаем библиотеку ввода-вывода
import "dart:io";
// объявим функцию для последовательного получения MD5-хеша из файла
String md5_sync(File source) {
// получим экземпляр класса MD5
MD5 hash = new MD5();
// синхронно прочитаем все содержимое файла в массив, с помощью метода
// readAsBytesSync
List<int> fileContent = source.readAsBytesSync();
// добавим наши данные к буферу для расчета сигнатуры MD5
hash.add(fileContent);
// получим MD5 "отпечаток"
List<int> result = hash.close();
// и выведем на печать хеш в качестве строки с шестнадцатеричными символами,
// с помощью вспомогательной функции CryptoUtils.bytesToHex
print (CryptoUtils.bytesToHex(result));
}
void main() {
// протестируем использование нашей функции
md5_sync(new File('/test1'));
}
Получение сигнатуры MD5 для файла при асинхронном чтении
// подключаем криптографическую библиотеку
import "dart:crypto";
// подключаем библиотеку ввода-вывода
import "dart:io";
void md5_async(File source) {
// получим экземпляр класса MD5
MD5 hash = new MD5();
// открываем поток для чтения
InputStream inputStream = source.openInputStream();
// определяем callback-функцию обработчик, которая будет вызываться при
// получении новой порции данных из файла
inputStream.onData = () {
// при получении новых данных из файла будем добавлять их к буферу расчета MD5
hash.add(inputStream.read());
};
// определяем callback-функцию обработчик, которая будет вызываться при
// завершении чтения из файла
inputStream.onClosed = () {
// когда все данные прочитаны из файла, получим MD5 "отпечаток"
List<int> result = hash.close();
// и выведем на печать хеш в качестве строки с шестнадцатеричными символами,
// с помощью вспомогательной функции CryptoUtils.bytesToHex
print (CryptoUtils.bytesToHex(result));
};
}
void main() {
// протестируем использование нашей функции
md5_async(new File('/test2'));
}