Exemple #1
0
        public void WriteSimple()
        {
            var bs = new BitWriteStream(4);

            bs.Write(0b_____101, 3);
            bs.Write(0b_1001110, 7);
            bs.Write(0b____0010, 4);

            uint value = BitConverter.ToUInt32(bs.GetBytes(), 0);

            Assert.AreEqual <uint>(0b_0010_1001110_101, value);
        }
Exemple #2
0
        public void WriteOneBit()
        {
            var bs = new BitWriteStream(4);

            uint expected = 0b10010011_11001001;

            for (ulong b = expected; b != 0; b >>= 1)
            {
                bs.Write(b, 1);
            }

            uint value = BitConverter.ToUInt32(bs.GetBytes(), 0);

            Assert.AreEqual <uint>(expected, value);
        }
Exemple #3
0
        public void Combine()
        {
            var bs1 = new BitWriteStream();

            bs1.Write(0b101010, 6);
            bs1.Write(0b101010, 6);

            var bs2 = new BitWriteStream();

            bs2.Write(0b010101, 6);
            bs2.Write(0b010101, 6);

            var cb = BitWriteStream.Combine(new[] { bs1, bs2 });

            Assert.AreEqual <byte>(0xAA, cb[0]);
            Assert.AreEqual <byte>(0x5A, cb[1]);
            Assert.AreEqual <byte>(0x55, cb[2]);
        }
Exemple #4
0
        public EncodeResult Encode(byte[] data)
        {
            var flagOut = new List <BitWriteStream>();
            var resOut  = new BitWriteStream();

            // Actual data length
            int dataLength = data.Length;

            // Perform specified number of rounds
            for (int ri = 0; ri < rounds; ri++)
            {
                flagOut.Add(new BitWriteStream());

                // Placeholder for header
                resOut.Write(0UL, 8);

                // Generate key set number
                int kset = key.GetNextKeyset();

                unsafe
                {
                    // Use raw pointers to skip array bounds check
                    fixed(byte *dptr = data)
                    {
                        // Perform MV2 substitutions
                        for (int i = 0; i < dataLength; i++)
                        {
                            // Scramble byte values before MV2 lookup
                            byte val = key.Encode(key.XorByte(dptr[i], i), kset);
                            var(res, flag) = TransformTable.Encode(val);

                            resOut.Write(res);
                            flagOut[ri].Write(flag);
                        }
                    }
                }

                // Num. free bits in last byte
                long fbits = 8 - (resOut.Position & 7);

                // Fill the header
                resOut[0] = (byte)((fbits & 7) | (kset << 3));

                // Forward the residual to next round
                data       = resOut.GetBytesInternal();
                dataLength = resOut.BytesWritten;
                resOut.Reset();

                // KLUDGE: Pad the flag bitstream to full byte
                flagOut[ri].FinishByte();

                // Terminate early if residual is too small
                if (dataLength <= MinResidual)
                {
                    break;
                }
            }

            // Concatenate flag buffers into final array
            var flagFinal = BitWriteStream.Combine(flagOut.Reverse <BitWriteStream>());

            // Trim the residual
            var resFinal = new byte[dataLength];

            Array.Copy(data, resFinal, dataLength);

            return(new EncodeResult {
                Residual = resFinal, Flag = flagFinal
            });
        }