Files
Wand-Enhancer/AsarSharp/Integrity/IntegrityHelper.cs
T
kitbyte 13759b1db6 feat: ship 1.0.8.0 release automation and runtime overhaul
- reduce ASAR IO overhead with streamed archive reads, buffered copies, faster relative-path handling and placeholder integrity records
- fix in-place app.asar.unpacked packing/extraction self-copy cases that caused locked-file failures
- tighten JS patch discovery with candidate bundle filters and search hints
- require prebuilt remote-panel dist artifacts and clean up embedded bridge/script packaging
- add unified build entrypoints for PowerShell, cmd and bash and move native CMake output under .tmp
- add release metadata validation, changelog section extraction, pre-commit hook and GitHub Actions validation/release pipelines
- make CHANGELOG the source of truth for release notes and document the tag-driven release flow
- add updater release notes UI with latest/full changelog loading and localize the new update strings
- modularize bridge renderer scripts, add installed apps and game status sync, and support remote launch/stop commands
- centralize bridge protocol, IPC and WebSocket constants and improve LAN IP selection for QR pairing
- refactor remote panel controls/state enums, persist accent color, polish library/session UI and refresh assets
2026-05-06 13:07:09 +03:00

85 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using Newtonsoft.Json;
namespace AsarSharp.Integrity
{
public static class IntegrityHelper
{
private const string ALGORITHM = "SHA256";
// 4MB default block size
private const int BLOCK_SIZE = 4 * 1024 * 1024;
private static readonly char[] HexDigits = "0123456789abcdef".ToCharArray();
public class FileIntegrity
{
[JsonProperty("algorithm")]
public string Algorithm { get; set; }
[JsonProperty("hash")]
public string Hash { get; set; }
[JsonProperty("blockSize")]
public int BlockSize { get; set; }
[JsonProperty("blocks")]
public List<string> Blocks { get; set; }
}
public static FileIntegrity GetFileIntegrity(string path)
{
using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, BLOCK_SIZE, FileOptions.SequentialScan))
using(var fileHash = SHA256.Create())
using (var blockHash = SHA256.Create())
{
int estimatedBlockCount = fileStream.Length > 0
? (int)((fileStream.Length + BLOCK_SIZE - 1) / BLOCK_SIZE)
: 0;
var blockHashes = new List<string>(estimatedBlockCount);
var buffer = new byte[BLOCK_SIZE];
int bytesRead;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
blockHashes.Add(HashBlock(blockHash, buffer, bytesRead));
fileHash.TransformBlock(buffer, 0, bytesRead, null, 0);
}
fileHash.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
return new FileIntegrity
{
Algorithm = ALGORITHM,
Hash = ToLowerHex(fileHash.Hash),
BlockSize = BLOCK_SIZE,
Blocks = blockHashes,
};
}
}
private static string HashBlock(HashAlgorithm hashAlgorithm, byte[] buffer, int bytesRead)
{
return ToLowerHex(hashAlgorithm.ComputeHash(buffer, 0, bytesRead));
}
private static string ToLowerHex(byte[] bytes)
{
if (bytes == null || bytes.Length == 0)
{
return string.Empty;
}
var chars = new char[bytes.Length * 2];
for (int index = 0; index < bytes.Length; index++)
{
byte value = bytes[index];
chars[index * 2] = HexDigits[value >> 4];
chars[index * 2 + 1] = HexDigits[value & 0x0F];
}
return new string(chars);
}
}
}