#!/usr/bin/perl
use Time::Local;
$minLen=1;                           # minimum number of digits in bigmap
%adrr=(\'addr1\'                    => \'file1.dat\',
       \'addr2\'                    => \'file2.dat\'
      );
                          
$client=$ENV{HTTP_REFERER};
$client=~s/\\/[^\\/]*$//;
$counterFile=$adrr{$client};
exit unless $counterFile;
@digits = ("3c 66 66 66 66 66 66 66 66 3c",  # 0
           "30 38 30 30 30 30 30 30 30 30",  # 1
           "3c 66 60 60 30 18 0c 06 06 7e",  # 2
           "3c 66 60 60 38 60 60 60 66 3c",  # 3
           "30 30 38 38 34 34 32 7e 30 78",  # 4
           "7e 06 06 06 3e 60 60 60 66 3c",  # 5
           "38 0c 06 06 3e 66 66 66 66 3c",  # 6
           "7e 66 60 60 30 30 18 18 0c 0c",  # 7
           "3c 66 66 66 3c 66 66 66 66 3c",  # 8
           "3c 66 66 66 66 7c 60 60 30 1c"); # 9
&incrementCount;
&generateBitmap;
&writeBitmap;
sub writeBitmap 
{  print "Content-type: image/x-xbitmap\\n\\n";
   printf ("#define count_width %d\\n#define count_height 10\\n", $len*8);
   printf STDOUT "static char count_bits[] = {\\n";
   for($i=0; $i<($#bytes+1); $i++) 
   {  print("0x$bytes[$i]");
      if ($i != $#bytes) 
      {  print(",");
         if (($i+1) % 7 == 0) 
         {  print("\\n");
         }
      }
   }
   print("};\\n");
}
sub generateBitmap 
{  $count = $totalReads;
   @bytes = ();
   $len = length($count) > $minLen ? length($count) : $minLen;
   $formattedCount = sprintf("%0${len}d",$count);
   for ($y=0; $y < 10; $y++) 
   {  for ($x=0; $x<$len; $x++) 
      {  $digit=substr($formattedCount,$x,1);
         $byte=substr(@digits[$digit],$y*3,2);
         push(@bytes,$byte);
      }
   }
}
sub incrementCount 
{  my (@a,$time,$remoteAdr,$limit);
   $time=timelocal((localtime)[0..5]);
   $remoteAdr=$ENV{REMOTE_ADDR};
   $limit=300;
   if (open(F,"<$counterFile")) 
   {  flock(F,1);
      chomp  ($totalReads=);
      while ()
      {  chomp;
         @a=split(/;/,$_);
         $lastClient{$a[0]}=$a[1];
      }
      close(F);
   }
   $totalReads++ if (!$lastClient{$remoteAdr} || $time-$lastClient{$remoteAdr}>$limit);
   $lastClient{$remoteAdr}=$time;
   if (open(F,">$counterFile"))
   {  flock(F,2);
      print F "$totalReads\\n";
      foreach (keys %lastClient)
      {  print F "$_;$lastClient{$_}\\n" if ($time-$lastClient{$_}<$limit);
      }
      close(F);
   }
}
Скрипт можно использовать для нескольких адресов.
В хэше %adrr заносится \'адресс страницы\' на которой установлен счётчик и файл для этой страницы.
При первом использовании файлы должны существовать, права для них - 6Х6. Для скрипта - как обычно 7Х5.