private static void EncodeNOfs(List <byte> bytes, List <CardCodeAndCount> nOfs)
        {
            foreach (CardCodeAndCount ccc in nOfs)
            {
                bytes.AddRange(Varint.GetVarint((ulong)ccc.Count));

                ParseCardCode(ccc.CardCode, out int setNumber, out string factionCode, out int cardNumber);
                int factionNumber = FactionCodeToIntIdentifier[factionCode];

                bytes.AddRange(Varint.GetVarint((ulong)setNumber));
                bytes.AddRange(Varint.GetVarint((ulong)factionNumber));
                bytes.AddRange(Varint.GetVarint((ulong)cardNumber));
            }
        }
        private static void EncodeGroupOf(List <byte> bytes, List <List <CardCodeAndCount> > groupOf)
        {
            bytes.AddRange(Varint.GetVarint((ulong)groupOf.Count));
            foreach (List <CardCodeAndCount> currentList in groupOf)
            {
                //how many cards in current group?
                bytes.AddRange(Varint.GetVarint((ulong)currentList.Count));

                //what is this group, as identified by a set and faction pair
                string currentCardCode = currentList[0].CardCode;
                ParseCardCode(currentCardCode, out int currentSetNumber, out string currentFactionCode, out int _);
                int currentFactionNumber = FactionCodeToIntIdentifier[currentFactionCode];
                bytes.AddRange(Varint.GetVarint((ulong)currentSetNumber));
                bytes.AddRange(Varint.GetVarint((ulong)currentFactionNumber));

                //what are the cards, as identified by the third section of card code only now, within this group?
                foreach (CardCodeAndCount cd in currentList)
                {
                    string code           = cd.CardCode;
                    int    sequenceNumber = int.Parse(code.Substring(4, 3));
                    bytes.AddRange(Varint.GetVarint((ulong)sequenceNumber));
                }
            }
        }
        public static List <CardCodeAndCount> GetDeckFromCode(string code)
        {
            List <CardCodeAndCount> result = new List <CardCodeAndCount>();

            byte[] bytes;
            try
            {
                bytes = Base32.Decode(code);
            }
            catch
            {
                throw new ArgumentException("Invalid deck code");
            }

            List <byte> byteList = bytes.ToList();

            //grab format and version
            //int format = bytes[0] >> 4;
            int version = bytes[0] & 0xF;

            byteList.RemoveAt(0);

            if (version > MaxKnownVersion)
            {
                throw new ArgumentException(
                          "The provided code requires a higher version of this library; please update.");
            }

            for (int i = 3; i > 0; i--)
            {
                int numGroupOfs = Varint.PopVarint(byteList);

                for (int j = 0; j < numGroupOfs; j++)
                {
                    int numOfsInThisGroup = Varint.PopVarint(byteList);
                    int set     = Varint.PopVarint(byteList);
                    int faction = Varint.PopVarint(byteList);

                    for (int k = 0; k < numOfsInThisGroup; k++)
                    {
                        int card = Varint.PopVarint(byteList);

                        string setString     = set.ToString().PadLeft(2, '0');
                        string factionString = IntIdentifierToFactionCode[faction];
                        string cardString    = card.ToString().PadLeft(3, '0');

                        CardCodeAndCount newEntry = new CardCodeAndCount()
                        {
                            CardCode = setString + factionString + cardString, Count = i
                        };
                        result.Add(newEntry);
                    }
                }
            }

            //the remainder of the deck code is comprised of entries for cards with counts >= 4
            //this will only happen in Limited and special game modes.
            //the encoding is simply [count] [card code]
            while (byteList.Count > 0)
            {
                int fourPlusCount   = Varint.PopVarint(byteList);
                int fourPlusSet     = Varint.PopVarint(byteList);
                int fourPlusFaction = Varint.PopVarint(byteList);
                int fourPlusNumber  = Varint.PopVarint(byteList);

                string fourPlusSetString     = fourPlusSet.ToString().PadLeft(2, '0');
                string fourPlusFactionString = IntIdentifierToFactionCode[fourPlusFaction];
                string fourPlusNumberString  = fourPlusNumber.ToString().PadLeft(3, '0');

                CardCodeAndCount newEntry = new CardCodeAndCount()
                {
                    CardCode = fourPlusSetString + fourPlusFactionString + fourPlusNumberString, Count = fourPlusCount
                };
                result.Add(newEntry);
            }

            return(result);
        }