Reading a textfile and calling a class with each text file line How could I get a better performance in my C# application? Or what should I change in my source code?

I would appreciate any kind of help.

This code is reading each line of a textfile which stores values like var1:var2 and calls a class with those values.

Function which calls the class:

private void bunifuFlatButton2_Click(object sender, EventArgs e)
{
    using (var streamReader = File.OpenText(filePath))
    {
        var lines = streamReader.ReadToEnd().Split(new char[] { '\n' });
        var count = lines.Count();

        bunifuProgressBar1.MaximumValue = count;

        for (int i = 0; i &lt; count; i++)
        {
            string[] words = lines[i].Split(':');
            string hash = mega.GenerateHash(words[0].ToLowerInvariant(), mega.PrepareKey(words[1].ToBytes()));

            bunifuCustomLabel4.Text = "Working: Total: " + count + ". Currently: " + (i + 1) + ".";
            bunifuCustomLabel4.Update();
            bunifuProgressBar1.Value = i + 1;
        }
    }
}


The class:

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

namespace MegaTool
{
    public static class mega
    {

        private static readonly Rijndael RijndaelCbc;
        private static readonly byte[] DefaultIv = new byte[16];

        static mega()
        {
            RijndaelCbc = Rijndael.Create();
            RijndaelCbc.Padding = PaddingMode.None;
            RijndaelCbc.Mode = CipherMode.CBC;
        }

        public static byte[] ToBytes(this string data)
        {
            return Encoding.UTF8.GetBytes(data);
        }

        public static byte[] PrepareKey(byte[] data)
        {
            byte[] pkey = new byte[] { 0x93, 0xC4, 0x67, 0xE3, 0x7D, 0xB0, 0xC7, 0xA4, 0xD1, 0xBE, 0x3F, 0x81, 0x01, 0x52, 0xCB, 0x56 };

            for (int it = 0; it &lt; 65536; it++)
            {
                for (int idx = 0; idx &lt; data.Length; idx += 16)
                {
                    byte[] key = data.CopySubArray(16, idx);

                    pkey = EncryptAes(pkey, key);
                }
            }

            return pkey;
        }

        public static byte[] EncryptAes(byte[] data, byte[] key)
        {
            using (ICryptoTransform encryptor = RijndaelCbc.CreateEncryptor(key, DefaultIv))
            {
                return encryptor.TransformFinalBlock(data, 0, data.Length);
            }
        }

        public static T[] CopySubArray&lt;T&gt;(this T[] source, int length, int offset = 0)
        {
            T[] result = new T[length];
            while (--length &gt;= 0)
            {
                if (source.Length &gt; offset + length)
                {
                    result[length] = source[offset + length];
                }
            }

            return result;
        }

        public static string GenerateHash(string email, byte[] passwordAesKey)
        {
            byte[] emailBytes = email.ToBytes();
            byte[] hash = new byte[16];

            for (int i = 0; i &lt; emailBytes.Length; i++)
            {
                hash[i % 16] ^= emailBytes[i];
            }

            for (int it = 0; it &lt; 16384; it++)
            {
                hash = EncryptAes(hash, passwordAesKey);
            }

            byte[] result = new byte[8];
            Array.Copy(hash, 0, result, 0, 4);
            Array.Copy(hash, 8, result, 4, 4);

            return result.ToBase64();
        }

        public static string ToBase64(this byte[] data)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(Convert.ToBase64String(data));
            sb.Replace('+', '-');
            sb.Replace('/', '_');
            sb.Replace("=", string.Empty);

            return sb.ToString();
        }
    }
}
public static T[] CopySubArray&lt;T&gt;(this T[] source, int length, int offset = 0)
{
    T[] result = new T[length];
    while (--length &gt;= 0)
    {
        if (source.Length &gt; offset + length)
        {
            result[length] = source[offset + length];
        }
    }

    return result;
}



I wonder why did you write this method? You can replace it with Array.Copy that, strangely enough, you already use in another place and even the exact same overload:


Array.Copy(hash, 0, result, 0, 4);



Signature:

public static void Copy(
    Array sourceArray,
    int sourceIndex,
    Array destinationArray,
    int destinationIndex,
    int length
)





public static string GenerateHash(string email, byte[] passwordAesKey)



This method should only generate a hash and not an encoded string. Encoding the hash is a responsibility for a different method.




ToBase64



Likewise is this method doing too much. It not only creates a base64 string but also replaces some characters. This should moved to a new method like CleanUpBase64String or whatever it does. It can be private but this kind of custom processing should be encapsulated.



Basically this is how it should look like:

public static byte[] GenerateHash(string email, byte[] passwordAesKey)
{
    ..
}

public static string GenerateHashBase64String(string email, byte[] passwordAesKey)
{
    var hash = GenerateHash(email, passwordAesKey);
    return ToEncodedBase64(hash);
}

public static string ToEncodedBase64(this byte[] data)
{
    var base64String = Convert.ToBase64String(data)
    return CleanUpBase64String(base64String);
}

private static string CleanUpBase64String(string value)
{
    ...
}