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.