Table of Contents

bdiffm

Compare a number of binary files and display a difference-percentage-matrix. Usage bdiffm FILE_1 FILE2 ... FILE_n.

Example output

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%

Source

/* $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;
}
 
 
 
snippets/bdiffm.txt · Last modified: 2006/02/17 14:01
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki