示例#1
0
        public void Decode()
        {
            byte[] bytes    = AlphabetMapper.TranslateMetroidStringToComputerBytes(Encoded);
            byte   checksum = bytes[ChecksumByte - 1];
            byte   shift    = bytes[ShiftByte - 1];

            byte[] decoded = new byte[ChecksumByteCount];
            Buffer.BlockCopy(bytes, 0, decoded, 0, ChecksumByteCount);

            decoded = decoded.RotateLeft(shift);

            byte verifyChecksum = CalculateChecksum(decoded, shift);

            if (verifyChecksum != checksum)
            {
                throw new ChecksumException("Invalid Metroid password");
            }

            // The bitpacking we use assumes that information is packed from the left which means that it makes a big difference for a byte full of bools
            // Information is actually packed from the right of the byte
            // Ergo we just have to flip each byte
            // However first we handle the only 32-bit value (which can't be fixed by a naive flip)
            if (!BitConverter.IsLittleEndian)
            {
                // The game age value comes in little-endian format
                Swap(decoded, GameAgeStartByteIndex, GameAgeEndByteIndex);
                Swap(decoded, GameAgeStartByteIndex + 1, GameAgeEndByteIndex - 1);
            }
            for (int i = 0; i < decoded.Length; i++)
            {
                if (i >= GameAgeStartByteIndex && i <= GameAgeEndByteIndex)
                {
                    continue;
                }
                decoded[i] = decoded[i].ReverseBits();
            }

            var reader     = new PackedBitReader(decoded);
            var serializer = new PackedBitSerializer(typeof(PasswordProperties));

            Properties = serializer.Deserialize(reader) as PasswordProperties;

            Properties.Checksum = checksum;
            Properties.Shift    = shift;
        }
示例#2
0
 public Password(PasswordProperties desired)
 {
     Properties = desired;
     Encode();
 }