Утилиты — криптография, хеширование, сжатие
Криптография
EncryptionHelper
Работа с AES и RSA шифрованием.
AES — симметричное шифрование
// Генерировать ключ из пароля (PBKDF2 + SHA512)
byte[] key = EncryptionHelper.AesCreateKey("myPassword", keyBytes: 32);
byte[] iv = EncryptionHelper.AesCreateIV("myPassword", keyBytes: 16);
// Или полностью случайные
byte[] randomKey = EncryptionHelper.AesGenerateKey(32); // 256-бит
byte[] randomIv = EncryptionHelper.AesGenerateIV();
// Зашифровать/расшифровать
byte[] plaintext = Encoding.UTF8.GetBytes("Secret message");
byte[] encrypted = EncryptionHelper.AesEncrypt(plaintext, key, iv);
byte[] decrypted = EncryptionHelper.AesDecrypt(encrypted, key, iv);
string message = Encoding.UTF8.GetString(decrypted);
RSA — асимметричное шифрование
// Генерировать пару ключей
EncryptionHelper.RsaGenerateKeys(out byte[] privateKey, out byte[] publicKey, keySize: 512);
// Зашифровать открытым ключом (требуется указать padding)
byte[] encrypted = EncryptionHelper.RsaEncrypt(
plaintext,
publicKey,
RSAEncryptionPadding.OaepSHA256, // схема заполнения
keySize: 512);
// Расшифровать приватным ключом
byte[] decrypted = EncryptionHelper.RsaDecrypt(
encrypted,
privateKey,
RSAEncryptionPadding.OaepSHA256,
keySize: 512);
Хеширование паролей
// PBKDF2 для хранения паролей
byte[] hashedPassword = EncryptionHelper.AesCreateKey("password"); // Рекомендуется хранить на основе hash
// Для реального хеширования паролей используйте пользовательское решение или просто AES ключ
Хеширование
HashHelper
SHA и контрольные суммы.
SHA хеширование
// От строки
string sha1 = HashHelper.GenerateSha1("data");
string sha256 = HashHelper.GenerateSha256("data");
string sha384 = HashHelper.GenerateSha384("data");
string sha512 = HashHelper.GenerateSha512("data");
// От массива байт
byte[] data = new byte[] { 1, 2, 3, 4, 5 };
string hash = HashHelper.GenerateSha256(data);
// От потока (для больших файлов)
using var file = File.OpenRead("largefile.bin");
string fileHash = HashHelper.GenerateSha256(file);
CRC контрольные суммы
byte[] data = Encoding.UTF8.GetBytes("Hello");
// CRC-8 (1 байт)
byte crc8 = CRC8.Calculate(data);
// CRC-16 (2 байта)
ushort crc16 = CRC16.Calculate(data);
// CRC-32 (4 байта)
uint crc32 = CRC32.Calculate(data);
Adler контрольные суммы
// Adler-16
ushort adler16 = Adler16.Calculate(data);
// Adler-32
uint adler32 = Adler32.Calculate(data);
Выбор алгоритма
| Алгоритм | Размер | Скорость | Использование |
|---|---|---|---|
| CRC-8 | 1 байт | Очень быстро | Контроль целостности малых данных |
| CRC-32 | 4 байта | Быстро | ZIP, проверка файлов |
| Adler-32 | 4 байта | Быстро | ZIP, потоковые данные |
| SHA-1 | 20 байт | Нормально | Наследие (небезопасно) |
| SHA-256 | 32 байта | Нормально | Стандарт для безопасности |
| SHA-512 | 64 байта | Нормально | Критичные системы |
Сжатие
CompressionHelper
Deflate, GZip, Brotli, LZMA.
byte[] data = new byte[100000];
// ... заполнить данные ...
// Deflate (быстро, среднее сжатие)
byte[] deflateCompressed = CompressionHelper.DeflateCompress(data, CompressionLevel.Optimal);
byte[] deflateDecompressed = CompressionHelper.DeflateDecompress(deflateCompressed);
// GZip (Deflate + заголовок)
byte[] gzipCompressed = CompressionHelper.GZipCompress(data);
byte[] gzipDecompressed = CompressionHelper.GZipDecompress(gzipCompressed);
// Brotli (отличное сжатие, медленнее)
byte[] brotliCompressed = CompressionHelper.BrotliCompress(data);
byte[] brotliDecompressed = CompressionHelper.BrotliDecompress(brotliCompressed);
// LZMA (лучшее сжатие, медленнее всех)
byte[] lzmaCompressed = CompressionHelper.LzmaCompress(data);
byte[] lzmaDecompressed = CompressionHelper.LzmaDecompress(lzmaCompressed);
Асинхронное сжатие
// Для потоков и файлов
byte[] compressed = await CompressionHelper.DeflateCompressAsync(data, CompressionLevel.Optimal);
byte[] decompressed = await CompressionHelper.DeflateDecompressAsync(compressed);
// Работа с потоками
using var sourceStream = File.OpenRead("input.bin");
byte[] compressed = await CompressionHelper.DeflateCompressAsync(sourceStream, CompressionLevel.Optimal);
Выбор алгоритма сжатия
| Алгоритм | Скорость | Сжатие | Использование |
|---|---|---|---|
| Deflate | ⭐⭐⭐⭐⭐ | ⭐⭐ | Быстрая загрузка, стрим |
| GZip | ⭐⭐⭐⭐ | ⭐⭐⭐ | Веб, архивы |
| Brotli | ⭐⭐⭐ | ⭐⭐⭐⭐ | Веб-контент, высокая степень |
| LZMA | ⭐⭐ | ⭐⭐⭐⭐⭐ | Архивы, распределение |
Случайные числа
Random — Xoroshiro128+
Детерминированный PRNG для репроизводимости сценариев.
// Глобальный экземпляр
var rng = Random.Shared;
// Новый с seed для воспроизводимости
var rng = new Random(42);
// Целые числа
ulong ul = rng.NextULong(); // [0, ulong.MaxValue]
long l = rng.NextLong(); // [long.MinValue, long.MaxValue]
long lRange = rng.NextLong(100); // [0, 100)
long lMinMax = rng.NextLong(10, 20); // [10, 20)
// Числа с плавающей точкой
float f = rng.NextFloat(); // [0, 1)
float fRange = rng.NextFloat(1.5f, 3.5f); // [1.5, 3.5)
double d = rng.NextDouble(); // [0, 1)
// Булевы значения
bool b = rng.NextBool(); // 50% true/false
Использование в игре
// Инициализировать со статичным seed для уровня
var levelRng = new Random(levelSeed);
// Генерировать процедурное содержимое детерминировано
for (int i = 0; i < 10; i++)
{
var enemyHealth = levelRng.NextInt(50, 100);
var enemyDamage = levelRng.NextInt(5, 15);
}
Утилиты строк и типов
StringUtils
string str = "hello World";
// Проверки
bool empty = StringUtils.IsEmpty(str);
bool nullOrEmpty = StringUtils.IsNullOrEmpty(str);
bool numeric = StringUtils.IsNumeric(str);
bool uppercase = StringUtils.IsUpperCase(str);
// Преобразования
string upper = StringUtils.ToUpperFirst(str); // "Hello World"
string lower = StringUtils.ToLowerFirst(str); // "hello World"
// Форматирование
string format = StringUtils.Format("Hello {0}", "World");
ReflectionUtils
var type = typeof(MyClass);
var obj = new MyClass();
// Поля и свойства с атрибутами
var serializableProps = ReflectionUtils.GetPropertiesWithAttribute<SerializableFieldAttribute>(type);
// Проверка атрибутов
bool hasAttr = ReflectionUtils.HasAttribute<MyAttribute>(type);
var attr = ReflectionUtils.GetAttribute<MyAttribute>(type);
// Вызов методов через рефлексию
object result = ReflectionUtils.InvokeMethod(obj, "MethodName", arg1, arg2);
// Получение значений полей
object fieldValue = ReflectionUtils.GetFieldValue(obj, "fieldName");
ReflectionUtils.SetFieldValue(obj, "fieldName", newValue);
Практические примеры
Безопасное сохранение конфигурации
public class AppConfig
{
public string ApiKey { get; set; }
public string DatabasePassword { get; set; }
public Dictionary<string, string> Settings { get; set; }
}
var config = new AppConfig
{
ApiKey = "secret-key-123",
DatabasePassword = "db-pass-456",
Settings = new() { { "debug", "false" } }
};
// Сохранить с шифрованием
var configJson = JsonUtils.Serialize(config);
byte[] configBytes = Encoding.UTF8.GetBytes(configJson);
byte[] key = EncryptionHelper.AesCreateKey("masterPassword");
byte[] iv = EncryptionHelper.AesCreateIV("masterPassword");
byte[] encrypted = EncryptionHelper.AesEncrypt(configBytes, key, iv);
await File.WriteAllBytesAsync("config.encrypted", encrypted);
// Загрузить и расшифровать
byte[] encryptedData = await File.ReadAllBytesAsync("config.encrypted");
byte[] decrypted = EncryptionHelper.AesDecrypt(encryptedData, key, iv);
var decryptedJson = Encoding.UTF8.GetString(decrypted);
var loadedConfig = JsonUtils.Deserialize<AppConfig>(decryptedJson);
Проверка целостности файлов
// Сохранить файл с хешем
byte[] fileData = await File.ReadAllBytesAsync("data.bin");
string sha256Hash = HashHelper.GenerateSha256(fileData);
await File.WriteAllTextAsync("data.bin.sha256", sha256Hash);
// Позже: проверить целостность
var loadedData = await File.ReadAllBytesAsync("data.bin");
var storedHash = await File.ReadAllTextAsync("data.bin.sha256");
var currentHash = HashHelper.GenerateSha256(loadedData);
if (currentHash == storedHash)
Console.WriteLine("✓ Файл не повреждён");
else
Console.WriteLine("✗ Файл повреждён или изменён!");
Процедурная генерация с deterministic RNG
// Одно семя — одинаковый результат всегда
ulong dungeonSeed = 12345;
var dungeonRng = new Random(dungeonSeed);
// Комнаты с одинаковой конфигурацией при одном seed
List<(int width, int height, int enemies)> GenerateDungeonLayout()
{
var layout = new List<(int, int, int)>();
for (int i = 0; i < 10; i++)
{
int width = dungeonRng.NextInt(5, 15);
int height = dungeonRng.NextInt(5, 15);
int enemies = dungeonRng.NextInt(1, 5);
layout.Add((width, height, enemies));
}
return layout;
}
var layout1 = GenerateDungeonLayout();
var layout2 = GenerateDungeonLayout(); // Идентично layout1, т.к. одинаковый seed
© 2026 Igdrasil Project. Все права защищены.