Example #1
0
        public void BasicEncodingWithFinalBlockFalse()
        {
            var rnd = new Random(42);

            for (int i = 0; i < 10; i++)
            {
                int         numBytes = rnd.Next(100, 1000 * 1000);
                Span <byte> source   = new byte[numBytes];
                Base64TestHelper.InitalizeBytes(source, numBytes);
                Span <byte> encodedBytes     = new byte[Base64.GetMaxEncodedToUtf8Length(source.Length)];
                int         expectedConsumed = source.Length / 3 * 3; // only consume closest multiple of three since isFinalBlock is false
                int         expectedWritten  = source.Length / 3 * 4;

                Assert.Equal(OperationStatus.NeedMoreData, Base64.EncodeToUtf8(source, encodedBytes, out int consumed, out int encodedBytesCount, isFinalBlock: false));
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(expectedWritten, encodedBytesCount);
                Assert.True(Base64TestHelper.VerifyEncodingCorrectness(expectedConsumed, expectedWritten, source, encodedBytes));
            }
        }
        private static void Base64DecodeInPlaceOnce(int numberOfBytes)
        {
            Span <byte> source = new byte[numberOfBytes];

            Base64TestHelper.InitalizeBytes(source);
            int         length      = Base64.GetMaxEncodedToUtf8Length(numberOfBytes);
            Span <byte> encodedSpan = new byte[length];

            int bytesWritten = 0;

            foreach (var iteration in Benchmark.Iterations)
            {
                Base64.EncodeToUtf8(source, encodedSpan, out _, out _);
                using (iteration.StartMeasurement())
                {
                    Base64.DecodeFromUtf8InPlace(encodedSpan, out bytesWritten);
                }
            }

            Assert.True(source.SequenceEqual(encodedSpan.Slice(0, bytesWritten)));
        }
        private static void Base64DecodeDetinationTooSmall(int numberOfBytes)
        {
            Span <byte> source = new byte[numberOfBytes];

            Base64TestHelper.InitalizeBytes(source);
            Span <byte> encoded = new byte[Base64.GetMaxEncodedToUtf8Length(numberOfBytes)];

            Base64.EncodeToUtf8(source, encoded, out _, out _);

            source = source.Slice(0, source.Length - 1);

            foreach (var iteration in Benchmark.Iterations)
            {
                using (iteration.StartMeasurement()) {
                    for (int i = 0; i < Benchmark.InnerIterationCount; i++)
                    {
                        Base64.DecodeFromUtf8(encoded, source, out int bytesConsumed, out int bytesWritten);
                    }
                }
            }
        }
        public void BasicDecoding()
        {
            var rnd = new Random(42);

            for (int i = 0; i < 10; i++)
            {
                int numBytes = rnd.Next(100, 1000 * 1000);
                while (numBytes % 4 != 0)
                {
                    numBytes = rnd.Next(100, 1000 * 1000);
                }
                Span <byte> source = new byte[numBytes];
                Base64TestHelper.InitalizeDecodableBytes(source, numBytes);

                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                Assert.Equal(OperationStatus.Done,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));
                Assert.Equal(source.Length, consumed);
                Assert.Equal(decodedBytes.Length, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(source.Length, decodedBytes.Length, source, decodedBytes));
            }
        }
        private static void Base64Encode(int numberOfBytes)
        {
            Span <byte> source = new byte[numberOfBytes];

            Base64TestHelper.InitalizeBytes(source);
            Span <byte> destination = new byte[Base64.GetMaxEncodedToUtf8Length(numberOfBytes)];

            foreach (var iteration in Benchmark.Iterations)
            {
                using (iteration.StartMeasurement()) {
                    for (int i = 0; i < Benchmark.InnerIterationCount; i++)
                    {
                        Base64.EncodeToUtf8(source, destination, out int consumed, out int written);
                    }
                }
            }

            Span <byte> backToSource = new byte[numberOfBytes];

            Base64.DecodeFromUtf8(destination, backToSource, out _, out _);
            Assert.True(source.SequenceEqual(backToSource));
        }
        public void BasicDecodingWithFinalBlockFalse()
        {
            var rnd = new Random(42);

            for (int i = 0; i < 10; i++)
            {
                int numBytes = rnd.Next(100, 1000 * 1000);
                while (numBytes % 4 != 0)
                {
                    numBytes = rnd.Next(100, 1000 * 1000);
                }
                Span <byte> source = new byte[numBytes];
                Base64TestHelper.InitalizeDecodableBytes(source, numBytes);

                Span <byte> decodedBytes     = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                int         expectedConsumed = source.Length / 4 * 4; // only consume closest multiple of four since isFinalBlock is false

                Assert.Equal(OperationStatus.NeedMoreData,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock: false));
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(decodedBytes.Length, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, decodedBytes.Length, source, decodedBytes));
            }
        }
        private static void Base64Decode(int numberOfBytes)
        {
            Span <byte> source = new byte[numberOfBytes];

            Base64TestHelper.InitalizeBytes(source);
            Span <byte> encoded = new byte[Base64.GetMaxEncodedToUtf8Length(numberOfBytes)];

            Base64.EncodeToUtf8(source, encoded, out _, out _);

            foreach (var iteration in Benchmark.Iterations)
            {
                using (iteration.StartMeasurement()) {
                    for (int i = 0; i < Benchmark.InnerIterationCount; i++)
                    {
                        Base64.DecodeFromUtf8(encoded, source, out int bytesConsumed, out int bytesWritten);
                    }
                }
            }

            Span <byte> backToEncoded = encoded.ToArray();

            Base64.EncodeToUtf8(source, encoded, out _, out _);
            Assert.True(backToEncoded.SequenceEqual(encoded));
        }
        public void DecodingInvalidBytesPadding()
        {
            // Only last 2 bytes can be padding, all other occurrence of padding is invalid
            for (int j = 0; j < 7; j++)
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 }; // valid input - "2222PPPP"
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[j] = Base64TestHelper.s_encodingPad;
                Assert.Equal(OperationStatus.InvalidData,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));

                if (j < 4)
                {
                    Assert.Equal(0, consumed);
                    Assert.Equal(0, decodedByteCount);
                }
                else
                {
                    Assert.Equal(4, consumed);
                    Assert.Equal(3, decodedByteCount);
                    Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
                }
            }

            // Invalid input with valid padding
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 42, 42, 42 };
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[6] = Base64TestHelper.s_encodingPad;
                source[7] = Base64TestHelper.s_encodingPad; // invalid input - "2222P*=="
                Assert.Equal(OperationStatus.InvalidData,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));

                Assert.Equal(4, consumed);
                Assert.Equal(3, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));

                source       = new byte[] { 50, 50, 50, 50, 80, 42, 42, 42 };
                decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[7]    = Base64TestHelper.s_encodingPad; // invalid input - "2222PP**="
                Assert.Equal(OperationStatus.InvalidData,
                             Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out decodedByteCount));

                Assert.Equal(4, consumed);
                Assert.Equal(3, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
            }

            // The last byte or the last 2 bytes being the padding character is valid
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 };
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[6] = Base64TestHelper.s_encodingPad;
                source[7] = Base64TestHelper.s_encodingPad; // valid input - "2222PP=="
                Assert.Equal(OperationStatus.Done,
                             Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount));

                Assert.Equal(source.Length, consumed);
                Assert.Equal(4, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(source.Length, 4, source, decodedBytes));

                source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 };
                decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[7]    = Base64TestHelper.s_encodingPad; // valid input - "2222PPP="
                Assert.Equal(OperationStatus.Done,
                             Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out decodedByteCount));

                Assert.Equal(source.Length, consumed);
                Assert.Equal(5, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(source.Length, 5, source, decodedBytes));
            }
        }
Example #9
0
        public void DecodingInvalidBytesPadding(bool isFinalBlock)
        {
            // Only last 2 bytes can be padding, all other occurrence of padding is invalid
            for (int j = 0; j < 7; j++)
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 }; // valid input - "2222PPPP"
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[j] = Base64TestHelper.EncodingPad;
                Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock));

                if (j < 4)
                {
                    Assert.Equal(0, consumed);
                    Assert.Equal(0, decodedByteCount);
                }
                else
                {
                    Assert.Equal(4, consumed);
                    Assert.Equal(3, decodedByteCount);
                    Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
                }
            }

            // Invalid input with valid padding
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 42, 42, 42 };
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[6] = Base64TestHelper.EncodingPad;
                source[7] = Base64TestHelper.EncodingPad; // invalid input - "2222P*=="
                Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock));

                Assert.Equal(4, consumed);
                Assert.Equal(3, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));

                source       = new byte[] { 50, 50, 50, 50, 80, 42, 42, 42 };
                decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[7]    = Base64TestHelper.EncodingPad; // invalid input - "2222PP**="
                Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out decodedByteCount, isFinalBlock));

                Assert.Equal(4, consumed);
                Assert.Equal(3, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(4, 3, source, decodedBytes));
            }

            // The last byte or the last 2 bytes being the padding character is valid, if isFinalBlock = true
            {
                Span <byte> source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 };
                Span <byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[6] = Base64TestHelper.EncodingPad;
                source[7] = Base64TestHelper.EncodingPad; // valid input - "2222PP=="

                OperationStatus expectedStatus   = isFinalBlock ? OperationStatus.Done : OperationStatus.InvalidData;
                int             expectedConsumed = isFinalBlock ? source.Length : 4;
                int             expectedWritten  = isFinalBlock ? 4 : 3;

                Assert.Equal(expectedStatus, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock));
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(expectedWritten, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, expectedWritten, source, decodedBytes));

                source       = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 };
                decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)];
                source[7]    = Base64TestHelper.EncodingPad; // valid input - "2222PPP="

                expectedConsumed = isFinalBlock ? source.Length : 4;
                expectedWritten  = isFinalBlock ? 5 : 3;
                Assert.Equal(expectedStatus, Base64.DecodeFromUtf8(source, decodedBytes, out consumed, out decodedByteCount, isFinalBlock));
                Assert.Equal(expectedConsumed, consumed);
                Assert.Equal(expectedWritten, decodedByteCount);
                Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, expectedWritten, source, decodedBytes));
            }
        }