В 2026 году может показаться странным писать новую библиотеку для MD5. Алгоритм считается устаревшим, браузеры постепенно убирают его из Web Crypto API, а в документации Node.js есть предупреждения о его использовании.
Но реальность сложнее. MD5 всё ещё жив в:
Контрольных суммах файлов (многие репозитории до сих пор публикуют MD5-хеши)
Системах кэширования (ключи на основе контента)
Легаси-протоколах (некоторые API требуют MD5-подписи)
Внутренних идентификаторах (где безопасность не важна)
Проблема в том, что существующие реализации либо устарели, либо не имеют TypeScript, либо не работают универсально (Node.js + браузер). Я решил это исправить и представил pure-md5 — современную, типизированную и адаптивную библиотеку.
В этой статье расскажу о технических решениях, архитектуре и покажу, почему это может быть полезно в ваших проектах.
⚠️ Важное предупреждение: MD5 криптографически небезопасен. Не используйте для паролей, токенов или цифровых подписей. Только для контрольных сумм, кэширования и совместимости.
Почему не встроенный crypto?
Первый вопрос, который возникает: «Зачем новая библиотека, если в Node.js есть crypto, а в браузерах — SubtleCrypto?»
Проблема |
Node.js |
Browser |
pure-md5 |
|---|---|---|---|
Работает в браузере |
❌ |
✅ |
✅ |
Работает в Node.js |
✅ |
❌ |
✅ |
TypeScript из коробки |
❌ (нужны @types) |
⚠️ |
✅ |
MD5 поддержка |
✅ |
⚠️ (убирают) |
✅ |
Размер |
Native |
Native |
<1KB gzipped |
Зависимости |
0 |
0 |
0 |
Ключевое преимущество pure-md5 — универсальность. Вы пишете код один раз, и он работает везде. Библиотека автоматически выбирает оптимальный адаптер:
// Один и тот же код работает в Node.js и браузере import { md5, hashFile } from 'pure-md5'; const hash = md5('hello'); const fileHash = await hashFile('large-file.bin');
Архитектура: Система адаптеров
Сердце библиотеки — адаптивная система, которая пытается использовать нативные API, а при их отсутствии падает на чистую JavaScript-реализацию.

Как работает детекция
// Упрощённая логика выбора адаптера function detectAdapter() { if (isNode && require('node:crypto')) { return nodeAdapter; // Приоритет 1 } if (globalThis.crypto?.subtle) { return webCryptoAdapter; // Приоритет 2 } return pureJSAdapter; // Фолбэк }
Это даёт несколько преимуществ:
Производительность: В Node.js используется нативный C++ код
Совместимость: В старых браузерах работает JS-реализация
Будущее-proof: Если WebCrypto уберёт MD5, библиотека продолжит работать
Работа с большими файлами: Стримы и прогресс
Одна из самых частых задач — хеширование больших файлов без загрузки в память. В pure-md5 это решено через стриминговый API с отслеживанием прогресса.
Пример: Хеширование файла с прогресс-баром
import { hashFile, createProgressTracker } from 'pure-md5'; const fileSize = 1024 * 1024 * 100; // 100 MB const progress = createProgressTracker(fileSize, (percent) => { console.log(`Прогресс: ${percent.toFixed(1)}%`); }); const result = await hashFile('large-file.bin', { onProgress: progress }); console.log('MD5:', result.digest); // например: "5d41402abc4b2a76b9719d911017c592" console.log('Обработано байт:', result.bytesProcessed); // 104857600
Под капотом
Библиотека использует потоковую обработку данных:
// Упрощённая реализация стрима class MD5Stream extends Transform { private hash: any; private bytesProcessed: number = 0; _transform(chunk: Buffer, encoding: string, callback: Function) { this.hash.update(chunk); this.bytesProcessed += chunk.length; this.emit('progress', { bytesProcessed: this.bytesProcessed }); callback(); } _flush(callback: Function) { this.emit('md5', { digest: this.hash.digest('hex'), bytesProcessed: this.bytesProcessed }); callback(); } }
Это позволяет хешировать файлы любого размера без риска переполнения памяти.
TypeScript как citizen first
В 2026 году библиотека без типов — это библиотека второго сорта. pure-md5 написана на TypeScript 5.6+ с полными определениями типов.
// Полная типизация всех API import { md5, hashFile, MD5Result } from 'pure-md5'; const hash: string = md5('hello'); const result: MD5Result = await hashFile('file.txt'); // result.digest: string // result.bytesProcessed: number
Никаких @types/md5, никаких any. Всё работает из коробки.
Бенчмарки
Размер и скорость — критичные метрики для фронтенд-библиотек.
Размер бандла (gzipped)
Библиотека |
Размер |
Зависимости |
|---|---|---|
pure-md5 |
<1KB |
0 |
md5 (pvorb/node-md5) |
~6KB |
3 (charenc, crypt, is-buffer) |
js-md4 |
~2KB |
0 |
blueimp-md5 |
~2KB |
0 |
crypto-js |
~4KB+ |
0 |
spark-md5 |
~3KB |
0 |
Скорость (операций в секунду, Node.js)
Библиотека |
ops/sec |
|---|---|
Node.js crypto |
1,200,000 |
pure-md5 (node adapter) |
1,150,000 |
pure-md5 (pure JS) |
450,000 |
md5 (pvorb) |
~350,000 |
crypto-js |
380,000 |
spark-md5 |
420,000 |
В Node.js pure-md5 почти не уступает нативному crypto благодаря адаптеру. В браузере чистая JS-реализация всё ещё быстрее конкурентов за счёт оптимизаций.
Сравнение с пакетом md5
Пакет md5 (от pvorb/node-md5) — одна из самых популярных реализаций MD5 (2.5M недельных скачиваний). Он работает только в Node.js и использует побайтовую обработку строк, что снижает производительность.
Основные различия:
Характеристика |
pure-md5 |
md5 (pvorb) |
|---|---|---|
Совместимость |
Node.js + Browser |
Только Node.js |
Типизация |
✅ TypeScript из коробки |
❌ Нет типов |
Размер |
<1KB |
~6KB |
Зависимости |
0 |
3 (charenc, crypt, is-buffer) |
Tree-shaking |
✅ Поддерживает |
❌ Нет (CommonJS) |
Stream API |
✅ Встроенный |
❌ Нет |
Адаптеры |
Автоматический выбор |
Только one-size-fits-all |
Производительность |
~1.15M ops/sec |
~350K ops/sec |
Пример использования:
// md5 (pvorb) - только в Node.js import md5 from 'md5'; // Ошибка! Не работает в браузере const hash = md5('hello');
// pure-md5 - универсальное решение import { md5 } from 'pure-md5'; // Работает везде const hash = md5('hello'); // ✅ Node.js const hash2 = md5('hello'); // ✅ Browser
Почему md5 медленнее?
Пакет md5 использует побайтовую обработку и вспомогательные библиотеки для работы с кодировками:
// Пример из md5 (pvorb) const str = new String(string); const bytes = []; for (let i = 0; i < str.length; i++) { bytes.push(str.charCodeAt(i)); } // ... затем обработка массива байт
В pure-md5 используется более эффективный подход — работа с 32-битными словами и оптимизированные циклы.
Практические примеры использования
1. Проверка целостности скачанного файла
import { verifyFile } from 'pure-md5'; const isVerified = await verifyFile( 'downloaded-file.zip', '5d41402abc4b2a76b9719d911017c592' // Ожидаемый хеш от сервера ); if (!isVerified) { throw new Error('Файл повреждён при загрузке'); } // true или false
2. Ключ кэша на основе контента
import { md5 } from 'pure-md5'; function getCacheKey(content: string): string { return `cache:${md5(content)}`; } const key = getCacheKey(JSON.stringify(userData)); // cache:5d41402abc4b2a76b9719d911017c592
3. Универсальное хеширование (Node + Browser)
// Один файл работает везде import { md5 } from 'pure-md5'; export function generateId(data: string | Uint8Array): string { if (data instanceof Uint8Array) { // Для бинарных данных нужно преобразование return md5(new TextDecoder().decode(data)); } return md5(data); } // md5() принимает string или Buffer (Node.js) // Для ArrayBuffer/Uint8Array в браузере используйте hashBinary() через adapter
Безопасность: Где можно и нельзя использовать
Сценарий |
Можно? |
Альтернатива |
|---|---|---|
Контрольные суммы файлов |
✅ |
— |
Ключи кэша |
✅ |
— |
Внутренние ID объектов |
✅ |
— |
Пароли пользователей |
❌ |
bcrypt, argon2 |
JWT токены |
❌ |
HS256, RS256 |
Цифровые подписи |
❌ |
SHA-256, EdDSA |
Правило: Если злоумышленник может получить выгоду от подделки хеша — MD5 не подходит.
Установка и быстрый старт
npm install pure-md5 # или yarn add pure-md5 # или pnpm add pure-md5
import { md5, hashFile, createMD5Stream } from 'pure-md5'; // Строка const hash = md5('hello'); // "5d41402abc4b2a76b9719d911017c592" // Файл const fileHash = await hashFile('path/to/file.txt'); // Стрим const stream = createMD5Stream(); fs.createReadStream('file.bin').pipe(stream);
Заключение
pure-md5 не пытается возродить MD5 для безопасности. Это инструмент для конкретных задач, где MD5 всё ещё используется, но реализация должна быть современной, типизированной и универсальной.
Если вам нужна контрольная сумма файла, ключ кэша или совместимость с легаси-API — pure-md5 даст вам лучший Developer Experience без лишних зависимостей.
Ссылки:
Комментарии (4)

Redduck119
17.02.2026 11:52Мне как то понадобился MD5 в браузере и на стороне сервера(PHP) из-за скорости его работы.
Ничего секретного у меня там не было.

Delagen
17.02.2026 11:52Если не использовать старые браузеры типа IE<11 и уж тем более Node.js, что уж прямо нелогично на сервере, то смысла в этих недообертках вообще нет, так как есть базовый API, его и пользуйте (этот же subtle) доступен со времен гороха, в Node.js как глобальный уже версии чуть ли не с 16, уже 20 с поддержки в апреле снимают. А потом удивляются откуда эти пакеты с зависимостями по несколько тысяч файлов с библиотеками на 3 строки кода или бойлер плейтами для поддержки IE6.
Если взглянуть на результат то как посчитали менее 1КБ вообще не ясно, тупо по размерам взять там js~24kb, cjs~94kb
Единственный плюс от либы это реализация устаревшего алгоритма, который уже из современных стеков выпилен зачастую, но и тут я бы предпочел какую то более совместимую реализацию без кучи полифилов.
Ладно хоть в бандле загрузка не ленивая, а то еще бы породил дополнительные чанки при сборке в браузере

darinavollkova
17.02.2026 11:52Круто, что кто-то наконец сделал MD5 универсальным и с TypeScript. Особенно радует стриминг больших файлов удобно и без риска съесть всю память. Для кэшей и проверок файлов идеальный вариант, без лишнего пафоса безопасности.
nin-jin
2x26 год, какой md5? Возьмите sha-1 хотя бы, и не доверяйте написание криптоалгоритмов нейроболванам.