I stumbled upon this question which is quite old but very close to what I'm attempting to do nowadays, that's why I would like to contribute to this thread. I'm trying to sort a List<Byte[]>
, whose values are the basically hashes and this is what I came up with:
[SuppressUnmanagedCodeSecurity]
internal static class NativeMethods
{
[DllImport("MSVCRT.dll", CallingConvention=CallingConvention.Cdecl, ExactSpelling=true)]
private static extern Int32 memcmp([In] IntPtr pointer1, [In] IntPtr pointer2, [In] UIntPtr count);
internal static Int32 CompareSequences(Byte[] array1, Byte[] array2)
{
if (ReferenceEquals(array1, array2))
return 0;
if (array1 == null)
return 1;
if (array2 == null)
return -1;
if (array1.Length != array2.Length)
return -Math.Min(Math.Max(array1.Length - array2.Length, -1), 1);
unsafe
{
fixed (Byte* pointer1 = array1, pointer2 = array2)
return -Math.Min(Math.Max(memcmp((IntPtr)pointer1, (IntPtr)pointer2, (UIntPtr)array1.Length), -1), 1);
}
}
}
Usage:
List<Byte[]> hashes = ComputeHashes();
hashes.Sort(NativeMethods.CompareSequences);
This is what it does:
- Null arrays are placed at the bottom of the list.
- Non-null arrays are sorted by length, then by "content":
- In presence of mismatching lengths, bigger arrays prevail.
- In presence of identical lengths, the array whose first mismatching byte is greater prevails.
Since you are working with hashes, there should be no null values and all the arrays in your list are supposed to have the same length. Hence, the comparison function could be simplified as follows:
internal static Int32 CompareSequences(Byte[] array1, Byte[] array2)
{
unsafe
{
fixed (Byte* pointer1 = array1, pointer2 = array2)
return -Math.Min(Math.Max(memcmp((IntPtr)pointer1, (IntPtr)pointer2, (UIntPtr)array1.Length), -1), 1);
}
}