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.



