MD 5 cheksum файлов

Тема в разделе "PHP Pro", создана пользователем Tycoon, 20 апр 2009.

Статус темы:
Закрыта.
  1. Tycoon

    Tycoon Постоялец

    Регистр.:
    20 апр 2006
    Сообщения:
    77
    Симпатии:
    36
    написал скрипт который отслеживает изменения в заданных файлах, которые находятся в md5_log/file.list


    список файлов :
    T:/home/server/www/spy2.php
    T:/home/server/www/spy.php
    T:/home/server/www/fs.php
    T:/home/server/www/scan_dir.php
    T:/home/server/www/chekmd5.php
    T:/home/server/www/md5.php



    PHP:

    ////////////////////////////////// 
    $arr file("md5_log/file.list"); // чита в массив список файлов 
    foreach ($arr as $value


       echo 
    "File $value  <br>";  // обпрабатываю их в цикле, хочу получить все значения 


    ///////////////////////////////////// 
    $files $value// записываю все значения в новую перменную 
    /********************** сравниваю           *******************************/ 
        
    $file_md5 "md5_log/md5.hash"// 
    $md5_new_file trim(@md5_file($files)); 
    $md5_old_file trim(file_get_contents($file_md5)); 

    if (
    $md5_new_file <> $md5_old_file

        echo 
    "Файл был изменен"
        
    rename($file_md5$file_md5 ".bak"); 
        
    $fp fopen($file_md5'w'); 
        
    fwrite($fp$md5_new_file); 
        
    fclose($fp); 
        
    ///////////////// crontab 

        
    $message "В последний раз файл <br>" $files " был изменен: " date("d-Y-H:i:s."
            @
    filemtime($files)) . " MD5 файла: " . @md5_file($files) . " Размер файла: " . @ 
            
    filesize($files) . " байт"

        echo (
    "<br>Информация об измененных файлах отправлена на емайл: <br> " $files 
            
    "<br>"); 
        @
    mail('noreply@bk.ru'
            
    'Сообщение об изменение МД5 суммы файлов на сервере : http://' $_SERVER['SERVER_NAME'] . 
            
    $value$message); 

        
    //////////////////////////////////////////////////////////////// 
        
    unlink($file_md5 ".bak"); 


    // 
    else 

        echo 
    "Ничего не изменилось"

    }

    проблема в том что когда делаю
    print "<pre>" ;
    print_r($arr);


    распечатывается:

    Array
    (
    [0] => T:/home/server/www/spy2.php

    [1] => T:/home/server/www/spy.php

    [2] => T:/home/server/www/fs.php

    [3] => T:/home/server/www/scan_dir.php

    [4] => T:/home/server/www/chekmd5.php

    [5] => T:/home/server/www/md5.php
    )
    Файл был изменен
    Информация об измененных файлах отправлена на емайл:
    T:/home/server/www/spy2.php

    Array
    (
    [0] => T:/home/server/www/spy2.php

    [1] => T:/home/server/www/spy.php

    [2] => T:/home/server/www/fs.php

    [3] => T:/home/server/www/scan_dir.php

    [4] => T:/home/server/www/chekmd5.php

    [5] => T:/home/server/www/md5.php
    )
    Ничего не изменилось

    Array
    (
    [0] => T:/home/server/www/spy2.php

    [1] => T:/home/server/www/spy.php

    [2] => T:/home/server/www/fs.php

    [3] => T:/home/server/www/scan_dir.php

    [4] => T:/home/server/www/chekmd5.php

    [5] => T:/home/server/www/md5.php
    )
    Ничего не изменилось

    Array
    (
    [0] => T:/home/server/www/spy2.php

    [1] => T:/home/server/www/spy.php

    [2] => T:/home/server/www/fs.php

    [3] => T:/home/server/www/scan_dir.php

    [4] => T:/home/server/www/chekmd5.php

    [5] => T:/home/server/www/md5.php
    )
    Ничего не изменилось

    Array
    (
    [0] => T:/home/server/www/spy2.php

    [1] => T:/home/server/www/spy.php

    [2] => T:/home/server/www/fs.php

    [3] => T:/home/server/www/scan_dir.php

    [4] => T:/home/server/www/chekmd5.php

    [5] => T:/home/server/www/md5.php
    )
    Ничего не изменилось

    Array
    (
    [0] => T:/home/server/www/spy2.php

    [1] => T:/home/server/www/spy.php

    [2] => T:/home/server/www/fs.php

    [3] => T:/home/server/www/scan_dir.php

    [4] => T:/home/server/www/chekmd5.php

    [5] => T:/home/server/www/md5.php
    )
    Файл был изменен
    Информация об измененных файлах отправлена на емайл:
    T:/home/server/www/md5.php


    изменения были тока в 1 файле : T:/home/server/www/md5.php , но почему то первый файл в списке


    Файл был изменен
    Информация об измененных файлах отправлена на емайл:
    T:/home/server/www/spy2.php


    сообщается что он тоже был изменен а на самом деле он не был изменен, и если я изменю други файлы из списка , сообщение и емайла нету о том что они были изменены....
     
  2. jik

    jik

    Регистр.:
    11 мар 2009
    Сообщения:
    243
    Симпатии:
    133
    для каждого из файлов вы рассчитываете md5, но сравниваете с одной и той же md5, взятой из файла:

    PHP:
    $file_md5 "md5_log/md5.hash"
    Сделайте так:

    PHP:
    $file_md5 "md5_log/" $files ".md5.hash";
     
    Tycoon нравится это.
  3. Tycoon

    Tycoon Постоялец

    Регистр.:
    20 апр 2006
    Сообщения:
    77
    Симпатии:
    36
    Я теперь пробую записать МД5 всех файлов, но все равно скрипт отсылат 1 сообщение 6 раз об изменении 1 файла, а точнее менно того который я запускаю с этим кодом, вот я добавил МД5 для всех фалов но ечть ошибка я не могу паноять где именно

    PHP:
     ////////////////////////////////// 
    $arr file("md5_log/file.list"); 
    foreach (
    $arr as $files


    echo 
    "File $files  <br>"
     
    $fp1 fopen("md5_log/md5.hash"'w+');  
        foreach (
    $arr as $value
       
       { 
            
    $files trim($value); 
            
    fwrite($fp1md5_file($files) . "\n"); // записываю хеши  фалов из списка$arr
     
        
     
    }   fclose($fp1); 



    $file_md5 file("md5_log/md5.hash");  //считываю их в массив

    // 
    $md5_new_file = @md5_file($files); 
    $md5_old_file file_get_contents($file_md5); 

    if (
    $md5_new_file <> $md5_old_file

        echo 
    "Файл был изменен"
        
    rename($file_md5$file_md5 ".bak"); 
        
    $fp fopen($file_md5'w'); 
        
    fwrite($fp$md5_new_file); 
        
    fclose($fp); 
        
    ///////////////// crontab 

        
    $message "В последний раз файл <br>" $files " был изменен: " date("d-Y-H:i:s."
            @
    filemtime($files)) . " MD5 файла: " . @md5_file($files) . " Размер файла: " . @ 
            
    filesize($files) . " байт"

        echo (
    "<br>Информация об измененных файлах отправлена на емайл: <br> " $files 
            
    "<br>"); 
        @
    mail('noreply@bk.ru'
            
    'Сообщение об изменение МД5 суммы файлов на сервере : http://' $_SERVER['SERVER_NAME'] . 
            
    $value$message); 

        
    //////////////////////////////////////////////////////////////// 
        
    unlink($file_md5 ".bak"); 


    // 
    else 

        echo 
    "Ничего не изменилось"


    }
     
  4. jik

    jik

    Регистр.:
    11 мар 2009
    Сообщения:
    243
    Симпатии:
    133
    1) не следует использовать цикл в цикле, сбивается внутренний указатель массива:

    PHP:
    foreach ($arr as $files

    ...
        foreach (
    $arr as $value)
    ...
    2) переменная, определенная внутри вложенного цикла,

    PHP:
    $files trim($value);
    используется далее вне этого цикла (содержит значение, присвоенное в последнем цикле, надо ли оно?)

    Лучше переписать код заново, используя следующий алгоритм. В file.list храним полный путь к файлам, по которым контролируем контр.сумму. В md5.hash храним имена файлов и контрольные суммы через ':', например:

    Код:
    /usr/www/index.php:23424234dfe78ed87
    /usr/www/index.html:596890834908d989f
    Реализация может быть, например, такой:
    PHP:
    $filename_filelist 'md5_log/file.list';
    $filename_md5hash 'md5_log/md5.hash';
    $arr file($filename_filelist); 
    $arr_tmp file($filename_md5hash);
    $arr_md5 = array();
    // считываем md5.hash в ассоц.массив
    foreach ($arr_tmp as $fileAndmd5) { 
      
    $aRow explode(':'trim($fileAndmd5));
      if (
    sizeof($aRow) == 2) {
        
    $arr_md5[trim($aRow[0])] = trim($aRow[1]); // пара Имя файла -> md5
      
    }
    }

    //проход по именам файлов и проверка md5
    $md5_changed false;
    foreach (
    $arr as $value) { 
      
    $curfile trim($value);
      if (
    file_exists($curfile)) {
        
    $md5_org $arr_md5[$curfile];
        if (
    strlen($md5_org) > 0) {
          
    // контр сумма для текущего файла уже подсчитана - проверим
          
    $md5_curfile = @md5_file($curfile); 
          if (
    $md5_org != $md5_curfile) {
            
    $message "В последний раз файл <br>" $curfile " был изменен: " date("d-Y-H:i:s."
            @
    filemtime($curfile)) . " MD5 файла: " . @md5_file($curfile) . " Размер файла: " . @filesize($curfile) . " байт"
        echo (
    "<br>Информация об измененных файлах отправлена на емайл: <br> " $curfile 
            
    "<br>"); 
        @
    mail('noreply@bk.ru'
            
    'Сообщение об изменение МД5 суммы файлов на сервере : http://' $_SERVER['SERVER_NAME'] . 
            
    $cur_file$message); 
            
    // запомним новую md5
            
    $arr_md5[$curfile] = $md5_curfile;
            
    $md5_changed true;
          }
        } else {
          
    // для этого файла md5 еще не рассчитывалась
          
    $arr_md5[$curfile] = $md5_curfile;
          
    $md5_changed true;
        }
      }
    }
    if (
    $md5_changed) {
      
    // записываем в файл md5.hash измененный ассоц массив
      
    rename($filename_md5hash$filename_md5hash '.bak');
      
    $fp fopen($filename_md5hash'w'); 
      foreach(
    $arr_md5 as $curfile => $curmd5) {
        
    fwrite($fp"$curfile:$curmd5\n"); 
      }
      
    fclose($fp); 
      
    unlink($filename_md5hash '.bak');
    }
     
    Tycoon нравится это.
  5. medvoodoo

    medvoodoo Постоялец

    Регистр.:
    28 мар 2007
    Сообщения:
    89
    Симпатии:
    19
    PHP:
    <?php
    /**
     *Класс для проверки изменений файлов передается имя файла содержащего
     *список файлов, каждый файл на новой строке
     */
    class md5_check{
        
    /**
         * сообщение об ошибках
         *@var string
         */
        
    protected $Error '';    
        function 
    __construct($fileMask){
          if(!
    file_exists($fileMask)){$this->Error="Отсутствует шаблон";}
         else{
         
    $arrayFiles file($fileMask);
          foreach(
    $arrayFiles as $file){
          
    $file trim($file);
          
    $fileMD5 $file.".md5";//здесб если md5 файлы храняться в другой папке можно дописать изменения пути
          
    if(file_exists($file)){//если файл существует
            
    if(!file_exists($fileMD5)){//если не существует md5 файл
            
    $this->Errors .= "Отсутствует файл $file.$fileMD5 \r\n";
            
    file_put_contents($fileMD5,md5_file($file));
            }
            else{
            if(
    file_get_contents($fileMD5) != md5_file($file))
            {
                 
    $this->Errors .= "Файл \"$file\" был изменен ".date("d-Y-H:i:s.",filemtime($file))."\r\n";
                 
    file_put_contents($fileMD5,md5_file($file));
            }
            }
          }
          else{
            
    $this->Errors .= "Отсутствует файл $file\r\n";
          }
          }
          if(
    $this->Errors != ''){//если были ошибки то выполняется
            
    echo $this->Errors;
          }
         }
        }
    }
     
    Tycoon нравится это.
  6. Tycoon

    Tycoon Постоялец

    Регистр.:
    20 апр 2006
    Сообщения:
    77
    Симпатии:
    36
    Почемуто в файл хешей записывается в таком виде
    HTML:
    T:/home/v-nedv/www/robert.php:
    T:/home/v-nedv/www/md5.php:
    а Мд5 не записывается

    я сделал так:

    PHP:
     <?php

    $filename_filelist 
    'md5_log/file.list';

    $arr file($filename_filelist); 
    print 
    "<pre>";
    print_r($arr);
     

     
    $fp1 fopen("md5_log/md5.hash"'w'); // записываю в хеш файл файл:МД5
        
    foreach ($arr as $value)
        {
            
    $files trim($value);
            
    fwrite($fp1$files ":" md5_file($files) . "\n");

        }
        
    fclose($fp1);
        
    $filename_md5hash  file ('md5_log/md5.hash');    


        
    /////////////////////////////////
    $arr_tmp $filename_md5hash ;

    print 
    "<pre>"// тут получаю 
    Array
    (
        [
    0] => T:/home/v-nedv/www/robert.php:d6949cefad9162333a218d09a552b084

        
    [1] => T:/home/v-nedv/www/md.php:1605df3d7439cd267eb6a74e1ea66f40

    )
    print_r($arr_tmp);

    //$arr_tmp = file($filename_md5hash);
    $arr_md5 = array();


    // считываем md5.hash в ассоц.массив
    foreach ($arr_tmp as $fileAndmd5) { 
      
    $aRow explode(':'trim($fileAndmd5));
      
      if (
    sizeof($aRow) == 2) {
        
    $arr_md5[trim($aRow[0])] = trim($aRow[1]); // пара Имя файла -> md5
      
    }
        
    }



    //проход по именам файлов и проверка md5
    $md5_changed false;
    foreach (
    $arr as $value) { 
      
    $curfile trim($value);
      if (
    file_exists($curfile)) {
        
    $md5_org $arr_md5[$curfile];
        if (
    strlen($md5_org) > 0) {
          
    // контр сумма для текущего файла уже подсчитана - проверим
          
    $md5_curfile = @md5_file($curfile); 
          if (
    $md5_org != $md5_curfile) {
            
    $message "В последний раз файл <br>" $curfile " был изменен: " date("d-Y-H:i:s."
            @
    filemtime($curfile)) . " MD5 файла: " . @md5_file($curfile) . " Размер файла: " . @filesize($curfile) . " байт"
        echo (
    "<br>Информация об измененных файлах отправлена на емайл: <br> " $curfile 
            
    "<br>"); 
        @
    mail('noreply@bk.ru'
            
    'Сообщение об изменение МД5 суммы файлов на сервере : http://' $_SERVER['SERVER_NAME'] . 
            
    $cur_file$message); 
            
    // запомним новую md5
            
    $arr_md5[$curfile] = $md5_curfile;
            
    $md5_changed true;
          }
        } else {
          
    // для этого файла md5 еще не рассчитывалась
          
    $arr_md5[$curfile] = $md5_curfile;
          
    $md5_changed true;
        }
      }
    }
    if (
    $md5_changed) {
      
    // записываем в файл md5.hash измененный ассоц массив
      
    rename($filename_md5hash$filename_md5hash '.bak');
      
    $fp fopen($filename_md5hash'w'); 
      foreach(
    $arr_md5 as $curfile => $curmd5) {
        
    fwrite($fp"$curfile:$curmd5\n"); 
      }
      
    fclose($fp); 
      
    unlink($filename_md5hash '.bak');
    }  

    ?>
    скрипт выдает
    HTML:
    Warning:  rename() expects parameter 1 to be string, array given in T:\home\site\www\md.php on line 80
    
    
    
    Warning:  fopen() expects parameter 1 to be string, array given in T:\home\site
    \www\md.php on line 81
    
    
    
    Warning:  fwrite(): supplied argument is not a valid stream resource in T:\home\site
    \www\md.php on line 83
    
    
    
    Warning:  fwrite(): supplied argument is not a valid stream resource in T:\home\site
    \www\md.php on line 83
    
    
    
    Warning:  fclose(): supplied argument is not a valid stream resource in T:\home\site
    \www\md.php on line 85
    
    
    
    Warning:  unlink(Array.bak) [function.unlink]: No such file or directory in T:\home\site
    \www\md.php on line 86
     
  7. jik

    jik

    Регистр.:
    11 мар 2009
    Сообщения:
    243
    Симпатии:
    133
    нашел ошибку:
    PHP:
        $md5_curfile = @md5_file($curfile); 
    надо вынести из if вверх

    С учетом исправления код выглядит так:
    PHP:
    $filename_filelist 'md5_log/file.list';
    $filename_md5hash 'md5_log/md5.hash';
    $arr file($filename_filelist); 
    $arr_tmp file($filename_md5hash);
    $arr_md5 = array();
    // считываем md5.hash в ассоц.массив
    foreach ($arr_tmp as $fileAndmd5) { 
      
    $aRow explode(':'trim($fileAndmd5));
      if (
    sizeof($aRow) == 2) {
        
    $arr_md5[trim($aRow[0])] = trim($aRow[1]); // пара Имя файла -> md5
      
    }
    }

    //проход по именам файлов и проверка md5
    $md5_changed false;
    foreach (
    $arr as $value) { 
      
    $curfile trim($value);
      if (
    file_exists($curfile)) {
        
    $md5_org $arr_md5[$curfile];
        
    $md5_curfile = @md5_file($curfile); 
        if (
    strlen($md5_org) > 0) {
          
    // контр сумма для текущего файла уже подсчитана - проверим
          
    if ($md5_org != $md5_curfile) {
            
    $message "В последний раз файл <br>" $curfile " был изменен: " date("d-Y-H:i:s."
            @
    filemtime($curfile)) . " MD5 файла: " . @md5_file($curfile) . " Размер файла: " . @filesize($curfile) . " байт"
        echo (
    "<br>Информация об измененных файлах отправлена на емайл: <br> " $curfile 
            
    "<br>"); 
        @
    mail('noreply@bk.ru'
            
    'Сообщение об изменение МД5 суммы файлов на сервере : http://' $_SERVER['SERVER_NAME'] . 
            
    $cur_file$message); 
            
    // запомним новую md5
            
    $arr_md5[$curfile] = $md5_curfile;
            
    $md5_changed true;
          }
        } else {
          
    // для этого файла md5 еще не рассчитывалась
          
    $arr_md5[$curfile] = $md5_curfile;
          
    $md5_changed true;
        }
      }
    }
    if (
    $md5_changed) {
      
    // записываем в файл md5.hash измененный ассоц массив
      
    rename($filename_md5hash$filename_md5hash '.bak');
      
    $fp fopen($filename_md5hash'w'); 
      foreach(
    $arr_md5 as $curfile => $curmd5) {
        
    fwrite($fp"$curfile:$curmd5\n"); 
      }
      
    fclose($fp); 
      
    unlink($filename_md5hash '.bak');
    }  
     
    Tycoon нравится это.
  8. Tycoon

    Tycoon Постоялец

    Регистр.:
    20 апр 2006
    Сообщения:
    77
    Симпатии:
    36
    спасибо, но сейчас если файл был изменен, мне кажется что условие // контр сумма для текущего файла уже подсчитана - проверим
    if ($md5_org != $md5_curfile) не срабатывает, т.е никаких сообщений не приходити не выводится, не мог бы подсказать в чем дело?
     
  9. jik

    jik

    Регистр.:
    11 мар 2009
    Сообщения:
    243
    Симпатии:
    133
    вот это место:

    PHP:
    $filename_md5hash  file ('md5_log/md5.hash');    
    /////////////////////////////////
    $arr_tmp $filename_md5hash ;
    надо заменить на:

    PHP:
    $filename_md5hash  'md5_log/md5.hash';
    /////////////////////////////////
    $arr_tmp file($filename_md5hash);
    Добавлено через 5 минут
    а если добавить вывод перед проверкой?:
    PHP:
    echo "curfile=$curfile md5_org=$md5_org md5_curfile=$md5_curfile<br>";
     
    Tycoon нравится это.
  10. Tycoon

    Tycoon Постоялец

    Регистр.:
    20 апр 2006
    Сообщения:
    77
    Симпатии:
    36
    белый экран выводится, ничего не выводит, насчет замены не очень понял т.к. ты же сам писал $filename_filelist = 'md5_log/file.list';
    $filename_md5hash = 'md5_log/md5.hash';
    $arr = file($filename_filelist);
    $arr_tmp = file($filename_md5hash);
    $arr_md5 = array();
     
Статус темы:
Закрыта.