예제 #1
0
 public void BitCalculatorTest()
 {
     Assert.AreEqual(2, BitCalculator.Calculate("1", "1"));
     Assert.AreEqual(4, BitCalculator.Calculate("10", "10"));
     Assert.AreEqual(2, BitCalculator.Calculate("10", "0"));
     Assert.AreEqual(3, BitCalculator.Calculate("10", "1"));
 }
예제 #2
0
        /// <summary>
        /// Encrypts data using a low-entropy packing scheme.
        /// </summary>
        /// <param name="path">The path to the data to encrypt.</param>
        /// <param name="encryptedPath">The path to write the encrypted data to.</param>
        /// <param name="padding">The percentage of padding to add, where 0 means no extra padding, 100 means to double the size and 200 means to tripple the size. This can be a number between 0 and 1000.</param>
        /// <param name="key">When this function returns, this is the 32-bit decryption key.</param>
        /// <param name="paddingMask">When this function returns, this is the 32-bit padding mask.</param>
        /// <param name="paddingByteCount">When this function returns, this is the number of bytes of to use for a padding block.</param>
        public void EncryptData(string path, string encryptedPath, int padding, out uint key, out uint paddingMask, out int paddingByteCount)
        {
            // 32-bit encryption key
            key = MathEx.RandomNumberGenerator.GetUInt32();

            // paddingMaskBits is a 32-bit number with a certain number of bits set.
            // After each encrypted byte, this mask is rotated right by 1.
            // If the least significant bit is 1, a padding is added to the encrypted data stream.
            // paddingByteCount is the number of consecutive bytes that are used as padding.

            paddingByteCount = 1 + padding / 100;
            int paddingMaskBits = padding * 32 / (100 + padding / 100 * 100);

            paddingMask = 0;
            foreach (int i in Enumerable.Range(0, 32).SortRandom().Take(paddingMaskBits))
            {
                paddingMask = BitCalculator.SetBit(paddingMask, i, true);
            }

            uint currentKey         = key;
            uint currentPaddingMask = paddingMask;

            using (FileStream stream = File.OpenRead(path))
                using (FileStream encryptedStream = File.Create(encryptedPath))
                {
                    int dataByte;
                    while ((dataByte = stream.ReadByte()) != -1)
                    {
                        // Xor the current byte with the least significant byte of the key.
                        // Then, key = (key ror 5) * 7
                        encryptedStream.WriteByte((byte)(dataByte ^ currentKey));

                        // If the padding mask's least significant bit is 1, add the given number of padding bytes.
                        // Then, rotate padding mask right by 1.
                        if ((currentPaddingMask & 1) == 1)
                        {
                            for (int j = 0; j < paddingByteCount; j++)
                            {
                                encryptedStream.WriteByte(0);
                            }
                        }

                        currentKey         = MathEx.Ror(currentKey, 5) * 7;
                        currentPaddingMask = MathEx.Ror(currentPaddingMask, 1);
                    }
                }
        }
예제 #3
0
 public void ShouldReturnTheSumOfGivenBinaryNumbersInDecimal(string numberOne, string numberTwo, int expected)
 {
     Assert.Equal(expected, BitCalculator.Calculate(numberOne, numberTwo));
 }
예제 #4
0
        // GET: Calculator
        public ActionResult Index()
        {
            var viewModel = new BitCalculator();

            return(View(viewModel));
        }
예제 #5
0
        public ActionResult Index(BitCalculator viewModel)
        {
            viewModel.CalculateConversions();

            return(View(viewModel));
        }