Binary Difference

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;
        }
    }
}

blog comments powered by Disqus

Custom Development

ALL USA BASED DEVELOPERS

 

Coder For Rent is a one-stop shop for all your .Net programming needs.  We can make project-based fixed bids as well as hourly/weekly/monthly quotes.  Our goal is to meet your needs the first time, saving you time and money.

 

Call to speak with an account manager. We take projects of all sizes.

 

713-482-7155 

Contact Us

Call 713-482-7155 
for technical or purchasing support

Freshbooks Rocks

FreshBooks

Silverlight Gantt Chart Control
Silverlight Scheduler Control