Пример #1
0
        private BitLock CreateAndIndexBitLock(IEnumerable <ushort> bitPositions)
        {
            var bitLock = new BitLock(bitPositions);

            foreach (var bitPosition in bitPositions)
            {
                if (!this._locksByBits.TryGetValue(bitPosition, out var indexedLocks))
                {
                    indexedLocks = new HashSet <BitLock>(ReferenceEqualityComparer <BitLock> .Default);
                    this._locksByBits.Add(bitPosition, indexedLocks);
                }

                indexedLocks.Add(bitLock);
            }

            return(bitLock);
        }
Пример #2
0
        private void DeindexBitLock(BitLock bitLock)
        {
            if (bitLock == null)
            {
                return;
            }

            foreach (var bitPosition in bitLock.BitPositions.Distinct())
            {
                var bitLocks = this._locksByBits[bitPosition];
                bitLocks.Remove(bitLock);

                if (!bitLocks.Any())
                {
                    this._locksByBits.Remove(bitPosition);
                }
            }
        }
Пример #3
0
        public bool Unlocks(BitLock bitLock)
        {
            var totalKeySegments  = this.Bits.Count;
            var totalLockSegments = bitLock.Bits.Count;

            if (totalLockSegments > totalKeySegments)
            {
                // If the lock is larger than the key, look first at all lock bytes past the key's length
                var farLock = bitLock.Bits.Skip(totalKeySegments);
                if (farLock.Any(x => x > 0))
                {
                    // If any lock byte past the key's length has any bits flipped to 1, this key cannot possibly fit
                    return(false);
                }
            }

            // Only look at the bytes of the key that have corresponding lock bytes
            // i.e. if the key is longer than the lock, trim down the key to fit the lock
            for (var segmentPos = 0; segmentPos < totalLockSegments; segmentPos++)
            {
                // Example:
                //  Key: 10010100
                // Lock: 10110011
                //       O XO  XX - passes 2 bits, fails 3 bits. Does NOT unlock.
                //  Key: 10010100
                // Lock: 10000100
                //       O    O   - passes 2 bits. Unlock successful. Don't care about extra key bits.

                var lockSegment = bitLock.Bits[segmentPos];
                var keySegment  = this.Bits[segmentPos];

                if ((keySegment & lockSegment) != lockSegment)
                {
                    return(false);
                }
            }

            // If no bytes failed, then the unlock is successful
            return(true);
        }