SHOW:
|
|
- or go back to the newest paste.
| 1 | <?php | |
| 2 | $kalimat1 = isset($_POST['kalimat1']) ? $_POST['kalimat1'] : 'Indonesia Raya'; | |
| 3 | $kalimat2 = isset($_POST['kalimat2']) ? $_POST['kalimat2'] : 'Indonesia Jaya'; | |
| 4 | $n = isset($_POST['n']) ? $_POST['n'] : 5; | |
| 5 | $window = isset($_POST['window']) ? $_POST['window'] : 4; | |
| 6 | $prima = isset($_POST['prima']) ? $_POST['prima'] : 2; | |
| 7 | ||
| 8 | ?> | |
| 9 | <html> | |
| 10 | <head> | |
| 11 | <title>Deteksi Plagiarisme Memanfaatkan Algoritma Winnowing</title> | |
| 12 | </head> | |
| 13 | <body> | |
| 14 | <form method="POST" action="winnowing.php"> | |
| 15 | <p>Kalimat 1 : </p> | |
| 16 | <textarea name="kalimat1" style="width :100%" rows="5"><?php echo $kalimat1;?></textarea> | |
| 17 | <p>Kalimat 2 : </p> | |
| 18 | <textarea name="kalimat2" style="width :100%" rows="5"><?php echo $kalimat2;?></textarea> | |
| 19 | <p>N Gram : <input type ="text" name = "n" value = "<?php echo $n;?>" ></p> | |
| 20 | <p>Window : <input type ="text" name = "window" value = "<?php echo $window;?>" ></p> | |
| 21 | <p>Bilangan Prima : | |
| 22 | <select name = "prima"> | |
| 23 | <option>Pilih Salah Satu</option> | |
| 24 | <?php | |
| 25 | for($i = 2; $i < 100; $i++){
| |
| 26 | $hitung = 0; | |
| 27 | for($j = 1; $j <= $i; $j++){
| |
| 28 | if(($i % $j) == 0) $hitung++; | |
| 29 | } | |
| 30 | if($hitung == 2) {
| |
| 31 | $selected = ''; if($prima == $i) $selected = ' selected'; | |
| 32 | echo '<option value="'.$i.'" '.$selected.'>'.$i.'</option>'; | |
| 33 | } | |
| 34 | } | |
| 35 | ?> | |
| 36 | </select> | |
| 37 | </p> | |
| 38 | <p><input type=Submit value="Proses"></p> | |
| 39 | </form> | |
| 40 | <?php | |
| 41 | if(!$_POST) {
| |
| 42 | echo "</body>\n</html>"; | |
| 43 | exit; | |
| 44 | } | |
| 45 | ||
| 46 | $w = new winnowing($kalimat1, $kalimat2); | |
| 47 | $w->SetPrimeNumber($prima); | |
| 48 | $w->SetNGramValue($n); | |
| 49 | $w->SetNWindowValue($window); | |
| 50 | ||
| 51 | $w->process(); | |
| 52 | ||
| 53 | ?> | |
| 54 | <h2>Hasil Proses</h2> | |
| 55 | <table style="width : 100%;"> | |
| 56 | <tr> | |
| 57 | <td>N-GRAM Kalimat 1</td> | |
| 58 | <td>N-GRAM Kalimat 2</td> | |
| 59 | </tr> | |
| 60 | <tr> | |
| 61 | <td> | |
| 62 | <textarea style="width :100%; overflow-y:scroll;" rows="5"> | |
| 63 | <?php | |
| 64 | $s =''; | |
| 65 | foreach($w->GetNGramFirst() as $ng){
| |
| 66 | $s .= $ng.' '; | |
| 67 | } | |
| 68 | echo rtrim($s, ' '); | |
| 69 | ?> | |
| 70 | </textarea> | |
| 71 | </td> | |
| 72 | <td> | |
| 73 | <textarea style="width :100%;overflow-y:scroll;" rows="5"> | |
| 74 | <?php | |
| 75 | $s =''; | |
| 76 | foreach($w->GetNGramSecond() as $ng){
| |
| 77 | $s .= $ng.' '; | |
| 78 | } | |
| 79 | echo rtrim($s, ' '); | |
| 80 | ?> | |
| 81 | </textarea> | |
| 82 | </td> | |
| 83 | </tr> | |
| 84 | <tr> | |
| 85 | <td>Rolling Hash Kalimat 1</td> | |
| 86 | <td>Rolling Hash Kalimat 2</td> | |
| 87 | </tr> | |
| 88 | <tr> | |
| 89 | <td><textarea style="width :100%; overflow-y:scroll;" rows="5"> | |
| 90 | <?php | |
| 91 | $s=''; | |
| 92 | foreach($w->GetRollingHashFirst() as $rl){
| |
| 93 | $s .= $rl.' '; | |
| 94 | } | |
| 95 | echo rtrim($s, ' '); | |
| 96 | ?> | |
| 97 | </textarea></td> | |
| 98 | <td><textarea style="width :100%;overflow-y:scroll;" rows="5"> | |
| 99 | <?php | |
| 100 | $s=''; | |
| 101 | foreach($w->GetRollingHashSecond() as $rl){
| |
| 102 | $s .= $rl.' '; | |
| 103 | } | |
| 104 | echo rtrim($s, ' '); | |
| 105 | ?> | |
| 106 | </textarea></td> | |
| 107 | </tr> | |
| 108 | <tr> | |
| 109 | <td>Window Kalimat 1</td> | |
| 110 | <td>Window Kalimat 2</td> | |
| 111 | </tr> | |
| 112 | <tr> | |
| 113 | <td><textarea style="width :100%; overflow-y:scroll;" rows="5"> | |
| 114 | <?php | |
| 115 | $wd = $w->GetWindowFirst(); | |
| 116 | for($i = 0; $i< count($wd); $i++){
| |
| 117 | $s = ''; | |
| 118 | for($j=0; $j < $window; $j++){
| |
| 119 | $s .= $wd[$i][$j]. ' '; | |
| 120 | } | |
| 121 | echo "W-".($i+1)." : {".rtrim($s, ' ')."}\n";
| |
| 122 | } | |
| 123 | ?> | |
| 124 | </textarea></td> | |
| 125 | <td><textarea style="width :100%;overflow-y:scroll;" rows="5"> | |
| 126 | <?php | |
| 127 | $wd = $w->GetWindowSecond(); | |
| 128 | for($i = 0; $i< count($wd); $i++){
| |
| 129 | $s = ''; | |
| 130 | for($j=0; $j < $window; $j++){
| |
| 131 | $s .= $wd[$i][$j]. ' '; | |
| 132 | } | |
| 133 | echo "W-".($i+1)." : {".rtrim($s, ' ')."}\n";
| |
| 134 | } | |
| 135 | ?> | |
| 136 | </textarea></td> | |
| 137 | </tr> | |
| 138 | <tr> | |
| 139 | <td>Fingerprints Kalimat 1</td> | |
| 140 | <td>Fingerprints Kalimat 2</td> | |
| 141 | </tr> | |
| 142 | <tr> | |
| 143 | <td><textarea style="width :100%; overflow-y:scroll;" rows="5"> | |
| 144 | <?php | |
| 145 | $s=''; | |
| 146 | foreach($w->GetFingerprintsFirst() as $fp){
| |
| 147 | $s .= $fp.' '; | |
| 148 | } | |
| 149 | echo rtrim($s, ' '); | |
| 150 | ?> | |
| 151 | </textarea></td> | |
| 152 | <td><textarea style="width :100%;overflow-y:scroll;" rows="5"> | |
| 153 | <?php | |
| 154 | $s=''; | |
| 155 | foreach($w->GetFingerprintsSecond() as $fp){
| |
| 156 | $s .= $fp.' '; | |
| 157 | } | |
| 158 | echo rtrim($s, ' '); | |
| 159 | ||
| 160 | $count_fingers1 = count($w->GetFingerprintsFirst()); | |
| 161 | $count_fingers2 = count($w->GetFingerprintsSecond()); | |
| 162 | ||
| 163 | $count_union_fingers = count(array_merge($w->GetFingerprintsFirst(), $w->GetFingerprintsSecond())); | |
| 164 | $count_intersect_fingers = count(array_intersect($w->GetFingerprintsFirst(), $w->GetFingerprintsSecond())); | |
| 165 | ||
| 166 | ?> | |
| 167 | </textarea> | |
| 168 | </td> | |
| 169 | </tr> | |
| 170 | </table> | |
| 171 | <p>Jumlah Fingerprints kalimat 1 = <?php echo $count_fingers1;?></p> | |
| 172 | <p>Jumlah Fingerprints kalimat 2 - <?php echo $count_fingers2;?></p> | |
| 173 | <p>Union (Gabungan) Fingerprints 1 dan 2 = <?php echo $count_union_fingers;?></p> | |
| 174 | <p>Intersection (fingerprints yang sama) = <?php echo $count_intersect_fingers;?></p> | |
| 175 | <p>(Union - Intersection) = <?php echo ($count_union_fingers - $count_intersect_fingers);?></p> | |
| 176 | <p>Prosentase Plagiarisme </p> | |
| 177 | <p> Koefisien Jaccard = (Intersection / (Union-Intersection)) * 100 </p> | |
| 178 | <p> (<?php echo $count_intersect_fingers ."/".($count_union_fingers - $count_intersect_fingers).") * 100 = ".$w->GetJaccardCoefficient();?> %</p> | |
| 179 | </body> | |
| 180 | </html> | |
| 181 | ||
| 182 | <?php | |
| 183 | class winnowing {
| |
| 184 | private $word1 = ''; | |
| 185 | private $word2 = ''; | |
| 186 | ||
| 187 | //input properties | |
| 188 | private $prime_number = 3; | |
| 189 | private $n_gram_value = 2; | |
| 190 | private $n_window_value = 4; | |
| 191 | ||
| 192 | //output properties | |
| 193 | private $arr_n_gram1; | |
| 194 | private $arr_n_gram2; | |
| 195 | private $arr_rolling_hash1; | |
| 196 | private $arr_rolling_hash2; | |
| 197 | private $arr_window1; | |
| 198 | private $arr_window2; | |
| 199 | private $arr_fingerprints1; | |
| 200 | private $arr_fingerprints2; | |
| 201 | ||
| 202 | public function SetPrimeNumber($value){
| |
| 203 | $this->prime_number = $value; | |
| 204 | } | |
| 205 | public function SetNGramValue($value){
| |
| 206 | $this->n_gram_value = $value; | |
| 207 | } | |
| 208 | public function SetNWindowValue($value){
| |
| 209 | $this->n_window_value = $value; | |
| 210 | } | |
| 211 | public function GetNGramFirst(){
| |
| 212 | return $this->arr_n_gram1; | |
| 213 | } | |
| 214 | public function GetNGramSecond(){
| |
| 215 | return $this->arr_n_gram2; | |
| 216 | } | |
| 217 | public function GetRollingHashFirst(){
| |
| 218 | return $this->arr_rolling_hash1; | |
| 219 | } | |
| 220 | public function GetRollingHashSecond(){
| |
| 221 | return $this->arr_rolling_hash2; | |
| 222 | } | |
| 223 | public function GetWindowFirst(){
| |
| 224 | return $this->arr_window1; | |
| 225 | } | |
| 226 | public function GetWindowSecond(){
| |
| 227 | return $this->arr_window2; | |
| 228 | } | |
| 229 | public function GetFingerprintsFirst(){
| |
| 230 | return $this->arr_fingerprints1; | |
| 231 | } | |
| 232 | public function GetFingerprintsSecond(){
| |
| 233 | return $this->arr_fingerprints2; | |
| 234 | } | |
| 235 | public function GetJaccardCoefficient($prosen = true){
| |
| 236 | if($prosen) | |
| 237 | return round( ($this->jaccard_coefficient * 100), 2); | |
| 238 | else | |
| 239 | return $this->jaccard_coefficient; | |
| 240 | } | |
| 241 | ||
| 242 | function __construct($w1, $w2){
| |
| 243 | $this->word1 = $w1; | |
| 244 | $this->word2 = $w2; | |
| 245 | } | |
| 246 | ||
| 247 | public function process(){
| |
| 248 | if (($this->word1 == '') || ($this->word2 == '')) exit; | |
| 249 | ||
| 250 | //langkah 1 : buang semua huruf yang bukan kelompok [a-z A-Z 0-9] dan ubah menjadi huruf kecil semua (lowercase) | |
| 251 | $this->word1 = strtolower(str_replace(' ','',preg_replace("/[^a-zA-Z0-9\s-]/", "", $this->word1)));
| |
| 252 | $this->word2 = strtolower(str_replace(' ','',preg_replace("/[^a-zA-Z0-9\s-]/", "", $this->word2)));
| |
| 253 | ||
| 254 | //langkah 2 : buat N-Gram | |
| 255 | $this->arr_n_gram1 = $this->n_gram($this->word1, $this->n_gram_value); | |
| 256 | $this->arr_n_gram2 = $this->n_gram($this->word2, $this->n_gram_value); | |
| 257 | ||
| 258 | //langkah 3 : rolling hash untuk masing-masing n gram | |
| 259 | $this->arr_rolling_hash1 = $this->rolling_hash($this->arr_n_gram1); | |
| 260 | $this->arr_rolling_hash2 = $this->rolling_hash($this->arr_n_gram2); | |
| 261 | ||
| 262 | //langkah 4 : buat windowing untuk masing-masing tabel hash | |
| 263 | $this->arr_window1 = $this->windowing($this->arr_rolling_hash1, $this->n_window_value); | |
| 264 | $this->arr_window2 = $this->windowing($this->arr_rolling_hash2, $this->n_window_value); | |
| 265 | ||
| 266 | //langkah 5 : cari nilai minimum masing-masing window table (fingerprints) | |
| 267 | $this->arr_fingerprints1 = $this->fingerprints($this->arr_window1); | |
| 268 | $this->arr_fingerprints2 = $this->fingerprints($this->arr_window2); | |
| 269 | ||
| 270 | //langkah 6 : hitung koefisien plagiarisme memanfaatkan persamaan Jaccard Coefficient | |
| 271 | $this->jaccard_coefficient = $this->jaccard_coefficient($this->arr_fingerprints1, $this->arr_fingerprints2); | |
| 272 | } | |
| 273 | ||
| 274 | private function n_gram($word, $n) {
| |
| 275 | $ngrams = array(); | |
| 276 | $length = strlen($word); | |
| 277 | for($i = 0; $i < $length; $i++) {
| |
| 278 | if($i > ($n - 2)) {
| |
| 279 | $ng = ''; | |
| 280 | for($j = $n-1; $j >= 0; $j--) {
| |
| 281 | $ng .= $word[$i-$j]; | |
| 282 | } | |
| 283 | $ngrams[] = $ng; | |
| 284 | } | |
| 285 | } | |
| 286 | return $ngrams; | |
| 287 | } | |
| 288 | ||
| 289 | private function char2hash($string) {
| |
| 290 | if (strlen($string) == 1) {
| |
| 291 | return ord($string); | |
| 292 | } else {
| |
| 293 | $result = 0; | |
| 294 | $length = strlen($string); | |
| 295 | for ($i = 0; $i < $length; $i++) {
| |
| 296 | $result += ord(substr($string, $i, 1)) * pow($this->prime_number, $length-$i); | |
| 297 | } | |
| 298 | return $result; | |
| 299 | } | |
| 300 | } | |
| 301 | ||
| 302 | private function rolling_hash($ngram){
| |
| 303 | $roll_hash = array(); | |
| 304 | foreach($ngram as $ng){
| |
| 305 | $roll_hash[] = $this->char2hash($ng); | |
| 306 | } | |
| 307 | return $roll_hash; | |
| 308 | } | |
| 309 | ||
| 310 | private function windowing($rolling_hash, $n){
| |
| 311 | $ngram = array(); | |
| 312 | $length = count($rolling_hash); | |
| 313 | $x = 0; | |
| 314 | for($i = 0; $i < $length; $i++){
| |
| 315 | if($i > ($n - 2)) {
| |
| 316 | $ngram[$x] = array(); | |
| 317 | $y = 0; | |
| 318 | for($j = $n-1; $j >= 0; $j--){
| |
| 319 | $ngram[$x][$y] = $rolling_hash[$i-$j]; | |
| 320 | $y++; | |
| 321 | } | |
| 322 | $x++; | |
| 323 | } | |
| 324 | } | |
| 325 | //echo $x.' '.$y; | |
| 326 | return $ngram; | |
| 327 | } | |
| 328 | ||
| 329 | private function fingerprints($window_table){
| |
| 330 | $fingers = array(); | |
| 331 | for($i = 0; $i < count($window_table); $i++){
| |
| 332 | $min = $window_table[$i][0]; | |
| 333 | for($j = 1 ; $j < $this->n_window_value; $j++){
| |
| 334 | if($min > $window_table[$i][$j]) | |
| 335 | $min = $window_table[$i][$j]; | |
| 336 | } | |
| 337 | $fingers[] = $min; | |
| 338 | } | |
| 339 | return $fingers; | |
| 340 | } | |
| 341 | ||
| 342 | private function jaccard_coefficient($fingerprint1, $fingerprint2){
| |
| 343 | $arr_intersect = array_intersect( $fingerprint1, $fingerprint2 ); | |
| 344 | $arr_union = array_merge( $fingerprint1, $fingerprint2 ); | |
| 345 | ||
| 346 | $count_intersect_fingers = count($arr_intersect); | |
| 347 | $count_union_fingers = count( $arr_union ); | |
| 348 | ||
| 349 | $coefficient = $count_intersect_fingers / | |
| 350 | ($count_union_fingers - $count_intersect_fingers ); | |
| 351 | ||
| 352 | return $coefficient; | |
| 353 | } | |
| 354 | } | |
| 355 | ?> |