16. January 2011 16:49
I wanted a way to get the difference between two images, so that I can transfer only the changes between client/servers. Here's what I came up with... thoughts?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CFR.BinaryDifference
{
public class Diff
{
public int Position { get; set; }
public byte[] Bytes { get; set; }
public Diff()
{
}
public static List<Diff> Compare(byte[] original, byte[] comp)
{
return Compare(original, comp, 1, 0);
}
public static List<Diff> Compare(byte[] original, byte[] comp, int inc, int start)
{
if (original.Length != comp.Length)
throw new NotSupportedException("Parameters \"original\" and \"comp\" must be of the same length");
List<Diff> results = new List<Diff>();
//bool skipBack = false;
for (int i = start; i < original.Length; i += inc)
{
if (original[i] != comp[i])
{
Diff d = new Diff();
int length = 0;
int pos = i;
for (int j = Math.Max(i - inc + 1, 0); j < original.Length; j++)
{
if (original[j] != comp[j])
{
if (length == 0)
pos = j;
length++;
}
else if (length > 0 && j < i)
{
length++;
}
else if (length > 0 && j >= i)
break;
}
d.Position = pos;
d.Bytes = new byte[length];
Array.Copy(comp, pos, d.Bytes, 0, length);
results.Add(d);
i = pos + length;
}
}
return results;
}
public static byte?[] Combine(List<Diff> differences)
{
return Combine(differences, 0);
}
public static byte?[] Combine(List<Diff> differences, byte defaultValue)
{
if (differences.Count == 0)
return new byte?[0];
byte?[] bytes = new byte?[differences.Max(d => d.Position + d.Bytes.Length)];
for (int i = 0; i < differences.Count; i++)
{
Diff d = differences[i];
for (int j = d.Position; j < d.Bytes.Length + d.Position; j++)
{
bytes[j] = d.Bytes[j - d.Position];
}
}
return bytes;
}
public static byte[] Merge(byte[] target, List<Diff> differences)
{
for (int i = 0; i < differences.Count; i++)
{
Diff d = differences[i];
for (int j = 0; j < d.Bytes.Length; j++)
{
target[d.Position + j] = d.Bytes[j];
}
}
return target;
}
}
}
bcbe3fb3-46fc-4c55-8a71-de56e484c9a9|3|5.0