Baran Topal

Baran Topal


May 2024
M T W T F S S
« Feb    
 12345
6789101112
13141516171819
20212223242526
2728293031  

Categories


CryptoServices in .NET: CRC32

baranbaran

Well, this is a followup of the post

This is the .NET Realm implementation. Note there are 4 other parts to fulfill this cryptoservices completely. Check the above link’s requirements, yet, this is also a standalone module if you implement this as a console library.

To my great surprise, there is actually no direct way to check for cyclic redundancy in .NET. I am extremely astonished once I learnt this fact..

The input file is as follows:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas imperdiet venenatis sodales. Nunc elementum scelerisque nibh, nec pellentesque lacus hendrerit sit amet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras luctus euismod augue, vitae pulvinar est feugiat vitae. Nunc ultricies facilisis mi sed commodo. Aliquam erat volutpat. Etiam id libero nunc. Morbi porttitor porta urna at facilisis.

Quisque at mauris quşam, in tempor odio. Aenean tempus enim quis velit consequat ac molestie sapien malesuada. Fusce mauris tellus, bibendum in scelerisque sit amet, tristique at lectus. Morbi posuere magna sed turpis lacinia ut consequat leo pellentesque. Sed sem orci, dictum non mattis quis, lobortis in diam. Vivamus sed erat ac eros euismod adipiscing eu et dolor. Nulla fringilla erat eu quam fringilla et dapibus quam imperdiet. Nullam a tempus leo. Suspendisse in justo turpis, nec convallis nisl. Donec vulputate, odio viverra euismod placerat, massa risus bibendum mauris, vestibulum fermentum justo metus quis nisl.

Here is the code for you to calculate CRC for a file:


/* 
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 * Company: -								 							 *            
 * Assignment: Cyclic Redundancy Check + 3DES + EF + WCF	             *
 * Deadline: -                           	 							 *
 * Programmer: Baran Topal                   							 *
 * Solution: Crypto					 							         *
 * Project Name: CRC32          	               	 					 *
 * File name: Crc32.cs                       							 *
 *                                           							 *      
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *	                                                                                         *
 *  LICENSE: This source file is subject to have the protection of GNU General               *
 *	Public License. You can distribute the code freely but storing this license information. *
 *	Contact Baran Topal if you have any questions. barantopal@barantopal.com                 *
 *	                                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

// CRC operations, hash calculations
// maybe later, i can explain this, i am tired
namespace CRC32
{
    public class Crc32 : HashAlgorithm
    {
        public const UInt32 DefaultPolynomial = 0xedb8820;
        public const UInt32 DefaultSeed = 0xffffffff;

        private UInt32 hash;
        private UInt32 seed;
        private UInt32[] table;
        private static UInt32[] defaultTable;

        public Crc32()
        {
            table = InitializeTable(DefaultPolynomial);
            seed = DefaultSeed;
            Initialize();
        }

        public Crc32(UInt32 polynomial, UInt32 seed)
        {
            table = InitializeTable(polynomial);
            this.seed = seed;
            Initialize();
        }

        public override void Initialize()
        {
            hash = seed;
        }

        protected override void HashCore(byte[] buffer, int start, int length)
        {
            hash = CalculateHash(table, hash, buffer, start, length);
        }

        protected override byte[] HashFinal()
        {
            byte[] hashBuffer = UInt32ToBigEndianBytes(~hash);
            this.HashValue = hashBuffer;
            return hashBuffer;
        }

        public override int HashSize
        {
            get
            {
                return 32;
            }
        }

        public static UInt32 Compute(byte[] buffer)
        {
            return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length);
        }

        public static UInt32 Compute(UInt32 seed, byte[] buffer)
        {
            return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length);
        }

        public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
        {
            return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
        }

        private static UInt32[] InitializeTable(UInt32 polynomial)
        {
            if (polynomial == DefaultPolynomial && defaultTable != null)
                return defaultTable;

            UInt32[] createTable = new UInt32[256];
            for (int i = 0; i < 256; i++)
            {
                UInt32 entry = (UInt32)i;
                for (int 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;
        }

        private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size)
        {
            UInt32 crc = seed;
            for (int i = start; i < size; i++)
                unchecked
                {
                    crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];
                }
            return crc;
        }

        private byte[] UInt32ToBigEndianBytes(UInt32 x)
        {
            return new byte[] { 
                (byte) ((x >> 24) & 0xff),
                (byte) ((x >> 16) & 0xff),
                (byte) ((x >> 8) & 0xff)                        
            };
        }
    }
}

This can be also as a standalone solution.


/* 
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 * Company: -								 			 *            
 * Assignment: Cyclic Redundancy Check + 3DES + EF + WCF	                                 *
 * Deadline: -                           	 						 *
 * Programmer: Baran Topal                   							 *
 * Solution: Crypto					 					 *
 * Project Name: CRC32          	               	 					 *
 * File name: Program.cs                       							 *
 *                                           							 *      
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *	                                                                                         *
 *  LICENSE: This source file is subject to have the protection of GNU General                   *
 *	Public License. You can distribute the code freely but storing this license information. *
 *	Contact Baran Topal if you have any questions. barantopal@barantopal.com                 *
 *	                                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CRC32
{
    // DLL
    class Program
    {
        /// 
        /// Test data
        /// 
        /// 
        static void Main(string[] args)
        {
            Crc32 crc32 = new Crc32();
            string hash = string.Empty;
            using (FileStream fs = File.Open("loremipsum.txt", FileMode.Open))
                foreach (byte b in crc32.ComputeHash(fs)) hash += b.ToString("x2").ToLower();
            Console.WriteLine("CRC-32 is {0}", hash);
        }
    }
}

Comments 0
There are currently no comments.