Add supprot for SimpleCrypt32 of Entis

This commit is contained in:
akiWagashi
2026-03-15 01:09:55 +08:00
parent 612eb2d0ad
commit 3ba4ef5e4e
2 changed files with 44 additions and 0 deletions

View File

@@ -29,6 +29,7 @@ using System.ComponentModel.Composition;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using GameRes.Formats.Strings;
@@ -131,6 +132,15 @@ namespace GameRes.Formats.Entis
if (EncType.Raw == nent.Encryption || null == narc || null == narc.Password)
return input;
if (EncType.SimpleCrypt32 == nent.Encryption)
{
if (0 != size % 4)
throw new InvalidFormatException();
using (input)
return DecodeSimpleCrypt32 (input, narc.Password, BitConverter.ToUInt32(nent.Extra, 4));
}
if (EncType.BSHFCrypt == nent.Encryption)
{
using (input)
@@ -239,6 +249,40 @@ namespace GameRes.Formats.Entis
return new MemoryStream (buf);
}
Stream DecodeSimpleCrypt32(Stream input, string password, uint imul_key)
{
var xor_key_map = Encoding.UTF8.GetBytes(password);
var password_crc32 = Crc32.Compute(xor_key_map, 0, xor_key_map.Length);
imul_key ^= password_crc32;
for (int i = 0; i < xor_key_map.Length; i++)
{
byte key_byte = (byte)~xor_key_map[i];
xor_key_map[i] = (byte)(key_byte ^ (key_byte * 7));
}
byte[] buffer = new byte[input.Length];
input.Read(buffer, 0, (int)input.Length);
Span<uint> buffer_span = MemoryMarshal.Cast<byte, uint>(buffer);
ReadOnlySpan<uint> xor_key_span = MemoryMarshal.Cast<byte, uint>(xor_key_map);
for(int i = 0; i < buffer_span.Length; i += xor_key_span.Length)
{
int window_size = Math.Min(buffer_span.Length - i, xor_key_span.Length);
Span<uint> window_span = buffer_span.Slice(i, window_size);
for (int j = 0; j < window_size; j++)
{
window_span[j] = (window_span[j] * imul_key) ^ xor_key_span[j];
}
}
return new MemoryStream(buffer);
}
public override ResourceOptions GetDefaultOptions ()
{
return new NoaOptions {

View File

Binary file not shown.