Compare a number of binary files and display a difference-percentage-matrix. Usage bdiffm FILE_1 FILE2 ... FILE_n.
The result could look like this:
$ bdiffm `ls -ltr | tail -n 16 | awk '{print $9}'`
Comparing 16 files. Mapping:
01 -> 86802faf4aa889f3cfd189458ad26f88.bin
02 -> 51107bb78165c57fc0f60797c7d5fbed.bin
03 -> 216e847b9d5d882608b897552d94dd6e.bin
04 -> 9c3cdcf28ddf15b58fc6d09381c15e47.bin
05 -> b4575efe92cb6ab34ce528f5dd0f85d6.bin
06 -> d16271abfa620acbc7a38fa263bd00f6.bin
07 -> 125ec60d2d717386337e7183c1bfd466.bin
08 -> d618490cf85d7b2409188369a55e4925.bin
09 -> cf1fd621e305cce07e76c214df9673b3.bin
10 -> f9dc4a724a268dc50f599d91414a25a8.bin
11 -> 34655f8572cb808857e1e9520482eee8.bin
12 -> e5c56fa0755616cb67e88fbc2e35b84b.bin
13 -> 6c844f691378d632dbf00b1824b2191a.bin
14 -> 8891ccc3ebadf998710b8946a068cf97.bin
15 -> c7231aa4ce95621a541f09bbae35198f.bin
16 -> d41d8cd98f00b204e9800998ecf8427e.bin
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
----+------------------------------------------------------------------------------------------------
01 | 100% 67% 1% 2% 2% 2% 2% 1% 7% 7% 3% 2% 2% 1% 3% 0%
02 | 100% 1% 3% 2% 3% 3% 1% 2% 2% 3% 3% 2% 1% 1% 0%
03 | 100% 4% 6% 3% 4% 100% 1% 1% 1% 4% 6% 1% 3% 0%
04 | 100% 44% 95% 100% 4% 3% 3% 5% 100% 44% 8% 13% 0%
05 | 100% 41% 44% 6% 1% 1% 2% 44% 100% 4% 6% 0%
06 | 100% 94% 3% 3% 3% 5% 95% 41% 9% 13% 0%
07 | 100% 4% 3% 3% 5% 100% 44% 8% 13% 0%
08 | 100% 1% 1% 1% 4% 6% 1% 3% 0%
09 | 100% 99% 21% 3% 1% 3% 2% 0%
10 | 100% 23% 3% 1% 3% 2% 0%
11 | 100% 5% 2% 3% 4% 0%
12 | 100% 44% 8% 13% 0%
13 | 100% 4% 6% 0%
14 | 100% 2% 0%
15 | 100% 0%
16 | 100%
/* $Id: bdiffm.c 1720 2005-07-28 19:34:58Z $ * bdiffm - display binary diff matrix for n files. * */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <math.h> #define uint unsigned int #define byte unsigned char #define min(a, b) (a < b ? a : b) #define max(a, b) (a > b ? a : b) #define abs(a) a >= 0 ? a : -(a) // \033[%d;1m%-5s\033[0m] #define CL_RESET 0 #define CL_RED 31 #define CL_GREEN 32 #define CL_YELLOW 33 #define CL_WHITE 37 void pcolor(uint c) { if( c == CL_RESET ) printf("\033[0m"); else printf("\033[%d;1m", c); } uint getFileSize(const char *filename) { uint size = 0; FILE *f = fopen(filename, "r"); if( f ) { fseek(f, 0, SEEK_END); size = ftell(f); fclose(f); } return size; } uint getSimilarity(const char *a, const char *b) { char *command; FILE *f; char buffer[0x10]; uint bytesRead; uint sizeA, sizeB; uint diffBytes; sizeA = getFileSize(a); sizeB = getFileSize(b); if( max(sizeA, sizeB) == 0 ) return 0; asprintf(&command, "cmp -bl %s %s 2> /dev/null | wc -l ", a, b); f = popen(command, "r"); bytesRead = fread((void *)buffer, 1, sizeof(buffer) - 1, f); pclose(f); free(command); buffer[bytesRead] = 0; if( sizeA >= sizeB ) diffBytes = atol(buffer) + (sizeA - sizeB); else diffBytes = atol(buffer) + (sizeB - sizeA); return (100 - (diffBytes * 100 / max(sizeA, sizeB))); } void displayMatrix(int count, char ** files) { printf("Comparing %d files. Mapping:\n\n", count); uint i, j, p; uint *diffMatrix; for( i = 0; i < count; i++ ) { printf(" %02d -> %s\n", (i + 1), files[i]); } printf("\n"); diffMatrix = (uint *)malloc(count * count * sizeof(uint)); for( i = 0; i < count; i++ ) { for( j = i; j < count; j++ ) { if( i == j ) { diffMatrix[i * count + j] = 100; } else { diffMatrix[i * count + j] = getSimilarity(files[i], files[j]); } } } printf(" |"); for( i = 0; i < count; i++ ) printf(" %02d", i + 1); printf("\n"); printf("----+"); for( i = 0; i < count; i++ ) printf("------"); printf("\n"); for( i = 0; i < count; i++ ) { printf(" %02d |", i + 1); for( j = 0; j < i; j++ ) printf(" "); for( j = i; j < count; j++ ) { p = diffMatrix[i * count + j]; if( j == i ) pcolor(CL_WHITE); else if( p >= 75 ) pcolor(CL_GREEN); else if( p >= 50 ) pcolor(CL_YELLOW); else pcolor(CL_RED); printf(" %3d%%", diffMatrix[i * count + j]); pcolor(CL_RESET); } printf("\n"); } printf("\n"); free(diffMatrix); } int main(int argc, char **argv) { if( argc < 2 ) { printf("usage: %s FILE_1 FILE_2 ... FILE_n\n", argv[0]); } else { displayMatrix(argc - 1, &argv[1]); } return 0; }