Beispiel #1
0
        private static EncodedString FindMatch(int nonEncodedHead)
        {
            var matchData = new EncodedString();

            var i = HashTable[GetHashKey(nonEncodedHead, true)];
            var j = 0;

            // если в хэш таблице есть совпадение
            while (i.HasValue)
            {
                // если оно совпадает с первым символом буфера
                if (SearchBuffer[i.Value] == NonEncodedBuffer[nonEncodedHead])
                {
                    j = 1;

                    while (SearchBuffer[(i.Value + j) % Constants.SearchBufferSize] ==
                           NonEncodedBuffer[(nonEncodedHead + j) % Constants.NonEncodedBufferSize])
                    {
                        if (j >= Constants.NonEncodedBufferSize)
                        {
                            break;
                        }

                        j++;
                    }

                    if (j > matchData.Length)
                    {
                        matchData.Length = j;
                        matchData.Offset = i.Value;
                    }
                }

                if (j >= Constants.NonEncodedBufferSize)
                {
                    matchData.Length = Constants.NonEncodedBufferSize;
                    break;
                }

                i = Next[i.Value];
            }

            return(matchData);
        }
        public string Decode(string stringToDecode)
        {
            var sb = new StringBuilder();

            int flag        = 0;
            int flagCount   = 7;
            int nextChar    = 0;
            var encodedCode = new EncodedString();

            for (var i = 0;;)
            {
                flag >>= 1;
                flagCount++;

                int currentChar;
                if (flagCount == 8)
                {
                    if (i >= stringToDecode.Length)
                    {
                        break;
                    }

                    currentChar = stringToDecode[i];
                    i++;

                    flag      = currentChar & Constants.AlphabetSize;
                    flagCount = 0;
                }
                // если флаг закодированных данных
                if (flag % 2 == 0)
                {
                    if (i >= stringToDecode.Length)
                    {
                        break;
                    }
                    // берем первые два квартета
                    encodedCode.Offset = stringToDecode[i];
                    i++;

                    if (i >= stringToDecode.Length)
                    {
                        break;
                    }
                    // берем вторые два квартета
                    encodedCode.Length = stringToDecode[i];
                    i++;
                    //первые два квартета склеиваем с первым квартетом из второй пары - получаем смещение
                    encodedCode.Offset = (encodedCode.Offset << 4) + ((encodedCode.Length & 240) >> 4);
                    //длину совпадение получаем из 4ого квартета + то, что отрезали при кодировании, чтобы влезть в 15
                    encodedCode.Length = (encodedCode.Length & 15) + Constants.MatchThreshold + 1;
                    // ищем в скользящем окне соответствующее смещение и длину совпадения - выписываем
                    for (var j = 0; j < encodedCode.Length; j++)
                    {
                        currentChar = SearchBuffer[(encodedCode.Offset + j) % Constants.SearchBufferSize];
                        sb.Append((char)currentChar);
                        SearchBuffer[(nextChar + j) % Constants.SearchBufferSize] = (char)currentChar;
                    }

                    nextChar = (nextChar + encodedCode.Length) % Constants.SearchBufferSize;
                }
                else
                {
                    if (i >= stringToDecode.Length)
                    {
                        break;
                    }

                    currentChar = stringToDecode[i];
                    i++;

                    //просто выписываем незашифрованный символ
                    sb.Append((char)currentChar);
                    SearchBuffer[nextChar] = (char)currentChar;
                    nextChar = (nextChar + 1) % Constants.SearchBufferSize;
                }
            }

            return(sb.ToString());
        }