Velika potražnja za programerima u zadnje vrijeme dovela je programiranje na titulu jednog od najpopularnijih zanimanja današnjice. Programski kodovi za određene funkcionalnosti se mogu pronaći na Internetu u par klikova. To dovodi do problema da se sve više programskih rješenja plagira, što zbog specifičnosti pisanja programskog koda nije lako otkriti. U ovom radu razmatraju se osnovne tehnike plagiranja programskog koda, kao i neke od tehnika detekcije plagijata u programskom kodu.
Plagijat se definira kao čin prisvajanja ili kopiranja tuđeg pisanog, umjetničkog ili drugog kreativnog rada u svoj vlastiti, bilo djelomice ili u cijelosti, bez navođenja izvornog autorstva ili izvornika [1]. Iz definicije se vidi da se plagiranje ne odnosi samo na tekstualne zapise, ali se danas najčešće srećemo upravo s tom vrstom plagiranja, pogotovo u akademskoj zajednici gdje su plagiranja seminara, laboratorijskih vježbi i ostalih aktivnosti postala česta pojava. Za razliku od „normalnog“ teksta, programski kod je specifičan tekst kojim se neka funkcionalnost može napisati na mnoštvo različitih načina, što i detekciju plagijata programskog koda čini kompliciranijom od npr. detekcije plagijata u tekstovima kao što su seminari, članci i sl.
Nije moguće navesti sve moguće metode kojima se program može transformirati u drugi program s istom funkcionalnošću. Ipak, neke uobičajene tehnike transformacije se mogu navesti [2].
Detekciju plagijata moguće je obaviti pomoću većeg broja tehnika [3]. U navedenim potpoglavljima navedene su i objašnjene neke od njih.
U ovoj tehnici dva koda se razmatraju kao dva redoslijeda linija/nizova koji se međusobno uspoređuju kako bi se pronašli nizovi istog teksta. Ako se ustanovi da su dva dijela koda jednaki prema sadržaju i opsegu, označavaju se kao klonovi.
Najčešće se prije analize provodi sljedeća osnovna filtracija koda:
Normalizacija teksta je proces transformacije teksta u standardni oblik odnosno u neku kanonsku formu koju prije nije imao. Primjer tablice normalizacije prikazan je ispod - npr. ako se u izvornom tekstu nalazi tip podatka int, double ili short, nakon normalizacije ti će tipovi biti zamijenjeni s “umjetnim” tipom podatka “num” i sl.
Element | Primjer elementa | Funkcionalna zamjena |
---|---|---|
Tekst | “Abort” | “…” |
Znak | 'y' | '.' |
Broj | 42 | 1 |
Decimalni broj | 0.3141159 | 1.0 |
Identifikator | Counter | p |
Osnovni numerički elementi | int, short, double | num |
Ime funkcije | Main | foo() |
Tablica 1 - Primjer operacija normalizacije nad izvornim kodom
Ova tehnika ima svoje nedostatke budući da analiziramo liniju po liniju koda. Detaljniju usporedbu moguće je dobiti promjenom veličine tokena usporedbe – za analizu se uzimaju manji dijelovi od jedne linije koda. Tako možemo potencijalno otkriti „umjetni“ prekid linije koda na nekom mjestu. Promjena identifikatora također može zavarati ovu tehniku, ali to se nastoji riješiti ranijom normalizacijom koda. Još jedan očit problem je izmjena izjava – npr. ako u izrazu nekog uvjeta zamijenimo redoslijed operanada, neće se detektirati plagijat jer alat misli da je to drugačiji blok naredbi.
Temelj ove tehnike je transformacija izvornog koda u znakovni niz koji se potom uspoređuje s drugim nizovima u namjeri otkrivanja dupliciranih dijelova. Ovakva metoda je za razliku od prijašnje otporna na prekide linija (u znakovnom nizu se mogu predstaviti kao određeni znak, ali mogu se i izostaviti). Na početku analize kod se također normalizira, a nakon transformacije komparacija se radi na temelju sufiksnog stabla temeljenog na dobivenim nizovima.
U ovoj tehnici na temelju izvornog koda stvara se stablo raščlambe koje se često naziva i apstraktnim stablom sintakse. Naziva se apstraktnim jer osnovne jedinice stabla čine apstraktni elementi, dok se određivanje tih elemenata vrši prema sintaksi pojedinog odabranog jezika. Ovo stablo ne sadrži imena varijabli i doslovne vrijednosti elemenata, već apstraktne relacije između naredbi, identifikatora i sl. Time se omogućuje računski povoljna komparacija stabla s drugim podstablima te se lako pronalaze samosličnosti unutar koda.
Ova tehnika nadogradnja je tehnike temeljene na stablima raščlambe. Interpretacijom koda uz pomoć semantičkih pravila pojedini elementi se prikazuju dijagramski čime se dobiva njihov grafikon međuovisnosti, tj. u konačnici vjerni prikaz funkcionalnosti i način rada gotovog programa. Dobiveni GPO izvornog programa bridovima prikazuje sljedove podataka i kontrole nad podacima, a pojedine funkcije i naredbe su prikazane uz pomoć čvorova. Ovisno o složenosti programa, GPO se može sastojati od manjih grafikona zbog bolje preglednosti dijagrama. Prednost ove metode je da se komparacijom GPO-a različitih programa može vidjeti plagiranje programa, uz iznimno veliku osjetljivost na kloniranje neovisno o redoslijedu, izmjeni samog koda ili identifikatora. Glavna mana ove metode je složenost GPO-a koja eksponencijalno raste povećanjem složenosti izvornog koda, što dovodi do računski nepovoljne obrade većim programa.
Tehnika komparacije karakterističnih vrijednosti razlikuje se od prijašnjih jer se ne uspoređuje izvorni kod, već se njegovi pojedini elementi prikazuju pomoću svojih vrijednosti ulaza i izlaza (zbog unikatnosti ih nazivamo “otisci prsta” programa). Kod se često prije analiziranja prevodi kroz ranije spomenuti grafikon programske ovisnosti ili stablo raščlanjivanja kako bi se ulazi i izlazi pojedinog elementa mogli prikazati kao vektori. Ova tehnika nije svojstvena samo za programske kodove, već i za otkrivanje duplikata u računalnim mrežama i sl.
U ovom poglavlju demonstrirat će se neki od popularnih alata za detekciju plagijata u programskom kodu. Za testiranje su napisana tri primjera Python programskog koda koji će se međusobno uspoređivati. Preciznije, prvi primjerak je originalan i pronađen na internetu, dok su preostala dva ručno modificirana.
Prvi programski kod je jednostavan - računa i ispisuje površinu trokuta.
a = 5 b = 6 c = 7 s = (a+b+c)/2 area = (s*(s-a)*(s-b)*(s-c))**0.5 print('The area of the triangle is %0.2f' %area)
Drugi programski kod ima promijenjena imena varijabli uz dodane razmake između operatora.
x = 5 y = 6 z = 7 tmp = (x + y + z) / 2 num = (tmp * (tmp - z) * (tmp - y) * (tmp - x)) ** 0.5 print('The area of the triangle is %0.2f' %num)
Treći programski kod uz različita imena varijabli ima odvojenu funkciju za računanje površine.
def area(i, j, k): temp = (i + j + k) / 2 return (temp * (temp - k) * (temp - j) * (temp - i)) ** 0.5 i = 5 j = 6 k = 7 ar = area(i, j, k) print('The area of the triangle is %0.2f' %ar)
Moss je jedan od najpopularnijih alata za detektiranje plagijata u programskom kodu. Nakon što se obavi registracija slanjem maila s korisničkim imenom, dobijemo automatski generiranu poruku u kojoj se nalazi Perl skripta za pokretanje programa. Moss detektira plagijate u preko 20 programskih jezika. Nakon što pokrenemo Perl skriptu i odaberemo datoteke koje šaljemo za detekciju dobijemo poveznicu na kojoj možemo vidjeti rezultate testiranja. Rezultati detekcije plagijata između prvog i drugog primjera prikazani su na slici ispod.
Iz prikazanog se vidi da je alat cijeli programski kod prepoznao kao plagijat - očito je da mijenjanje imena varijabli i dodavanje beskorisnih razmaka i linija ne čini problem ovom alatu. Pri učitavanju trećeg primjera programskog koda (primjer s izdvojenom funkcijom), alat iz nepoznatog razloga kaže da nema podudaranja s ostalim primjercima što je čudno budući da je ranije između prvog i drugog primjera prepoznao sva podudaranja - moguće je da je riječ o nekoj grešci u alatu. Ipak, uzmemo li u obzir detekciju koju smo ranije proveli, može se reći da alat dobro obavlja svoj posao na manje promjene varijabli tj. pri detekciji ne uzima u obzir samo “čisti” tekst programa.
CopyLeaks je online alat za detekciju sličnosti u programskom kodu. Osim toga, može se koristiti i ostale provjere plagijata kao što su plagijati tekstualnih dokumenata i sl. Omogućena je detekcija plagijata za oko 20 programskih jezika. Osim što se izvorne datoteke mogu međusobno uspoređivati, alat pretražuje svoju internu bazu podataka, web i ostale izvore informacija kako bi provjerio pojavljuje li se objavljeni kod negdje kao javan izvor. Upravo zato je prvi primjer programskog koda ranije naveden prepoznat kao plagijat. Za usporedbu primjera programa međusobno potrebno je pretplatiti se za alat pa to nije provedeno. To je možda i jedini problem ovog alata - u besplatnoj verziji dopušta samo određene funkcionalnosti i nudi ograničen broj skeniranja dnevno. Primjer prepoznatog plagijata u alatovoj internoj bazi podataka prikazan je na slici ispod.
Ovaj alat za provjeru plagijata u programskom kodu napisan je kao Python skripta koju je moguće pokrenuti iz terminala. Nakon što se preuzme izvorni kod, potrebno je instalirati pakete potrebne za njegovo izvršavanje. Skripta je jednostavna za koristiti - u direktorij u kojemu se skripta nalazi potrebno je postaviti tekstualne datoteke s izvornim kodom, a skripta će usporediti sličnosti svakog para datoteka međusobno. Usporedba se radi tako da se svaki tekst pretvori u vektore, nakon čega ih se uspoređuje i računa sličnost dokumenata.
Rezultati uspoređivanja primjera programa je zanimljiva. Program je pronašao veću sličnost između prvog primjera i trećeg primjera, iako bi treći primjer trebalo biti teže detektirati pošto ima i promijenjena imena varijabli i izdvojenu zasebnu funkciju. Rezultati su prikazani na slici ispod.
Uz navedene alate, postoji još mnoštvo detektora plagijata za programski kod. Problem je što se većina tih alata, kao što je Codequity plaćaju jer je većina njih je razvijena kako bi se spriječilo plagiranje programskih kodova u akademskim ustanovama. Ostali alati koji su besplatni većinom su davno razvijeni, ne pružaju moderne metode za detekciju plagijata i nemaju potporu da mnogo programskih jezika.
Većina alata za detekciju plagijata u programskom kodu temelji se na usporedbi tokena i sličnih tekstualnih vrijednosti, a to nam često nije dovoljno. Također, plagiranje se ne provodi samo zbog programerovog neznanja, nego i zbog lošeg upravljanja vremenom - dobar programer sposoban je transformirati neki izvorni kod u potpuno drugačiji tekstualni oblik. Zbog toga se nastoji raditi analiza koda na “nižoj razini” odnosno analiziraju se instrukcije izvršnog koda. Jedan slučaj takve analize za programski jezik Java [4] imao je puno više uspjeha nego analiziranje “čistih” izvornih kodova. Slično, nastoje se raditi analize kojima bi se fragmenti koda karakterizirali pomoću jezgrenih vrijednosti izvršnih datoteka [5]. Još jedna tehnika detekcije plagijata bila bi izdvajanje “biljega” iz izvornog koda koji se potom uspoređuju pomoću kosinusne sličnosti. Za ovakvu detekciju nije potreban izvorni kod, a otporna je i na slabe i na jake tehnike obusfikacije programskog koda [6]. Iz navedenog se vidi da se detektiranje plagijata u programskom kodu sve više orijentira k analizi izvršnih datoteka, što je kompliciranije područje, ali daje više uspjeha.
Plagiranje programskog koda je složena tema koja svakim danom postaje sve složenija. U ovom radu navedene su neke tehnike plagiranja koda kao i tehnike detekcije plagijata te odgovarajući alati za detekciju plagijata, ali tu je zapravo samo zagrebana površina. Čak da imamo “savršen” detektor plagijata, pitanje je možemo li 100% dokazati da je netko nešto plagirao. Kratki programi koji rade jednostavne funkcije (npr. program koji iz polja cijelih brojeva ispisuje pozitivne brojeve) se često pišu na isti način pa nema smisla raditi detekciju plagijata. S druge strane, možda su npr. na nekoj laboratorijskoj vježbi studenti prepisali taj isti jednostavan program, a nisu kažnjeni i dobili su bodove koje ne zaslužuju. U svakom slučaju, uz potrebnu programsku podršku za detekciju plagijata očito je da je potrebna i intervencija čovjeka koji na kraju sam mora odlučiti je li neko programsko rješenje plagijat ili ne.
Rasprave
Što je normalizacija teksta? Navedite alate za detekciju plagiranja programskog koda i napravite njihov krati pregled. Dodajte poveznice na alate. Što se novo radi u ovom području? Pogledajte u IEEEXlore, sažmite ideje novih radova. Dodajte u tekst linkove i reference na izvore gdje se može pronaći više informacija o temama o kojima govorite.