Dr. Baranyai László, fénykép

Dr. Baranyai László

 

Másolatok felderítése

dec 12, 20:41, |

 

Az elektronikus dokumentumkezelés egyik hátránya, hogy azonos tartalmakat többszörösen, tipikusan eltérő nevekkel is mentünk. Ez csökkenti a tárolókapacitást és nehezíti a dokumentumok átláthatóságát. Természetesen léteznek kitűnő verziókezelő (SVN) rendszerek, de ennél sokkal egyszerűbben is felderíthetőek a felesleges másodpéldányok.

MD5 ujjlenyomat

A "message digest" MD5 algoritmus digitális ujjlenyomatot képez, esetünkben a fájlok tartalma alapján. Az eredmény 32 jegyű hexadecimális számsor, amely egyedinek tekinthető. Például az általam jelenleg használt openSUSE shell:

$ md5sum /bin/sh
0f0563d30e47049730e38e1adb258ff2  /bin/sh

A program kimenete tartalmazza az ujjlenyomatot és a teljes elérési útvonalat. Ezt a listát nagyon egyszerű ellőrizni. Egy rövidke - mindössze 45 soros - C++ programot készítettem a listában előforduló ismétlődő MD5 azonosítók felderítésére.

#include <stdio.h>
#include <string.h>

typedef struct tCHK {
 bool used;
 char md5[35];
 char fn[260];
} tCHK;

const int MAXDATA = 2000;

int main(void)
{
 tCHK *Data;
 int i,j,N,F;
 bool isPrinted;

 printf("MD5 checksum list verification\n");
 Data = new tCHK[MAXDATA];
 N = 0;
 while(!feof(stdin) && N<MAXDATA) {
  fgets(Data[N].md5,33,stdin);
  fgets(Data[N].fn,255,stdin);
  Data[N].used = false;
  N++;
 }
 printf("Processing %d lines ...\n",N);
 F = 0;
 for (i=0;i<N-1;i++) {
  isPrinted = false;
  for (j=i+1;j<N;j++) {
   if (Data[j].used==false && strcmp(Data[i].md5,Data[j].md5)==0) {
    Data[j].used = true;
    if (!isPrinted) {
     printf("MD5 found: %s\n\t[s]%s",Data[i].md5,Data[i].fn);
     isPrinted = true; 
    }
    printf("\t%s",Data[j].fn); F++;
   }
  }
 }
 printf("%d duplicates were found.\n",F);
 delete[] Data;
 return 0;
}

A fenti kódban tCHK struktúra tárolja a sorokat, kiegészítve a találat jelzésével. Ez utóbbira azért van szükség, hogy a többszörös találatok is csak egy alkalommal jelenjenek meg a kimeneten. A MAXDATA konstans határozza meg a lista maximális méretét. A program a szabványos bemenetről olvas fgets() függvény segítségével. Itt figyelembe kell venni, hogy a név tartalmazni fogja a sorvége (\n) jelölést is. A találatokat szimpla ciklussal feltérképezhetjük. Végül a használata:

$ g++ chkmd5.cpp -o chkmd5
$ md5sum `ls /bin/*` | ./chkmd5

Figyelje meg a fájlnév lista létrehozásához használt idézőjeleket! A fenti parancsok elsőként lefordítják a C++ kódot, majd a /bin könyvtár azonos állományait keresik meg (ezek várhatóan kompatibilitási céllal készített linkek lesznek).

Platformfüggetlen megoldás

Habár a fenti alkalmazási példa Linux környezetben működött, a Windows felhasználók sem maradnak segítség nélkül. A Windows-KB841290-x86-ENU kiegészítés az FCIV (File Checksum Integrity Verifier) programot telepíti, amely MD5 és SHA1 ujjlenyomatokat számít. Szerencsére a bemutatott C++ kód nem tartalmaz OS specifikus elemeket, ezért lefordítható akár ingyenes eszközökkel is. Ehhez javasolnám a méltán népszerű Borland C++ 5.5 (32 bit) ingyenes fordítót.

Jó vadászatot!