The earliest folders in the archive were plain text files produced by a script called sim_c, one of the University of Missouri-St. Louis computer science department's local tools from 2004. Each row held two student IDs and a single number: the percentage of matching lines. Maya Lindqvist, a senior instructor who has taught CS 225 since 2010, pulled a 2006 report while preparing a department seminar. Two students in an assembly language course had a 94% line match on a linked-list traversal. The report gave no context, no snippet, no web source, and no indication of which lines were original.
The evolution of code similarity detection in this department is a move from after-the-fact line matching to token fingerprints, abstract syntax tree comparisons, web-source checks, and AI-aware scoring. Each stage caught cases the previous stage missed, and each stage created new blind spots.
Starting With Diff and the First Token Fingerprints
Before dedicated similarity checkers became common, many departments ran a modified Unix diff on normalized source files. Normalization removed comments and whitespace. Identifiers remained untouched, so a student who renamed loop counters from i to iter could drop the match below the department's 70% threshold. The first automated detectors in the 1980s used attribute counting, counting operators, operands, and Halstead metrics, but those were easy to game with variable names and comments.
By 2004, the Missouri-St. Louis team had shifted to a token fingerprint script that hashed five-token sliding windows and compared sets. The script is reproduced here because it is a clear ancestor of modern fingerprinting.
# 2004-era token n-gram fingerprinting for a Java assignment
import re, hashlib
def token_fingerprint(path, k=5):
tokens = re.findall(r'[A-Za-z_][A-Za-z0-9_]*|\d+|.', open(path).read())
# normalize identifiers to a fixed bucket before hashing
normalized = ['ID' if tok.isidentifier() else tok for tok in tokens]
return {hashlib.md5(''.join(normalized[i:i+k]).encode()).hexdigest()
for i in range(len(normalized)-k+1)}
Alex Aiken's MOSS, a web service at Stanford, had already popularized the same broad idea with more careful winnowing. The 2003 Winnowing paper by Schleimer, Wilkerson, and Aiken showed how to select a subset of hashes that preserved match boundaries without storing every n-gram. MOSS did not require a local install, which mattered in a department with one shared Sun workstation. Lindqvist remembers submitting batches of 400 Java files at 2 a.m. because the service slowed during west-coast business hours.
The token approach was not perfect. Two students who both copied the textbook's code structure could trigger an 80% match without copying each other. The department's academic integrity committee learned to treat high MOSS percentages as a lead, not a verdict.
AST Comparison Made Surface Renaming Less Useful
JPlag appeared from German universities in the late 1990s and took a different path. It parsed programs into abstract syntax trees before comparing them. That shift mattered because ASTs ignored identifier names entirely. A student who renamed every variable and reordered independent functions still left the same tree shape.
"We started using JPlag for every CS 225 section in 2012. The first semester, we flagged 38 pairs. When we investigated, 31 had shared structure but different variable names and reformatted indentation. The old line diff would have caught maybe six."
AST comparison compares the structure of loops, conditionals, and calls, not layout. A student who changes comments, whitespace, variable names, and even function order will often leave the same nested loop and conditional shape. This was the beginning of refactoring-resistant detection, an approach that later became standard in tools such as Codequiry's source code plagiarism checker.
The limitation was different this time. AST matching could flag students who independently followed the same template. In a 2014 data structures course, 14 of 22 flagged pairs came from students who had all attended the same lab and copied the same starter structure. The tool could not tell shared instruction from shared cheating.

The Web Source Problem Arrived With Stack Overflow
By 2015, the department noticed that pairs flagged by JPlag were sometimes both copied from a public GitHub repository or a Stack Overflow answer. Peer matching found the two students, but it could not identify where the original came from. That was a new class of plagiarism: web-source copying, not collusion.
In 2018, a teaching assistant forgot to enable the web-source checking flag in the department's custom wrapper. A batch of 19 submissions in CS 225 came back with low peer similarity because no two students copied the same GitHub repository. They had each found different public solutions. The omission went unnoticed until an instructor recognized a piece of code from a popular YouTube tutorial during office hours.
Web-source checks changed the workflow. The department began running a separate online-origin scan for every submission that had a JPlag match below 50% but still looked suspicious. The two-step process worked, but it produced three reports per assignment: one for peer matches, one for web matches, and one for source structure. Faculty assembled the story by hand.
Codequiry folded peer, web, and structure matching into a single workflow. Its code plagiarism checker traces submissions to GitHub repositories, Stack Overflow questions, and other public sources while still comparing against the cohort. For a department that had spent years juggling separate exports, that consolidation removed a real operational bottleneck.

AI-Generated Code Entered the Queue
In fall 2023, the department ran its first AI detector on two CS 225 sections using Codequiry's AI detection alongside its existing peer and web checks. The report flagged 17% of 411 submissions as AI-assisted or fully AI-generated. Lindqvist reviewed the top 20 manually. Eight contained comments that explained the code in a way students rarely write. Six used a repetitive error-handling pattern that repeated across unrelated assignments.
"The AI detector did not prove anything by itself. It gave us a short list. The old peer check gave the same students a low similarity score because they had not worked together. The combined report was the first time we could see three different signals at once."
She is careful about the tool's limits. The department has not validated its AI detection beyond a few hundred submissions, and borderline cases still require manual review. A high AI score can reflect boilerplate, IDE autocomplete, or an assignment with very common structure. The AI code detector became a triage instrument rather than a source of proof.

What the Department Changed in Its Workflow
The department still runs MOSS for final checks in capstone courses, because its match percentage is familiar to the academic integrity committee. JPlag remains the tool of choice for Java and C# assignments where AST structure matters. The shift to Codequiry happened because the committee wanted peer, web, and AI signals in one report rather than three separate exports. The API also allowed the department's custom grading scripts to submit batches without a browser.
A 2012-era config flag became the single most common reason a scan returned incomplete results across three sections. Every check now defaults to enabling peer, web, and AI scores. In 2024, the flag was still not exposed in the department's older grading wrapper, so new teaching assistants kept disabling it by accident until a one-line patch renamed the option from run_optional_checks to run_all_checks.

The evolving toolstack also changed assignment design. Faculty removed single-path assignments that produced identical structures. They added design documents, in-lab code walks, and git commit histories as supporting evidence. A code walk, Lindqvist notes, catches more than any similarity score: a student who cannot explain a function they submitted has already answered the question.
Where the Evidence Is Genuinely Mixed
No detector can prove intent. Two students may share structure because they both followed a template. A high AI score can reflect boilerplate or an IDE autocomplete rather than a language model. The university's academic integrity committee now treats tool output as a triage signal, not evidence. A flagged submission triggers a manual review against assignment logs, timestamps, git history, and a short oral code walk.
In 2024, 12 of 24 AI-flagged submissions were exonerated after review. Eleven resulted in meetings. One was withdrawn by the student before the meeting. The numbers are small, and Lindqvist does not generalize from them. She does argue that a single signal was never enough.
The same layered logic applies to enterprise code review. A contractor's code may not match any peer submission, but web and AI checks can show it originated from a public repository with a conflicting license. The question is no longer just "who copied whom" but "where did this code actually come from."
Departments and engineering teams that want peer, web, and AI signals in one workflow can test Codequiry's code plagiarism checker on a small batch of submissions before the next academic term or release cycle.