diff --git a/SabreTools.Helper/External/OptimizedCRC.cs b/SabreTools.Helper/External/OptimizedCRC.cs
new file mode 100644
index 00000000..92e42e0d
--- /dev/null
+++ b/SabreTools.Helper/External/OptimizedCRC.cs
@@ -0,0 +1,146 @@
+
+/*
+
+ Copyright (c) 2012-2015 Eugene Larchenko (spct@mail.ru)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+*/
+
+using System;
+using System.IO;
+
+namespace CRC32
+{
+ public class OptimizedCRC : IDisposable
+ {
+ private const uint kCrcPoly = 0xEDB88320;
+ private const uint kInitial = 0xFFFFFFFF;
+ private const int CRC_NUM_TABLES = 8;
+ private static readonly uint[] Table;
+
+ static OptimizedCRC()
+ {
+ unchecked
+ {
+ Table = new uint[256 * CRC_NUM_TABLES];
+ int i;
+ for (i = 0; i < 256; i++)
+ {
+ uint r = (uint)i;
+ for (int j = 0; j < 8; j++)
+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+ Table[i] = r;
+ }
+ for (; i < 256 * CRC_NUM_TABLES; i++)
+ {
+ uint r = Table[i - 256];
+ Table[i] = Table[r & 0xFF] ^ (r >> 8);
+ }
+ }
+ }
+
+ private uint value;
+
+ public OptimizedCRC()
+ {
+ Init();
+ }
+
+ ///
+ /// Reset CRC
+ ///
+ public void Init()
+ {
+ value = kInitial;
+ }
+
+ public int Value
+ {
+ get { return (int)~value; }
+ }
+
+ public void Update(byte[] data, int offset, int count)
+ {
+ new ArraySegment(data, offset, count); // check arguments
+ if (count == 0) return;
+
+ var table = OptimizedCRC.Table;
+
+ uint crc = value;
+
+ for (; (offset & 7) != 0 && count != 0; count--)
+ crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
+
+ if (count >= 8)
+ {
+ /*
+ * Idea from 7-zip project sources (http://7-zip.org/sdk.html)
+ */
+
+ int end = (count - 8) & ~7;
+ count -= end;
+ end += offset;
+
+ while (offset != end)
+ {
+ crc ^= (uint)(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) + (data[offset + 3] << 24));
+ uint high = (uint)(data[offset + 4] + (data[offset + 5] << 8) + (data[offset + 6] << 16) + (data[offset + 7] << 24));
+ offset += 8;
+
+ crc = table[(byte)crc + 0x700]
+ ^ table[(byte)(crc >>= 8) + 0x600]
+ ^ table[(byte)(crc >>= 8) + 0x500]
+ ^ table[/*(byte)*/(crc >> 8) + 0x400]
+ ^ table[(byte)(high) + 0x300]
+ ^ table[(byte)(high >>= 8) + 0x200]
+ ^ table[(byte)(high >>= 8) + 0x100]
+ ^ table[/*(byte)*/(high >> 8) + 0x000];
+ }
+ }
+
+ while (count-- != 0)
+ crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
+
+ value = crc;
+ }
+
+ static public int Compute(byte[] data, int offset, int count)
+ {
+ var crc = new OptimizedCRC();
+ crc.Update(data, offset, count);
+ return crc.Value;
+ }
+
+ static public int Compute(byte[] data)
+ {
+ return Compute(data, 0, data.Length);
+ }
+
+ static public int Compute(ArraySegment block)
+ {
+ return Compute(block.Array, block.Offset, block.Count);
+ }
+
+ public void Dispose()
+ {
+ value = 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Helper/SabreTools.Helper.csproj b/SabreTools.Helper/SabreTools.Helper.csproj
index e6215bcc..c94fd167 100644
--- a/SabreTools.Helper/SabreTools.Helper.csproj
+++ b/SabreTools.Helper/SabreTools.Helper.csproj
@@ -85,6 +85,7 @@
+
True
True
@@ -108,7 +109,6 @@
-
diff --git a/SabreTools.Helper/Tools/CRC32.cs b/SabreTools.Helper/Tools/CRC32.cs
deleted file mode 100644
index 4cd9741c..00000000
--- a/SabreTools.Helper/Tools/CRC32.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) Damien Guard. All rights reserved.
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-// Originally published at http://damieng.com/blog/2006/08/08/calculating_crc32_in_c_and_net
-
-using System;
-using System.Collections.Generic;
-using System.Security.Cryptography;
-
-namespace DamienG.Security.Cryptography
-{
- ///
- /// Implements a 32-bit CRC hash algorithm compatible with Zip etc.
- ///
- ///
- /// Crc32 should only be used for backward compatibility with older file formats
- /// and algorithms. It is not secure enough for new applications.
- /// If you need to call multiple times for the same data either use the HashAlgorithm
- /// interface or remember that the result of one Compute call needs to be ~ (XOR) before
- /// being passed in as the seed for the next Compute call.
- ///
- public sealed class Crc32 : HashAlgorithm
- {
- public const UInt32 DefaultPolynomial = 0xedb88320u;
- public const UInt32 DefaultSeed = 0xffffffffu;
-
- static UInt32[] defaultTable;
-
- readonly UInt32 seed;
- readonly UInt32[] table;
- UInt32 hash;
-
- public Crc32()
- : this(DefaultPolynomial, DefaultSeed)
- {
- }
-
- public Crc32(UInt32 polynomial, UInt32 seed)
- {
- table = InitializeTable(polynomial);
- this.seed = hash = seed;
- }
-
- public override void Initialize()
- {
- hash = seed;
- }
-
- protected override void HashCore(byte[] array, int ibStart, int cbSize)
- {
- hash = CalculateHash(table, hash, array, ibStart, cbSize);
- }
-
- protected override byte[] HashFinal()
- {
- var hashBuffer = UInt32ToBigEndianBytes(~hash);
- HashValue = hashBuffer;
- return hashBuffer;
- }
-
- public override int HashSize { get { return 32; } }
-
- public static UInt32 Compute(byte[] buffer)
- {
- return Compute(DefaultSeed, buffer);
- }
-
- public static UInt32 Compute(UInt32 seed, byte[] buffer)
- {
- return Compute(DefaultPolynomial, seed, buffer);
- }
-
- public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
- {
- return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
- }
-
- static UInt32[] InitializeTable(UInt32 polynomial)
- {
- if (polynomial == DefaultPolynomial && defaultTable != null)
- return defaultTable;
-
- var createTable = new UInt32[256];
- for (var i = 0; i < 256; i++)
- {
- var entry = (UInt32)i;
- for (var j = 0; j < 8; j++)
- if ((entry & 1) == 1)
- entry = (entry >> 1) ^ polynomial;
- else
- entry = entry >> 1;
- createTable[i] = entry;
- }
-
- if (polynomial == DefaultPolynomial)
- defaultTable = createTable;
-
- return createTable;
- }
-
- static UInt32 CalculateHash(UInt32[] table, UInt32 seed, IList buffer, int start, int size)
- {
- var crc = seed;
- for (var i = start; i < size - start; i++)
- crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];
- return crc;
- }
-
- static byte[] UInt32ToBigEndianBytes(UInt32 uint32)
- {
- var result = BitConverter.GetBytes(uint32);
-
- if (BitConverter.IsLittleEndian)
- Array.Reverse(result);
-
- return result;
- }
- }
-}
\ No newline at end of file
diff --git a/SabreTools.Helper/Tools/FileTools.cs b/SabreTools.Helper/Tools/FileTools.cs
index d6f56145..7460488f 100644
--- a/SabreTools.Helper/Tools/FileTools.cs
+++ b/SabreTools.Helper/Tools/FileTools.cs
@@ -1,4 +1,4 @@
-using DamienG.Security.Cryptography;
+using CRC32;
using SharpCompress.Archive;
using SharpCompress.Archive.SevenZip;
using SharpCompress.Common;
@@ -608,7 +608,7 @@ namespace SabreTools.Helper
try
{
- using (Crc32 crc = new Crc32())
+ using (OptimizedCRC crc = new OptimizedCRC())
using (MD5 md5 = MD5.Create())
using (SHA1 sha1 = SHA1.Create())
using (FileStream fs = File.OpenRead(input))
@@ -623,7 +623,7 @@ namespace SabreTools.Helper
int read;
while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
{
- crc.TransformBlock(buffer, 0, read, buffer, 0);
+ crc.Update(buffer, 0, read);
if (!noMD5)
{
md5.TransformBlock(buffer, 0, read, buffer, 0);
@@ -634,8 +634,8 @@ namespace SabreTools.Helper
}
}
- crc.TransformFinalBlock(buffer, 0, 0);
- rom.HashData.CRC = BitConverter.ToString(crc.Hash).Replace("-", "").ToLowerInvariant();
+ crc.Update(buffer, 0, 0);
+ rom.HashData.CRC = crc.Value.ToString("X8").ToLowerInvariant();
if (!noMD5)
{