Rework gen3 crc32 to not require a new obj for byte[]

removes toarray in favor of iterating over the source array
maybe with the next c# (span)...
This commit is contained in:
Kurt 2017-12-04 16:13:18 -08:00
parent 1007c5ddb8
commit 5a69f1d596
2 changed files with 28 additions and 13 deletions

View File

@ -219,9 +219,10 @@ protected override void SetChecksums()
{
for (int i = 0; i < BLOCK_COUNT; i++)
{
byte[] chunk = Data.Skip(ABO + i*SIZE_BLOCK).Take(chunkLength[BlockOrder[i]]).ToArray();
ushort chk = SaveUtil.CRC32(chunk);
BitConverter.GetBytes(chk).CopyTo(Data, ABO + i*SIZE_BLOCK + 0xFF6);
int ofs = ABO + i * SIZE_BLOCK;
int len = chunkLength[BlockOrder[i]];
ushort chk = SaveUtil.CRC32(Data, ofs, len);
BitConverter.GetBytes(chk).CopyTo(Data, ofs + 0xFF6);
}
}
public override bool ChecksumsValid
@ -230,9 +231,10 @@ public override bool ChecksumsValid
{
for (int i = 0; i < BLOCK_COUNT; i++)
{
byte[] chunk = Data.Skip(ABO + i * SIZE_BLOCK).Take(chunkLength[BlockOrder[i]]).ToArray();
ushort chk = SaveUtil.CRC32(chunk);
if (chk != BitConverter.ToUInt16(Data, ABO + i*SIZE_BLOCK + 0xFF6))
int ofs = ABO + i * SIZE_BLOCK;
int len = chunkLength[BlockOrder[i]];
ushort chk = SaveUtil.CRC32(Data, ofs, len);
if (chk != BitConverter.ToUInt16(Data, ofs + 0xFF6))
return false;
}
return true;
@ -245,10 +247,10 @@ public override string ChecksumInfo
var list = new List<string>();
for (int i = 0; i < BLOCK_COUNT; i++)
{
byte[] chunk = Data.Skip(ABO + i * SIZE_BLOCK).Take(chunkLength[BlockOrder[i]]).ToArray();
ushort chk = SaveUtil.CRC32(chunk);
ushort old = BitConverter.ToUInt16(Data, ABO + i*SIZE_BLOCK + 0xFF6);
if (chk != old)
int ofs = ABO + i * SIZE_BLOCK;
int len = chunkLength[BlockOrder[i]];
ushort chk = SaveUtil.CRC32(Data, ofs, len);
if (chk != BitConverter.ToUInt16(Data, ofs + 0xFF6))
list.Add($"Block {BlockOrder[i]:00} @ {i*SIZE_BLOCK:X5} invalid.");
}
return list.Any() ? string.Join(Environment.NewLine, list) : "Checksums are valid.";

View File

@ -647,20 +647,33 @@ public static ushort CRC16(byte[] data, int start, int length, ushort initial =
chk = (ushort) (crc16[(data[i] ^ chk) & 0xFF] ^ chk >> 8);
return (ushort)~chk;
}
/// <summary>Calculates the 32bit checksum over an input byte array. Used in GBA save files.</summary>
/// <param name="data">Input byte array</param>
/// <param name="initial">Initial value for checksum</param>
/// <returns>Checksum</returns>
public static ushort CRC16(byte[] data, ushort initial = 0) => CRC16(data, 0, data.Length, initial);
public static byte[] Resign7(byte[] sav7)
{
return MemeCrypto.Resign7(sav7);
}
/// <summary>Calculates the 32bit checksum over an input byte array. Used in GBA save files.</summary>
/// <param name="data">Input byte array</param>
/// <param name="start">Offset to start checksum at</param>
/// <param name="length">Length of array to checksum</param>
/// <param name="initial">Initial value for checksum</param>
/// <returns>Checksum</returns>
public static ushort CRC32(byte[] data)
public static ushort CRC32(byte[] data, int start, int length, uint initial = 0)
{
uint val = 0;
for (int i = 0; i < data.Length; i += 4)
uint val = initial;
for (int i = start; i < start + length; i += 4)
val += BitConverter.ToUInt32(data, i);
return (ushort)(val + (val >> 16));
}
/// <summary>Calculates the 32bit checksum over an input byte array. Used in GBA save files.</summary>
/// <param name="data">Input byte array</param>
/// <param name="initial">Initial value for checksum</param>
/// <returns>Checksum</returns>
public static ushort CRC32(byte[] data, uint initial = 0) => CRC32(data, 0, data.Length, initial);
private static void CheckHeaderFooter(ref byte[] input, ref byte[] header, ref byte[] footer)
{
if (input.Length > SIZE_G4RAW) // DeSmuME Gen4/5 DSV