Script PHP Cek Double Entry Dari Setiap Line Dalam 1 File

Script untuk pengecekan double entry dari setiap linenya dalam 1 file. Dapat digunain juga untuk pengecekan wordlist, email, password, proxy, dll

Jadi ceritanya kemarin ada NOC yang bertanya, bisa ga sih klo kita ngecek entri konfigurasi yang double menggunakan script. Terus ane dikasi contoh file yang namanya nice.rsc. Setelah saya buka, ternyata file tersebut digunakan untuk menambahkan alamat IP yang terdaftar di OpenIXP ke MikroTik RouterOS.

Setelah saya cek lagi dari atas ke bawah, ternyata konfigurasinya 1 line 1 rule. Karena 1 line 1 rule juga saya jadi ingat dengan sistem semacam wordlist untuk melakukan bruteforce. =D

Lalu saya iseng dan membuat scriptnya untuk ngecek entry yang double dari setiap linenya dalam 1 file. Jadi bisa digunain juga untuk ngecek wordlist, email, password, proxy, dll yang double2.

Penampakannya kurang lebih seperti di sini :

Scriptnya:

  1<?php
  2/**
  3 * This program used to find duplicate entry for each line of text from given
  4 * file. For example to check list of email, proxy, username:password,
  5 * configurations, etc.
  6 * 
  7 * This is not WebBased PHP program, so use it from CLI.
  8 * Depend on your machine, you might need to reset your PHP memory_limit to -1
  9 * for checking large file.
 10 * 
 11 * Still very early release, hasn't been tested on Windows and just for fun
 12 * coding purpose :)
 13 * 
 14 * coded by ditatompel
 15 * Usage : new findDuplicates($argv);
 16 */
 17
 18class FindDuplicates
 19{
 20    var $cmd = array();
 21    var $reqFunc = array('file_get_contents', 'fopen', 'fwrite');
 22    
 23    function __construct ($opts) {
 24        $this->checkReqFunc();
 25        
 26        $this->cmd = $this->args($opts);
 27        if ( !array_key_exists('list', $this->cmd) )
 28            exit( $this->usage($this->cmd['input'][0]) );
 29        $this->enumValues($this->cmd['list']);
 30    }
 31    
 32    function checkReqFunc() {
 33        $ok = 1;
 34        foreach( $this->reqFunc as $func ) {
 35            if ( !function_exists($func) ) {
 36                print 'You need function ' . $func . " to execute this tool!\n";
 37                $ok = 0;
 38            }
 39        }
 40        if(php_sapi_name() != 'cli') {
 41            print "<strong>This is not WebBased program! Use this tool from CLI.</strong>";
 42            $ok = 0;
 43        }
 44        if ( !$ok ) exit;
 45    }
 46    
 47    /**
 48     * Check list file
 49     * @return bool. TRUE if file exists and readable.
 50     */
 51    function cekFile ($file) {
 52        if ( !is_file($file) || !is_readable($file) )
 53            return false;
 54        return true;
 55    }
 56    
 57    private function usage($file) {
 58        $msg = "Usage : ";
 59        $msg .= $file . " --list=[list]\n";
 60        $msg .= "\tOptions : \n";
 61        $msg .= "\t\t-v :\t\t verbose mode.\n";
 62        $msg .= "\t\t--out=[file] :\t Save non duplicate entry to file.\n";
 63        $msg .= "Example :\n";
 64        $msg .= $file . " --list=/path/to/file.txt --out=/path/to/file.txt.new -v\n";
 65        return $msg;
 66    }
 67    
 68    private function enumValues($filename) {
 69        if ( !$this->cekFile($filename) )
 70            exit("File is not readable!\n");
 71        if ( array_key_exists("out", $this->cmd) ) {
 72            $this->checkWrite($this->cmd['out']);
 73            $fh = fopen($this->cmd['out'], 'w');
 74        }
 75        $time_start = microtime(1);
 76        print "File : " . $filename . " (" . $this->format_bytes(filesize($filename)) . ")\n";
 77        $fGetContents = file_get_contents($filename);
 78        $content = explode("\n", $fGetContents);
 79        $totalLines = count($content);
 80        print "Total : " . $this->plural($totalLines,'line') . "\n";
 81        $totalDuplicate = 0;
 82        print "Please be patient, process will be a little longer for large file sizes...\n";
 83        $unique = array_unique($content);
 84        if( $totalLines > count($unique) ) {
 85            for($i = 0; $i < $totalLines; $i++) {
 86                $percentage = (int)number_format($i/$totalLines, 2, '', '');
 87                $prog = "Progress : " . $this->ID_nummeric($i) . "/" . $this->ID_nummeric($totalLines) . " " . $percentage . "%";
 88                echo $prog;
 89                echo "\033[" . strlen($prog) . "D";
 90                if(!array_key_exists($i, $unique)) {
 91                    if ( array_key_exists("v", $this->cmd) )
 92                        print "Duplicate entry on line " . ($i+1) . ": " . $content[$i] . "\n";
 93                    $totalDuplicate++;
 94                }
 95                else {
 96                    if ( array_key_exists("out", $this->cmd) ) {
 97                        if ( !is_writable($this->cmd['out']) )
 98                            exit("[Error] " . $this->cmd['out'] . " is not writable.\n");
 99                        fwrite($fh, $content[$i] . "\n");
100                    }
101                }
102            }
103        }
104        print "Total duplicate entry : " . $this->plural($totalDuplicate)  . "\n";
105        if ( array_key_exists("out", $this->cmd) )
106            print "New list saved to: " . $this->cmd['out'] . " (" . $this->format_bytes(filesize($this->cmd['out'])) . ")\n";
107        $time_end = microtime(1);
108        $execution_time = ($time_end - $time_start);
109        print 'process complete in ' . $execution_time . " sec\n";
110    }
111
112    private function ID_nummeric ($number) {
113        return number_format($number, 0, ',','.');
114    }
115    
116    private function checkWrite($location) {
117        if ( is_dir($location) )
118            exit("[Error] " . $location . " is a directory.\n");
119    }
120    
121    private function plural($number, $txt='item') {
122        if ( $number > 1 ) 
123            return $this->ID_nummeric($number) . " "  . $txt . "s";
124        return $this->ID_nummeric($number) . " "  . $txt;
125    }
126    
127    // yatsynych at gmail dot com
128    function format_bytes($a_bytes) {
129        if ($a_bytes < 1024) {
130            return $a_bytes .' B';
131        } elseif ($a_bytes < 1048576) {
132            return round($a_bytes / 1024, 2) .' KiB';
133        } elseif ($a_bytes < 1073741824) {
134            return round($a_bytes / 1048576, 2) . ' MiB';
135        } elseif ($a_bytes < 1099511627776) {
136            return round($a_bytes / 1073741824, 2) . ' GiB';
137        } elseif ($a_bytes < 1125899906842624) {
138            return round($a_bytes / 1099511627776, 2) .' TiB';
139        } elseif ($a_bytes < 1152921504606846976) {
140            return round($a_bytes / 1125899906842624, 2) .' PiB';
141        } elseif ($a_bytes < 1180591620717411303424) {
142            return round($a_bytes / 1152921504606846976, 2) .' EiB';
143        } elseif ($a_bytes < 1208925819614629174706176) {
144            return round($a_bytes / 1180591620717411303424, 2) .' ZiB';
145        } else {
146            return round($a_bytes / 1208925819614629174706176, 2) .' YiB';
147        }
148    }
149    
150    /**
151     * Make UNIX like parameter command.
152     * This function from losbrutos and modified by earomero. Thankyou. =)
153     * @author losbrutos <[email protected]>
154     * @author earomero <[email protected]>
155     * @param array argv
156     * @return array
157     */
158    private function args($argv) {
159        $_ARG = array();
160        foreach ($argv as $arg) {
161            if (preg_match('#^-{1,2}([a-zA-Z0-9]*)=?(.*)$#', $arg, $matches)) {
162                $key = $matches[1];
163                switch ($matches[2]) {
164                    case '':
165                    case 'true':
166                    $arg = true;
167                    break;
168                    case 'false':
169                    $arg = false;
170                    break;
171                    default:
172                    $arg = $matches[2];
173                }
174                
175                // make unix like -afd == -a -f -d
176                if(preg_match("/^-([a-zA-Z0-9]+)/", $matches[0], $match)) {
177                    $string = $match[1];
178                    for($i=0; strlen($string) > $i; $i++) {
179                        $_ARG[$string[$i]] = true;
180                    }
181                } else {
182                    $_ARG[$key] = $arg;
183                }
184            } else {
185                $_ARG['input'][] = $arg;
186            }
187        }
188        return $_ARG;
189    }
190}
191?>

Tinggal panggil classnya :

1$cek = new FindDuplicates ($argv); 

Ingat, ini CLI ya.. jadi buat eksekusinya :

1php [nama_script_phpnya] --list=[nama_file_yang_di_cek]

Ada 2 option tambahan yang bisa digunakan :

  • -v : untuk verbose mode.
  • --out=[file] : buat bikin file baru yang udah diilangin duplikatnya.
1php class.FindDuplicates.php --list=openixp.rsc --out=openixp.rsc.new -v

Akan menampilkan line yang sama/serupa/sudah ada ke terminal dari file openixp.rsc kemudian bikin file baru yang udah ‘dibersihin’ dengan nama openixp.rsc.new.

Misal file yang mau di cek gede, sampe puluhan mega, mungkin perlu ngeset PHP memory_limit nya jadi -1.

Belum saya test di windows. Silahkan klo ada yg mau mengembangkan.