private string encode(string originalString) { string compressedString = originalString.Substring(0, 1); string encodeChar = null; for (int n=161;n<191;n++) { //- Find a character not in the file to use in the encoding formatting string c = new string(((char)n), 1); if (originalString.IndexOf(c, 0, originalString.Length) == -1) { encodeChar = c; break; } } if (encodeChar == null) { MessageBox.Show("This file can't be compressed (No free character found)"); return ""; } int[] findBestResult = new int[2]; // store position and sequence length int currPos = 1; int radix = 114; // the number base int bufferSize = radix*radix-1; // history buffer size int lookAheadBufferSize = radix-1; // max number of characters to copy in a sequence string lookAheadString = originalString.Substring(currPos, Math.Min(originalString.Length-currPos, lookAheadBufferSize)); while (lookAheadString.Length > 0) // while there are characters to encode { encodeFindBest(originalString, Math.Max(currPos-bufferSize, 0), currPos-1, lookAheadString, findBestResult); // try to find an upcoming sequence in the history buffer and refer to it if (findBestResult[0] == -1) // no sequence found, just move 1 character forward and add the current character to the coded sequence { compressedString += originalString.Substring(currPos, 1); currPos++; } else // a sequence was found, convert the position and sequence length to ASCII characters { int p = currPos-findBestResult[0]; int l = findBestResult[1]; int ms = (int)(p/radix); int ls = p-ms*radix; compressedString += encodeChar + new string((char)(14+ms), 1) + new string((char)(14+ls), 1) + new string((char)(14+l), 1); currPos += l; } lookAheadString = originalString.Substring(currPos, Math.Min(originalString.Length-currPos, lookAheadBufferSize)); } return "v1.0 " + encodeChar + compressedString; } private void encodeFindBest(string str, int winStart, int winEnd, string lookAhead, int[] res) { int lookAheadLength = lookAhead.Length; string winStr = str.Substring(winStart, winEnd-winStart); int sequenceLength = 5; int matchLength = 0; int matchPos = 0; int n; while (sequenceLength <= lookAheadLength) { n = winStr.IndexOf(lookAhead.Substring(0, sequenceLength)); if (n == -1) { break; } else { matchLength = sequenceLength; matchPos = n; } sequenceLength++; } if (matchLength > 0) { res[0] = winStart+matchPos; res[1] = matchLength; } else { res[0] = -1; } }