Утилиты — криптография, хеширование, сжатие

Криптография

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. Все права защищены.