Go Plagiarism Check
func plagiarismCheck(code1, code2 []string) bool {
c1 := strings.Join(code1, " ")
c2 := strings.Join(code2, " ")
if c1 == c2 {
return false
}
wordRe := regexp.MustCompile(`[\w]+`)
numericRe := regexp.MustCompile(`^[0-9]+$`)
d1 := wordRe.FindAllString(c1, -1)
d2 := wordRe.FindAllString(c2, -1)
rCand := make(map[string]string)
var order []string
for k, v := range d1 {
if k >= len(d2) {
break
}
if v != d2[k] && !numericRe.MatchString(v) {
if _, exists := rCand[v]; !exists {
order = append(order, v)
}
rCand[v] = d2[k]
}
}
// Two-pass rename: stash originals behind a placeholder first so that
// swapping two identifiers (e.g. a<->b) doesn't clobber itself, then
// swap the placeholders in for the real replacements.
for _, orig := range order {
re1 := regexp.MustCompile(`(\W)` + regexp.QuoteMeta(orig) + `(\W*)`)
c1 = re1.ReplaceAllString(c1, "${1}PLACEHOLDER"+orig+"$2")
re2 := regexp.MustCompile(`(\W)` + regexp.QuoteMeta(orig))
c1 = re2.ReplaceAllString(c1, "${1}PLACEHOLDER"+orig)
}
for _, orig := range order {
repl := rCand[orig]
re3 := regexp.MustCompile(`(\W)PLACEHOLDER` + regexp.QuoteMeta(orig) + `(\W)`)
c1 = re3.ReplaceAllString(c1, "${1}"+repl+"$2")
re4 := regexp.MustCompile(`(\W)PLACEHOLDER` + regexp.QuoteMeta(orig))
c1 = re4.ReplaceAllString(c1, "${1}"+repl)
}
return c1 == c2
}
This flattens both snippets, tries consistent identifier replacements, and checks whether the rewritten code matches.