private static byte[] RijndaelEncryption(byte[] input, byte[] key, bool encrypt, bool parallel = true)
        {
            var algorithm = new Rijndael();
            int InputBlockLen_byte = algorithm.InputBlockLen_bit/8;
            byte[] expandedkey = algorithm.ExpandKey(key);

            if (input.Length > 0 && key.Length > 0)
            {
                int countblocks;
                byte[] output;
                if (encrypt)
                {
                    int bytestoadd = (InputBlockLen_byte - (input.Length + 1)%InputBlockLen_byte)%InputBlockLen_byte;
                    int newinputlen = input.Length + bytestoadd + 1;
                    Array.Resize(ref input, newinputlen);
                    input[input.Length - 1] = (byte) bytestoadd;
                    countblocks = newinputlen/InputBlockLen_byte;
                    output = new byte[newinputlen];
                }
                else
                {
                    countblocks = input.Length/InputBlockLen_byte;
                    output = new byte[input.Length];
                }
                if (parallel)
                {
                    Parallel.For(0, countblocks, delegate(int b)
                    {
                        var block = new byte[InputBlockLen_byte];
                        Buffer.BlockCopy(input, b*InputBlockLen_byte, block, 0, InputBlockLen_byte);
                        block = encrypt
                            ? algorithm.EncryptBlock(block, expandedkey)
                            : algorithm.DecryptBlock(block, expandedkey);
                        Buffer.BlockCopy(block, 0, output, b*InputBlockLen_byte, InputBlockLen_byte);
                    });
                }
                else
                {
                    var block = new byte[InputBlockLen_byte];
                    for (int b = 0; b < countblocks; b++)
                    {
                        Buffer.BlockCopy(input, b*InputBlockLen_byte, block, 0, InputBlockLen_byte);
                        block = encrypt
                            ? algorithm.EncryptBlock(block, expandedkey)
                            : algorithm.DecryptBlock(block, expandedkey);
                        Buffer.BlockCopy(block, 0, output, b*InputBlockLen_byte, InputBlockLen_byte);
                    }
                }
                if (!encrypt)
                {
                    int countbytestoerase = output[output.Length - 1] + 1;

                    int newoutputlenght = output.Length - countbytestoerase;
                    Array.Resize(ref output, newoutputlenght);
                }

                return output;
            }
            return null;
        }
        private static byte[] RijndaelEncryption(byte[] input, byte[] key, bool encrypt, bool parallel = true)
        {
            var algorithm          = new Rijndael();
            int InputBlockLen_byte = algorithm.InputBlockLen_bit / 8;

            byte[] expandedkey = algorithm.ExpandKey(key);

            if (input.Length > 0 && key.Length > 0)
            {
                int    countblocks;
                byte[] output;
                if (encrypt)
                {
                    int bytestoadd  = (InputBlockLen_byte - (input.Length + 1) % InputBlockLen_byte) % InputBlockLen_byte;
                    int newinputlen = input.Length + bytestoadd + 1;
                    Array.Resize(ref input, newinputlen);
                    input[input.Length - 1] = (byte)bytestoadd;
                    countblocks             = newinputlen / InputBlockLen_byte;
                    output = new byte[newinputlen];
                }
                else
                {
                    countblocks = input.Length / InputBlockLen_byte;
                    output      = new byte[input.Length];
                }
                if (parallel)
                {
                    Parallel.For(0, countblocks, delegate(int b)
                    {
                        var block = new byte[InputBlockLen_byte];
                        Buffer.BlockCopy(input, b * InputBlockLen_byte, block, 0, InputBlockLen_byte);
                        block = encrypt
                            ? algorithm.EncryptBlock(block, expandedkey)
                            : algorithm.DecryptBlock(block, expandedkey);
                        Buffer.BlockCopy(block, 0, output, b * InputBlockLen_byte, InputBlockLen_byte);
                    });
                }
                else
                {
                    var block = new byte[InputBlockLen_byte];
                    for (int b = 0; b < countblocks; b++)
                    {
                        Buffer.BlockCopy(input, b * InputBlockLen_byte, block, 0, InputBlockLen_byte);
                        block = encrypt
                            ? algorithm.EncryptBlock(block, expandedkey)
                            : algorithm.DecryptBlock(block, expandedkey);
                        Buffer.BlockCopy(block, 0, output, b * InputBlockLen_byte, InputBlockLen_byte);
                    }
                }
                if (!encrypt)
                {
                    int countbytestoerase = output[output.Length - 1] + 1;

                    int newoutputlenght = output.Length - countbytestoerase;
                    Array.Resize(ref output, newoutputlenght);
                }

                return(output);
            }
            return(null);
        }