From c0f6d04cb0a8d595b645673f4c9e4fc2392e1807 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 2 Feb 2015 19:16:35 +0000 Subject: [PATCH] Added Adler-32 checksum --- SharpHash/Checksums/Adler32Context.cs | 176 ++++++++++++++++++++++++++ SharpHash/Program.cs | 9 ++ SharpHash/SharpHash.csproj | 1 + 3 files changed, 186 insertions(+) create mode 100644 SharpHash/Checksums/Adler32Context.cs diff --git a/SharpHash/Checksums/Adler32Context.cs b/SharpHash/Checksums/Adler32Context.cs new file mode 100644 index 0000000..d34ff99 --- /dev/null +++ b/SharpHash/Checksums/Adler32Context.cs @@ -0,0 +1,176 @@ +// +// Adler32Context.cs +// +// Author: +// Natalia Portillo +// +// Copyright (c) 2015 © Claunia.com +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Text; +using System.IO; + +namespace SharpHash.Checksums +{ + public class Adler32Context + { + private UInt16 sum1, sum2; + private const UInt16 AdlerModule = 65521; + + /// + /// Initializes the Adler-32 sums + /// + public void Init() + { + sum1 = 1; + sum2 = 0; + } + + /// + /// Updates the hash with data. + /// + /// Data buffer. + /// Length of buffer to hash. + public void Update(byte[] data, uint len) + { + for (int i = 0; i < len; i++) + { + sum1 = (ushort)((sum1 + data[i]) % AdlerModule); + sum2 = (ushort)((sum2 + sum1) % AdlerModule); + } + } + + /// + /// Updates the hash with data. + /// + /// Data buffer. + public void Update(byte[] data) + { + Update(data, (uint)data.Length); + } + + /// + /// Returns a byte array of the hash value. + /// + public byte[] Final() + { + UInt32 finalSum = (uint)((sum2 << 16) | sum1); + return BigEndianBitConverter.GetBytes(finalSum); + } + + /// + /// Returns a hexadecimal representation of the hash value. + /// + public string End() + { + UInt32 finalSum = (uint)((sum2 << 16) | sum1); + StringBuilder adlerOutput = new StringBuilder(); + + for (int i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++) + { + adlerOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2")); + } + + return adlerOutput.ToString(); + } + + /// + /// Gets the hash of a file + /// + /// File path. + public static byte[] File(string filename) + { + byte[] hash; + File(filename, out hash); + return hash; + } + + /// + /// Gets the hash of a file in hexadecimal and as a byte array. + /// + /// File path. + /// Byte array of the hash value. + public static string File(string filename, out byte[] hash) + { + FileStream fileStream = new FileStream(filename, FileMode.Open); + UInt16 localSum1, localSum2; + UInt32 finalSum; + + localSum1 = 1; + localSum2 = 0; + + localSum1 = (ushort)((localSum1 + fileStream.ReadByte()) % AdlerModule); + localSum2 = (ushort)((localSum2 + localSum1) % AdlerModule); + + finalSum = (uint)((localSum2 << 16) | localSum1); + + hash = BitConverter.GetBytes(finalSum); + + StringBuilder adlerOutput = new StringBuilder(); + + for (int i = 0; i < hash.Length; i++) + { + adlerOutput.Append(hash[i].ToString("x2")); + } + + return adlerOutput.ToString(); + } + + /// + /// Gets the hash of the specified data buffer. + /// + /// Data buffer. + /// Length of the data buffer to hash. + /// Byte array of the hash value. + public string Data(byte[] data, uint len, out byte[] hash) + { + UInt16 localSum1, localSum2; + UInt32 finalSum; + + localSum1 = 1; + localSum2 = 0; + + for (int i = 0; i < len; i++) + { + localSum1 = (ushort)((localSum1 + data[i]) % AdlerModule); + localSum2 = (ushort)((localSum2 + localSum1) % AdlerModule); + } + + finalSum = (uint)((localSum2 << 16) | localSum1); + + hash = BitConverter.GetBytes(finalSum); + + StringBuilder adlerOutput = new StringBuilder(); + + for (int i = 0; i < hash.Length; i++) + { + adlerOutput.Append(hash[i].ToString("x2")); + } + + return adlerOutput.ToString(); + } + + /// + /// Gets the hash of the specified data buffer. + /// + /// Data buffer. + /// Byte array of the hash value. + public string Data(byte[] data, out byte[] hash) + { + return Data(data, (uint)data.Length, out hash); + } + } +} + diff --git a/SharpHash/Program.cs b/SharpHash/Program.cs index 07d3327..0106de1 100644 --- a/SharpHash/Program.cs +++ b/SharpHash/Program.cs @@ -77,6 +77,10 @@ namespace SharpHash Checksums.Fletcher32Context fletcher32Context = new Checksums.Fletcher32Context(); fletcher32Context.Init(); + Console.WriteLine("Initializing Adler-32..."); + Checksums.Adler32Context adler32Context = new Checksums.Adler32Context(); + adler32Context.Init(); + Console.WriteLine("Initializing MD5..."); Checksums.MD5Context md5Context = new Checksums.MD5Context(); md5Context.Init(); @@ -120,6 +124,7 @@ namespace SharpHash crc64Context.Update(dataBuffer); fletcher16Context.Update(dataBuffer); fletcher32Context.Update(dataBuffer); + adler32Context.Update(dataBuffer); md5Context.Update(dataBuffer); ripemd160Context.Update(dataBuffer); sha1Context.Update(dataBuffer); @@ -137,6 +142,7 @@ namespace SharpHash crc64Context.Update(dataBuffer); fletcher16Context.Update(dataBuffer); fletcher32Context.Update(dataBuffer); + adler32Context.Update(dataBuffer); md5Context.Update(dataBuffer); ripemd160Context.Update(dataBuffer); sha1Context.Update(dataBuffer); @@ -155,6 +161,7 @@ namespace SharpHash crc64Context.Update(dataBuffer); fletcher16Context.Update(dataBuffer); fletcher32Context.Update(dataBuffer); + adler32Context.Update(dataBuffer); md5Context.Update(dataBuffer); ripemd160Context.Update(dataBuffer); sha1Context.Update(dataBuffer); @@ -169,6 +176,7 @@ namespace SharpHash byte[] crc64Hash = crc64Context.Final(); byte[] fletcher16Hash = fletcher16Context.Final(); byte[] fletcher32Hash = fletcher32Context.Final(); + byte[] adler32Hash = adler32Context.Final(); byte[] md5Hash = md5Context.Final(); byte[] ripemd160Hash = ripemd160Context.Final(); byte[] sha1Hash = sha1Context.Final(); @@ -183,6 +191,7 @@ namespace SharpHash Console.WriteLine("CRC64: {0}", stringify(crc64Hash)); Console.WriteLine("Fletcher-16: {0}", stringify(fletcher16Hash)); Console.WriteLine("Fletcher-32: {0}", stringify(fletcher32Hash)); + Console.WriteLine("Adler-32: {0}", stringify(adler32Hash)); Console.WriteLine("MD5: {0}", stringify(md5Hash)); Console.WriteLine("RIPEMD160: {0}", stringify(ripemd160Hash)); Console.WriteLine("SHA1: {0}", stringify(sha1Hash)); diff --git a/SharpHash/SharpHash.csproj b/SharpHash/SharpHash.csproj index efd46e4..5c5340a 100644 --- a/SharpHash/SharpHash.csproj +++ b/SharpHash/SharpHash.csproj @@ -50,6 +50,7 @@ +