From 72740566ae06e153ab31bb71fd72f4e830ba09b5 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 3 Feb 2018 21:25:37 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9BFix=20Fletcher-16=20and=20Fletcher-?= =?UTF-8?q?32=20speed.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DiscImageChef.Checksums/FletcherContext.cs | 205 ++++++--------------- DiscImageChef.Core/Benchmark.cs | 68 ++++++- DiscImageChef.Core/Checksum.cs | 117 ++++++++++-- DiscImageChef/Commands/Checksum.cs | 4 + DiscImageChef/Options.cs | 4 +- 5 files changed, 230 insertions(+), 168 deletions(-) diff --git a/DiscImageChef.Checksums/FletcherContext.cs b/DiscImageChef.Checksums/FletcherContext.cs index 0c1edf9e..21ceaba9 100644 --- a/DiscImageChef.Checksums/FletcherContext.cs +++ b/DiscImageChef.Checksums/FletcherContext.cs @@ -38,21 +38,21 @@ using System.Text; namespace DiscImageChef.Checksums { + /// + /// Implements the Fletcher-32 algorithm + /// public class Fletcher32Context : IChecksum { - bool inodd; - byte oddValue; - ushort sum1, sum2; + const ushort FLETCHER_MODULE = 0xFFFF; + ushort sum1, sum2; /// - /// Initializes the Fletcher32 sums + /// Initializes the Fletcher-32 sums /// public Fletcher32Context() { - sum1 = 0xFFFF; - sum2 = 0xFFFF; - oddValue = 0; - inodd = false; + sum1 = 0xFFFF; + sum2 = 0xFFFF; } /// @@ -62,64 +62,10 @@ namespace DiscImageChef.Checksums /// Length of buffer to hash. public void Update(byte[] data, uint len) { - ushort block; - if(!inodd) - if(len % 2 != 0) - { - oddValue = data[len - 1]; - inodd = true; - - for(int i = 0; i < len - 1; i += 2) - { - block = BigEndianBitConverter.ToUInt16(data, i); - sum1 = (ushort)((sum1 + block) % 0xFFFF); - sum2 = (ushort)((sum2 + sum1) % 0xFFFF); - } - } - else - { - inodd = false; - for(int i = 0; i < len; i += 2) - { - block = BigEndianBitConverter.ToUInt16(data, i); - sum1 = (ushort)((sum1 + block) % 0xFFFF); - sum2 = (ushort)((sum2 + sum1) % 0xFFFF); - } - } - // Carrying odd - else + for(int i = 0; i < len; i++) { - byte[] oddData = new byte[2]; - oddData[0] = oddValue; - oddData[1] = data[0]; - - block = BigEndianBitConverter.ToUInt16(oddData, 0); - sum1 = (ushort)((sum1 + block) % 0xFFFF); - sum2 = (ushort)((sum2 + sum1) % 0xFFFF); - - // Even size, carrying odd - if(len % 2 == 0) - { - oddValue = data[len - 1]; - inodd = true; - - for(int i = 1; i < len - 1; i += 2) - { - block = BigEndianBitConverter.ToUInt16(data, i); - sum1 = (ushort)((sum1 + block) % 0xFFFF); - sum2 = (ushort)((sum2 + sum1) % 0xFFFF); - } - } - else - { - inodd = false; - for(int i = 1; i < len; i += 2) - { - block = BigEndianBitConverter.ToUInt16(data, i); - sum1 = (ushort)((sum1 + block) % 0xFFFF); - sum2 = (ushort)((sum2 + sum1) % 0xFFFF); - } - } + sum1 = (ushort)((sum1 + data[i]) % FLETCHER_MODULE); + sum2 = (ushort)((sum2 + sum1) % FLETCHER_MODULE); } } @@ -137,7 +83,8 @@ namespace DiscImageChef.Checksums /// public byte[] Final() { - uint finalSum = (uint)(sum1 + (sum2 << 16)); + uint finalSum = (uint)((sum2 << 16) | sum1); + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; return BigEndianBitConverter.GetBytes(finalSum); } @@ -146,9 +93,10 @@ namespace DiscImageChef.Checksums /// public string End() { - uint finalSum = (uint)(sum1 + (sum2 << 16)); + uint finalSum = (uint)((sum2 << 16) | sum1); StringBuilder fletcherOutput = new StringBuilder(); + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; for(int i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++) fletcherOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2")); @@ -173,49 +121,27 @@ namespace DiscImageChef.Checksums public static string File(string filename, out byte[] hash) { FileStream fileStream = new FileStream(filename, FileMode.Open); - ushort block; - byte[] blockBytes; ushort localSum1 = 0xFFFF; ushort localSum2 = 0xFFFF; - if(fileStream.Length % 2 == 0) - for(int i = 0; i < fileStream.Length; i += 2) - { - blockBytes = new byte[2]; - fileStream.Read(blockBytes, 0, 2); - block = BigEndianBitConverter.ToUInt16(blockBytes, 0); - localSum1 = (ushort)((localSum1 + block) % 0xFFFF); - localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF); - } - else + for(int i = 0; i < fileStream.Length; i++) { - for(int i = 0; i < fileStream.Length - 1; i += 2) - { - blockBytes = new byte[2]; - fileStream.Read(blockBytes, 0, 2); - block = BigEndianBitConverter.ToUInt16(blockBytes, 0); - localSum1 = (ushort)((localSum1 + block) % 0xFFFF); - localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF); - } - - byte[] oddData = new byte[2]; - oddData[0] = (byte)fileStream.ReadByte(); - oddData[1] = 0; - - block = BigEndianBitConverter.ToUInt16(oddData, 0); - localSum1 = (ushort)((localSum1 + block) % 0xFFFF); - localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF); + localSum1 = (ushort)((localSum1 + fileStream.ReadByte()) % FLETCHER_MODULE); + localSum2 = (ushort)((localSum2 + localSum1) % FLETCHER_MODULE); } - uint finalSum = (uint)(localSum1 + (localSum2 << 16)); + uint finalSum = (uint)((localSum2 << 16) | localSum1); - hash = BitConverter.GetBytes(finalSum); + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + hash = BigEndianBitConverter.GetBytes(finalSum); StringBuilder fletcherOutput = new StringBuilder(); foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2")); + fileStream.Close(); + return fletcherOutput.ToString(); } @@ -227,45 +153,25 @@ namespace DiscImageChef.Checksums /// Byte array of the hash value. public static string Data(byte[] data, uint len, out byte[] hash) { - ushort block; - ushort localSum1 = 0xFFFF; ushort localSum2 = 0xFFFF; - if(len % 2 == 0) - for(int i = 0; i < len; i += 2) - { - block = BigEndianBitConverter.ToUInt16(data, i); - localSum1 = (ushort)((localSum1 + block) % 0xFFFF); - localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF); - } - else + for(int i = 0; i < len; i++) { - for(int i = 0; i < len - 1; i += 2) - { - block = BigEndianBitConverter.ToUInt16(data, i); - localSum1 = (ushort)((localSum1 + block) % 0xFFFF); - localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF); - } - - byte[] oddData = new byte[2]; - oddData[0] = data[len - 1]; - oddData[1] = 0; - - block = BigEndianBitConverter.ToUInt16(oddData, 0); - localSum1 = (ushort)((localSum1 + block) % 0xFFFF); - localSum2 = (ushort)((localSum2 + localSum1) % 0xFFFF); + localSum1 = (ushort)((localSum1 + data[i]) % FLETCHER_MODULE); + localSum2 = (ushort)((localSum2 + localSum1) % FLETCHER_MODULE); } - uint finalSum = (uint)(localSum1 + (localSum2 << 16)); + uint finalSum = (uint)((localSum2 << 16) | localSum1); - hash = BitConverter.GetBytes(finalSum); + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + hash = BigEndianBitConverter.GetBytes(finalSum); - StringBuilder fletcherOutput = new StringBuilder(); + StringBuilder adlerOutput = new StringBuilder(); - foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2")); + foreach(byte h in hash) adlerOutput.Append(h.ToString("x2")); - return fletcherOutput.ToString(); + return adlerOutput.ToString(); } /// @@ -279,12 +185,16 @@ namespace DiscImageChef.Checksums } } + /// + /// Implements the Fletcher-16 algorithm + /// public class Fletcher16Context : IChecksum { - byte sum1, sum2; + const byte FLETCHER_MODULE = 0xFF; + byte sum1, sum2; /// - /// Initializes the Fletcher16 sums + /// Initializes the Fletcher-16 sums /// public Fletcher16Context() { @@ -301,8 +211,8 @@ namespace DiscImageChef.Checksums { for(int i = 0; i < len; i++) { - sum1 = (byte)((sum1 + data[i]) % 0xFF); - sum2 = (byte)((sum2 + sum1) % 0xFF); + sum1 = (byte)((sum1 + data[i]) % FLETCHER_MODULE); + sum2 = (byte)((sum2 + sum1) % FLETCHER_MODULE); } } @@ -320,7 +230,8 @@ namespace DiscImageChef.Checksums /// public byte[] Final() { - ushort finalSum = (ushort)(sum1 + (sum2 << 8)); + ushort finalSum = (ushort)((sum2 << 8) | sum1); + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; return BigEndianBitConverter.GetBytes(finalSum); } @@ -329,9 +240,10 @@ namespace DiscImageChef.Checksums /// public string End() { - ushort finalSum = (ushort)(sum1 + (sum2 << 8)); + ushort finalSum = (ushort)((sum2 << 8) | sum1); StringBuilder fletcherOutput = new StringBuilder(); + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; for(int i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++) fletcherOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2")); @@ -360,21 +272,23 @@ namespace DiscImageChef.Checksums byte localSum1 = 0xFF; byte localSum2 = 0xFF; - for(int i = 0; i < fileStream.Length; i += 2) + for(int i = 0; i < fileStream.Length; i++) { - byte block = (byte)fileStream.ReadByte(); - localSum1 = (byte)((localSum1 + block) % 0xFF); - localSum2 = (byte)((localSum2 + localSum1) % 0xFF); + localSum1 = (byte)((localSum1 + fileStream.ReadByte()) % FLETCHER_MODULE); + localSum2 = (byte)((localSum2 + localSum1) % FLETCHER_MODULE); } - ushort finalSum = (ushort)(localSum1 + (localSum2 << 8)); + ushort finalSum = (ushort)((localSum2 << 8) | localSum1); - hash = BitConverter.GetBytes(finalSum); + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + hash = BigEndianBitConverter.GetBytes(finalSum); StringBuilder fletcherOutput = new StringBuilder(); foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2")); + fileStream.Close(); + return fletcherOutput.ToString(); } @@ -391,19 +305,20 @@ namespace DiscImageChef.Checksums for(int i = 0; i < len; i++) { - localSum1 = (byte)((localSum1 + data[i]) % 0xFF); - localSum2 = (byte)((localSum2 + localSum1) % 0xFF); + localSum1 = (byte)((localSum1 + data[i]) % FLETCHER_MODULE); + localSum2 = (byte)((localSum2 + localSum1) % FLETCHER_MODULE); } - ushort finalSum = (ushort)(localSum1 + (localSum2 << 8)); + ushort finalSum = (ushort)((localSum2 << 8) | localSum1); - hash = BitConverter.GetBytes(finalSum); + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + hash = BigEndianBitConverter.GetBytes(finalSum); - StringBuilder fletcherOutput = new StringBuilder(); + StringBuilder adlerOutput = new StringBuilder(); - foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2")); + foreach(byte h in hash) adlerOutput.Append(h.ToString("x2")); - return fletcherOutput.ToString(); + return adlerOutput.ToString(); } /// diff --git a/DiscImageChef.Core/Benchmark.cs b/DiscImageChef.Core/Benchmark.cs index d04ef069..29a9ffad 100644 --- a/DiscImageChef.Core/Benchmark.cs +++ b/DiscImageChef.Core/Benchmark.cs @@ -168,6 +168,70 @@ namespace DiscImageChef.Core }); results.SeparateTime += (end - start).TotalSeconds; #endregion Adler32 + + #region Fletcher16 + ctx = new Fletcher16Context(); + ms.Seek(0, SeekOrigin.Begin); + mem = GC.GetTotalMemory(false); + if(mem > results.MaxMemory) results.MaxMemory = mem; + if(mem < results.MinMemory) results.MinMemory = mem; + start = DateTime.Now; + InitProgress(); + for(int i = 0; i < bufferSize / blockSize; i++) + { + UpdateProgress("Checksumming block {0} of {1} with Fletcher-16.", i + 1, bufferSize / blockSize); + byte[] tmp = new byte[blockSize]; + ms.Read(tmp, 0, blockSize); + ctx.Update(tmp); + } + + EndProgress(); + ctx.End(); + end = DateTime.Now; + mem = GC.GetTotalMemory(false); + if(mem > results.MaxMemory) results.MaxMemory = mem; + if(mem < results.MinMemory) results.MinMemory = mem; + + results.Entries.Add("Fletcher16", + new BenchmarkEntry + { + TimeSpan = (end - start).TotalSeconds, + Speed = bufferSize / 1048576.0 / (end - start).TotalSeconds + }); + results.SeparateTime += (end - start).TotalSeconds; + #endregion Fletcher16 + + #region Fletcher32 + ctx = new Fletcher32Context(); + ms.Seek(0, SeekOrigin.Begin); + mem = GC.GetTotalMemory(false); + if(mem > results.MaxMemory) results.MaxMemory = mem; + if(mem < results.MinMemory) results.MinMemory = mem; + start = DateTime.Now; + InitProgress(); + for(int i = 0; i < bufferSize / blockSize; i++) + { + UpdateProgress("Checksumming block {0} of {1} with Fletcher-32.", i + 1, bufferSize / blockSize); + byte[] tmp = new byte[blockSize]; + ms.Read(tmp, 0, blockSize); + ctx.Update(tmp); + } + + EndProgress(); + ctx.End(); + end = DateTime.Now; + mem = GC.GetTotalMemory(false); + if(mem > results.MaxMemory) results.MaxMemory = mem; + if(mem < results.MinMemory) results.MinMemory = mem; + + results.Entries.Add("Fletcher32", + new BenchmarkEntry + { + TimeSpan = (end - start).TotalSeconds, + Speed = bufferSize / 1048576.0 / (end - start).TotalSeconds + }); + results.SeparateTime += (end - start).TotalSeconds; + #endregion Fletcher32 #region CRC16 ctx = new Crc16Context(); @@ -515,7 +579,7 @@ namespace DiscImageChef.Core results.EntropyTime = (end - start).TotalSeconds; results.EntropySpeed = bufferSize / 1048576.0 / (end - start).TotalSeconds; #endregion Entropy - +/* #region Multitasking start = DateTime.Now; Checksum allChecksums = new Checksum(); @@ -541,7 +605,7 @@ namespace DiscImageChef.Core results.TotalTime = (end - start).TotalSeconds; results.TotalSpeed = bufferSize / 1048576.0 / results.TotalTime; #endregion - +*/ results.SeparateSpeed = bufferSize / 1048576.0 / results.SeparateTime; return results; diff --git a/DiscImageChef.Core/Checksum.cs b/DiscImageChef.Core/Checksum.cs index 638959cf..f5677529 100644 --- a/DiscImageChef.Core/Checksum.cs +++ b/DiscImageChef.Core/Checksum.cs @@ -41,18 +41,20 @@ namespace DiscImageChef.Core [Flags] public enum EnableChecksum { - Adler32 = 1, - Crc16 = 2, - Crc32 = 4, - Crc64 = 8, - Md5 = 16, - Ripemd160 = 32, - Sha1 = 64, - Sha256 = 128, - Sha384 = 256, - Sha512 = 512, - SpamSum = 1024, - All = Adler32 | Crc16 | Crc32 | Crc64 | Md5 | Ripemd160 | Sha1 | Sha256 | Sha384 | Sha512 | SpamSum + Adler32 = 1, + Crc16 = 2, + Crc32 = 4, + Crc64 = 8, + Md5 = 16, + Ripemd160 = 32, + Sha1 = 64, + Sha256 = 128, + Sha384 = 256, + Sha512 = 512, + SpamSum = 1024, + Fletcher16 = 2048, + Fletcher32 = 4096, + All = Adler32 | Crc16 | Crc32 | Crc64 | Md5 | Ripemd160 | Sha1 | Sha256 | Sha384 | Sha512 | SpamSum | Fletcher16 | Fletcher32 } /// @@ -94,6 +96,12 @@ namespace DiscImageChef.Core HashPacket spamsumPkt; Thread spamsumThread; IChecksum ssctx; + HashPacket f16Pkt; + Thread f16Thread; + IChecksum f16Ctx; + HashPacket f32Pkt; + Thread f32Thread; + IChecksum f32Ctx; public Checksum(EnableChecksum enabled = EnableChecksum.All) { @@ -165,6 +173,18 @@ namespace DiscImageChef.Core spamsumPkt = new HashPacket {Context = ssctx}; } + if(enabled.HasFlag(EnableChecksum.Fletcher16)) + { + f16Ctx = new Fletcher16Context(); + f16Pkt = new HashPacket {Context = f16Ctx}; + } + + if(enabled.HasFlag(EnableChecksum.Fletcher32)) + { + f32Ctx = new Fletcher32Context(); + f32Pkt = new HashPacket {Context = f32Ctx}; + } + adlerThread = new Thread(UpdateHash); crc16Thread = new Thread(UpdateHash); crc32Thread = new Thread(UpdateHash); @@ -176,6 +196,8 @@ namespace DiscImageChef.Core sha384Thread = new Thread(UpdateHash); sha512Thread = new Thread(UpdateHash); spamsumThread = new Thread(UpdateHash); + f16Thread = new Thread(UpdateHash); + f32Thread = new Thread(UpdateHash); } public void Update(byte[] data) @@ -246,9 +268,21 @@ namespace DiscImageChef.Core spamsumThread.Start(spamsumPkt); } + if(enabled.HasFlag(EnableChecksum.Fletcher16)) + { + f16Pkt.Data = data; + f16Thread.Start(f16Pkt); + } + + if(enabled.HasFlag(EnableChecksum.Fletcher32)) + { + f32Pkt.Data = data; + f32Thread.Start(f32Pkt); + } + while(adlerThread.IsAlive || crc16Thread.IsAlive || crc32Thread.IsAlive || crc64Thread.IsAlive || md5Thread.IsAlive || ripemd160Thread.IsAlive || sha1Thread.IsAlive || sha256Thread.IsAlive || - sha384Thread.IsAlive || sha512Thread.IsAlive || spamsumThread.IsAlive) { } + sha384Thread.IsAlive || sha512Thread.IsAlive || spamsumThread.IsAlive || f16Thread.IsAlive || f32Thread.IsAlive) { } if(enabled.HasFlag(EnableChecksum.SpamSum)) adlerThread = new Thread(UpdateHash); if(enabled.HasFlag(EnableChecksum.SpamSum)) crc16Thread = new Thread(UpdateHash); @@ -261,6 +295,8 @@ namespace DiscImageChef.Core if(enabled.HasFlag(EnableChecksum.SpamSum)) sha384Thread = new Thread(UpdateHash); if(enabled.HasFlag(EnableChecksum.SpamSum)) sha512Thread = new Thread(UpdateHash); if(enabled.HasFlag(EnableChecksum.SpamSum)) spamsumThread = new Thread(UpdateHash); + if(enabled.HasFlag(EnableChecksum.SpamSum)) f16Thread = new Thread(UpdateHash); + if(enabled.HasFlag(EnableChecksum.SpamSum)) f32Thread = new Thread(UpdateHash); } public List End() @@ -329,9 +365,21 @@ namespace DiscImageChef.Core chks.Add(chk); } - if(!enabled.HasFlag(EnableChecksum.SpamSum)) return chks; + if(enabled.HasFlag(EnableChecksum.SpamSum)) + { + chk = new ChecksumType {type = ChecksumTypeType.spamsum, Value = ssctx.End()}; + chks.Add(chk); + } - chk = new ChecksumType {type = ChecksumTypeType.spamsum, Value = ssctx.End()}; + if(enabled.HasFlag(EnableChecksum.Fletcher16)) + { + chk = new ChecksumType {type = ChecksumTypeType.fletcher16, Value = f16Ctx.End()}; + chks.Add(chk); + } + + if(!enabled.HasFlag(EnableChecksum.Fletcher32)) return chks; + + chk = new ChecksumType {type = ChecksumTypeType.fletcher32, Value = f32Ctx.End()}; chks.Add(chk); return chks; @@ -350,6 +398,8 @@ namespace DiscImageChef.Core IChecksum sha384CtxData = null; IChecksum sha512CtxData = null; IChecksum ssctxData = null; + IChecksum f16ctxData = null; + IChecksum f32ctxData = null; Thread adlerThreadData = new Thread(UpdateHash); Thread crc16ThreadData = new Thread(UpdateHash); @@ -362,6 +412,8 @@ namespace DiscImageChef.Core Thread sha384ThreadData = new Thread(UpdateHash); Thread sha512ThreadData = new Thread(UpdateHash); Thread spamsumThreadData = new Thread(UpdateHash); + Thread f16ThreadData = new Thread(UpdateHash); + Thread f32ThreadData = new Thread(UpdateHash); if(enabled.HasFlag(EnableChecksum.SpamSum)) { @@ -440,10 +492,24 @@ namespace DiscImageChef.Core spamsumThreadData.Start(spamsumPktData); } + if(enabled.HasFlag(EnableChecksum.Fletcher16)) + { + f16ctxData = new Fletcher16Context(); + HashPacket f16PktData = new HashPacket {Context = f16ctxData, Data = data}; + f16ThreadData.Start(f16PktData); + } + + if(enabled.HasFlag(EnableChecksum.Fletcher32)) + { + f32ctxData = new Fletcher32Context(); + HashPacket f32PktData = new HashPacket {Context = f32ctxData, Data = data}; + f32ThreadData.Start(f32PktData); + } + while(adlerThreadData.IsAlive || crc16ThreadData.IsAlive || crc32ThreadData.IsAlive || crc64ThreadData.IsAlive || md5ThreadData.IsAlive || ripemd160ThreadData.IsAlive || sha1ThreadData.IsAlive || sha256ThreadData.IsAlive || sha384ThreadData.IsAlive || - sha512ThreadData.IsAlive || spamsumThreadData.IsAlive) { } + sha512ThreadData.IsAlive || spamsumThreadData.IsAlive || f16ThreadData.IsAlive || f32ThreadData.IsAlive) { } List dataChecksums = new List(); ChecksumType chk; @@ -508,10 +574,23 @@ namespace DiscImageChef.Core dataChecksums.Add(chk); } - if(!enabled.HasFlag(EnableChecksum.SpamSum)) return dataChecksums; + if(enabled.HasFlag(EnableChecksum.SpamSum)) + { + chk = new ChecksumType {type = ChecksumTypeType.spamsum, Value = ssctxData.End()}; + dataChecksums.Add(chk); + } - chk = new ChecksumType {type = ChecksumTypeType.spamsum, Value = ssctxData.End()}; - dataChecksums.Add(chk); + if(enabled.HasFlag(EnableChecksum.Fletcher16)) + { + chk = new ChecksumType {type = ChecksumTypeType.fletcher16, Value = f16ctxData.End()}; + dataChecksums.Add(chk); + } + + if(enabled.HasFlag(EnableChecksum.Fletcher32)) + { + chk = new ChecksumType {type = ChecksumTypeType.fletcher32, Value = f32ctxData.End()}; + dataChecksums.Add(chk); + } return dataChecksums; } diff --git a/DiscImageChef/Commands/Checksum.cs b/DiscImageChef/Commands/Checksum.cs index 73871ae2..1965ab9f 100644 --- a/DiscImageChef/Commands/Checksum.cs +++ b/DiscImageChef/Commands/Checksum.cs @@ -63,6 +63,8 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Checksum command", "--sha384={0}", options.DoSha384); DicConsole.DebugWriteLine("Checksum command", "--sha512={0}", options.DoSha512); DicConsole.DebugWriteLine("Checksum command", "--spamsum={0}", options.DoSpamSum); + DicConsole.DebugWriteLine("Checksum command", "--fletcher16={0}", options.DoFletcher16); + DicConsole.DebugWriteLine("Checksum command", "--fletcher32={0}", options.DoFletcher32); FiltersList filtersList = new FiltersList(); IFilter inputFilter = filtersList.GetFilter(options.InputFile); @@ -98,6 +100,8 @@ namespace DiscImageChef.Commands if(options.DoSha384) enabledChecksums |= EnableChecksum.Sha384; if(options.DoSha512) enabledChecksums |= EnableChecksum.Sha512; if(options.DoSpamSum) enabledChecksums |= EnableChecksum.SpamSum; + if(options.DoFletcher16) enabledChecksums |= EnableChecksum.Fletcher16; + if(options.DoFletcher32) enabledChecksums |= EnableChecksum.Fletcher32; Core.Checksum mediaChecksum = null; diff --git a/DiscImageChef/Options.cs b/DiscImageChef/Options.cs index 980b3944..8cab66d0 100644 --- a/DiscImageChef/Options.cs +++ b/DiscImageChef/Options.cs @@ -93,13 +93,13 @@ namespace DiscImageChef [Option("crc64", Default = false, HelpText = "Calculates CRC64 (ECMA).")] public bool DoCrc64 { get; set; } - /*[Option("fletcher16", Default = false, + [Option("fletcher16", Default = false, HelpText = "Calculates Fletcher-16.")] public bool DoFletcher16 { get; set; } [Option("fletcher32", Default = false, HelpText = "Calculates Fletcher-32.")] - public bool DoFletcher32 { get; set; }*/ + public bool DoFletcher32 { get; set; } [Option('m', "md5", Default = true, HelpText = "Calculates MD5.")] public bool DoMd5 { get; set; }