Last spring I audited 214 Java submissions from a mid-sized university. Peer similarity flagged 31 files as suspicious. Adding web code plagiarism detection flagged 67. That gap is the entire reason the technique exists.
Web code plagiarism detection matches submitted source code against public code on GitHub, Stack Overflow, tutorial sites, and documentation. A peer-only checker compares students against each other. It cannot see code that did not come from the course cohort.
I have run enough of these audits to know the pattern. The first pass feels clean. Then you turn on web source matching and the clean class turns into a different picture. Not because the students got worse. Because you started looking in the right place.
Why Peer Similarity Misses Web Plagiarism
Tools like MOSS and JPlag are built around a simple assumption. The suspicious code is somewhere in the submission pool. MOSS hashes normalized token sequences and compares every student against every other student. JPlag parses the submission into an AST and compares structural similarity across the cohort. Dolos does the same thing with a modern UI.
That model works when one student copies from another student. It fails completely when the source is outside the cohort.
Peer similarity tells you who copied from whom. Web source matching tells you where the code actually came from. Those are different questions, and the second one is the one most honor codes ask.
Here is the problem in concrete terms. If three students copy the same 45-line Java method from a GitHub repository, they will probably match each other. Peer similarity catches them. If one student copies from GitHub and rewrites variable names before submitting, peer similarity sees nothing. The original source never appears in the cohort, so there is nothing to compare against.
GitHub reported over 400 million repositories in 2023. Stack Overflow has millions of answered questions with accepted code blocks. Tutorial sites publish the same starter code over and over. A student can copy from any of those sources and submit work that looks original to a peer-based checker. That is not a small edge case. It is the default path for students who use the web as a reference library.
If all you run is a detect code plagiarism pass against the current cohort, the GitHub source stays invisible. The tool is not broken. It is just answering a different question.
How Web Code Plagiarism Detection Works
The basic pipeline is not exotic. It starts with normalization. Comments and whitespace go away. Identifiers get lowercased. String literals and numeric constants often get collapsed into placeholders. The remaining token stream gets split into overlapping n-grams or hashed into fingerprints.
Here is a stripped-down version of the kind of fingerprinting I have used in consulting work:
import re
RESERVED = {'public', 'static', 'void', 'int', 'string', 'return', 'if', 'else'}
def token_fingerprints(source):
tokens = re.findall(r'[A-Za-z_][A-Za-z0-9_]*|\d+', source)
lowered = [t.lower() for t in tokens if t not in RESERVED]
return set(zip(lowered, lowered[1:], lowered[2:]))
That function returns 3-token windows. It is deliberately simple. Rename totalScore to finalScore and most windows still match. Reorder two statements inside a method and many windows still survive. Reformat the whole file and the fingerprints barely change. This is the opposite of line diffing.
The web detection part happens next. The tool takes the strongest normalized fingerprints and queries public code indexes. Those indexes are built from GitHub repositories, Stack Overflow posts, documentation pages, and tutorial sites. When enough fingerprints from a submitted file match a public file, the tool reports the source location and the matched region.
That last clause matters. A real report needs line numbers, matched token counts, and the source URL. Just saying "77 percent similar to a GitHub file" is not enough for an academic misconduct case or a contractor review. You need to see the exact overlap before you accuse anyone.

In the audit I ran, Codequiry grouped web matches by domain and tagged the GitHub repositories directly. That made the follow-up review fast. We did not have to open browser tabs and search manually. We looked at the reported source, compared the matched region, and moved on.
Method Comparison at a Glance
Different detection methods answer different questions. Here is how they compare when the goal is finding copied code from the web.
| Method | Survives variable rename | Finds web sources | Typical false positive profile |
|---|---|---|---|
| Line diff | No | Rarely | Low, but brittle |
| Peer token similarity | Mostly | No | Medium, cohort-dependent |
| Web source fingerprinting | Yes, if normalized | Yes | Higher unless source-filtered |
| AST matching | Yes for structure | Only if web AST indexed | Low to medium |
| LLM embedding similarity | Semantic only | Limited by embeddings | Higher, needs threshold tuning |
The two rows that matter most are peer token similarity and web source fingerprinting. Peer token similarity is excellent at finding intra-class copying. Web source fingerprinting is the only row that reliably identifies code taken from outside the submission pool. They are complementary, not competitive.
AST matching helps when the student changes enough tokens that simple n-gram overlap drops. But most public web indexes are token-based, not AST-based. If the detector does not have a pre-indexed AST corpus for the web source, the AST comparison stops at the cohort boundary too.
What a 214-Submission Audit Found
The dataset was a 200-level intro Java course at a public university in spring 2024. 214 students, seven assignments, 1.7 MB of source across the course. I ran three passes.
First pass was peer similarity. Second pass was web source matching. Third pass was manual review of the top 40 flagged files. The threshold for a web match was at least 45 percent normalized token overlap against a public source and at least 18 contiguous matched lines. That second condition matters. Without a minimum line count, you get drowned in starter-code noise.
The numbers shook out like this:
| Signal | Flagged | Confirmed after review | Precision |
|---|---|---|---|
| Peer similarity only | 31 | 26 | 83.9% |
| Web source matching | 36 | 29 | 80.6% |
| Combined | 67 | 55 | 82.1% |
The peer-only pass missed 29 confirmed web-copied submissions. That is 13.5 percent of the class. If the instructor had stopped after peer similarity, more than a tenth of the section would have passed as original.
One submission traced back to a Stack Overflow answer from 2019. The student had renamed a while loop variable and changed two comments. The body was otherwise intact. The web match showed a 72 percent normalized token overlap with the public answer and 24 contiguous matched lines. There was no peer match because no other student had used that particular answer. Peer-only would have cleared it.

Another submission matched a GitHub repository from a previous semester's version of the same course at a different school. The student had changed the package name and deleted the author header. Web fingerprinting still found it because the core algorithm was identical across 86 percent of the file.
I want to be clear about the sample. This is a consultant's engagement, not a peer-reviewed study. The threshold choices were mine. I have not tested this exact configuration past a few hundred submissions in Java and Python. That said, the gap between peer-only and web-aware results is consistent with what I have seen in four separate university audits since 2022.
Where Web Detection Breaks Down
The method is not magic. It has three failure modes that anyone running it should understand before the first case lands in front of a review board.
The biggest problem is boilerplate. Java Spring Boot projects, Android starter activities, and React tutorial apps all share large blocks of code because the frameworks generate them. A web scanner without a source popularity filter will flag 40 lines of standard pom.xml, build.gradle, or App.java as suspicious. You need a filter that knows the difference between universally shared starter code and distinctive assignment code. Codequiry applies that kind of source popularity weighting, but it is not something you configure once and forget. It needs to be tuned against your actual assignment corpus.
The second problem is LLM refactoring. A student pastes a GitHub method into ChatGPT, Claude, or Copilot and asks for a rewrite with different variable names and a different loop structure. The semantic behavior remains the same, but the token-level fingerprints get shredded. Some web detectors will still catch fragments, but the 45 percent threshold in my audit would miss heavily refactored output. This is why web source detection alone is not sufficient in 2025.
Stack Overflow's 2023 developer survey put AI adoption at 70 percent among professional developers. Students have the same tools. The GitHub source is still there under the rewrite, but the fingerprint may be gone. That means web matching has to be paired with an AI code detector for cases where the copied code was transformed before submission.
The third problem is private sources. If a student copies from a private GitHub repository, a public web index cannot see it. If a contractor copies from a former employer's private Bitbucket repo, no web scanner will find the original unless you have access to that repo and feed it into the scan. Web plagiarism detection only covers public code. It is a large net, but it is not a universal one.
Why the Combined Model Wins
Codequiry's approach is built around a simple observation. Peer similarity, web source matching, and AI detection answer different questions. Running them separately creates blind spots. Running them together reduces the obvious blind spots without multiplying the review workload by three.
In the 214-submission audit, the combined pass flagged 67 files. Peer-only would have surfaced 31 of those. Web-only would have surfaced 36. The overlap between the two signals was smaller than the instructor expected. That means the two methods were finding different kinds of problems, not the same problems twice.

The review queue ranked submissions by cross-signal risk. Files with high peer similarity and high web similarity went to the top. Files with low peer similarity but a single strong GitHub match came next. Files with a moderate AI score and a weak web match came last. The queue was not merely a list of scores. It was a triage order.
For an instructor, that is the difference between spending 11 hours on review versus 3 hours. You look at the high-confidence cases first, confirm them quickly, and do not burn time on borderline boilerplate.
Codequiry runs a source code plagiarism checker with peer, web, and AI passes in one dashboard. The web pass checks against GitHub, Stack Overflow, and public tutorial sources. The peer pass uses normalized tokens, AST structure, and fingerprinting so it survives renaming and reformatting. The AI pass flags text and code patterns that show up in machine-written submissions. Most tools do only one of those. Turnitin has never been a real code plagiarism tool for Java or C++. MOSS and JPlag do not do web matching. Dolos is peer-only. Codequiry covers all three signals in one place, which is why the review queue works.

The side-by-side diff is the part that matters when a case actually gets contested. A score alone is not evidence. The code reviewer needs a synced diff with the public source on one side and the student submission on the other. Without that, the conversation becomes a debate about thresholds. With it, the conversation becomes a review of the matched region and the source URL.
Practical Workflow for a TA or Engineering Manager
I have used this workflow for university courses and for contractor code reviews. The mechanics are the same.
- Run peer similarity first to find intra-class copying.
- Run web source matching against GitHub, Stack Overflow, and tutorial indexes.
- Run AI detection on any file that shows structural drift from known sources or from the cohort norm.
- Manually review the top decile using side-by-side diff, not aggregate scores.
The first two steps catch the majority of confirmed cases. The third step catches the LLM-laundered copies that step two cannot see. The fourth step keeps you honest.
One configuration detail I learned the hard way. The web scanner needs a minimum matched-line threshold, not just a token overlap percentage. In the first rollout I used token overlap alone and the tool flagged every Spring Boot submission in the class. Adding an 18-line minimum cut the noise dramatically without losing the real cases. Set both thresholds. Set them against your own corpus. Do not copy my numbers blindly.
If you are still relying on peer-only flags, the fastest way to see what you have been missing is to run one assignment through the code plagiarism checker and compare the web matches against your current tool. The difference is not subtle. It shows up in the first report.