現在、プロジェクトに圧縮アルゴリズムを実装しようとしていますが、効果的には lz77 である必要があります...既にデータを解凍できますが、圧縮に関してどこから始めればよいか想像できません。データをバイト配列で渡すのが最善だと思っていましたが、それだけです...私の問題は、アルゴリズムのすべての説明が非常にわかりにくいことです。アルゴリズムがどのように機能するか、および何を監視する必要があるかについて明確に説明していただければ幸いです。また: C# でコーディングする場合、安全でないメソッドとポインターを使用する義務がありますか? それは避けた方がいいのかな……。
あなたが私に与えてくれた情報のおかげで、これまでに得たものは次のとおりです。
private const int searchWindow = 4095;
private const byte lookaheadWindow = 15;
public static byte[] lzCompressData(byte[] input)
{
int position = 0;
List<byte> tempInput = input.ToList();
List<byte> output = new List<byte>();
MemoryStream init = new MemoryStream();
BinaryWriter inbw = new BinaryWriter(init);
inbw.Write(((input.Length << 8) & 0xFFFFFF00) | 0x10);
output.AddRange(init.ToArray());
while (position < input.Length)
{
byte decoder = 0;
List<byte> tempOutput = new List<byte>();
for (int i = 0; i < 8; ++i)
{
List<byte> eligible;
if(position < 255)
{
eligible = tempInput.GetRange(0, position);
}
else
{
eligible = tempInput.GetRange(position - searchWindow, searchWindow);
}
if (!(position > input.Length - 8))
{
MemoryStream ms = new MemoryStream(eligible.ToArray());
List<byte> currentSequence = new List<byte>();
currentSequence.Add(input[position]);
int offset = 0;
int length = 0;
long tempoffset = StreamHelper.FindPosition(ms, currentSequence.ToArray());
while ((tempoffset != -1) && (length < lookaheadWindow) && position < input.Length - 8)
{
offset = (int)tempoffset;
length = currentSequence.Count;
position++;
currentSequence.Add(input[position]);
}
if (length >= 3)
{
decoder = (byte)(decoder | (byte)(1 << i));
byte b1 = (byte)((length << 4) | (offset >> 8));
byte b2 = (byte)(offset & 0xFF);
tempOutput.Add(b1);
tempOutput.Add(b2);
}
else
{
tempOutput.Add(input[position]);
position++;
}
}
else
{
if (position < input.Length)
{
tempOutput.Add(input[position]);
position++;
}
else
{
tempOutput.Add(0xFF);
}
}
}
output.Add(decoder);
output.AddRange(tempOutput.ToArray());
}
return output.ToArray();
}