Plagiarism detector

SherlockScan

SherlockScan is my rebuilt interface for an open-source plagiarism detector. Upload a PDF and the pipeline finds likely sources online, scrapes them and pinpoints the copied sentences.

SherlockScan landing page with Investigate Plagiarism and Upload a PDF buttons

The challenge

Checking a document for plagiarism means comparing it with a lot of text. Doing that phrase by phrase is slow, and a search API alone tells you a page matched, not which sentences were lifted.

I found an open-source detector that solves the matching problem and rebuilt its interface as a product-style site, SherlockScan.

The approach

The engine, from Crypt0knights' MIT-licensed Plagiarism-Detector, is a neat piece of algorithm design. Each word becomes a number, every three-word phrase is hashed seven ways with a rolling hash, and two Bloom filters shrink both texts to phrases they probably share. Only those survivors go through an exact Aho-Corasick match, which removes false positives and stitches the hits back into sentences.

My part was the front end: the SherlockScan name and logo, a full-screen hero with the PDF upload, about and feature sections, a contact section and footer, a responsive layout and ScrollReveal animations.

  • PDF uploadExpress and Multer accept a PDF, and pdf2json turns it into plain text.
  • Source discoveryThe text goes to the Copyleaks API, and the five highest-scoring URLs are scraped for visible text or PDF content.
  • Two-stage filteringRolling hashes and two Bloom filters discard phrases the texts cannot share.
  • Exact matchingAn Aho-Corasick pass confirms matches and reports the copied sentences with a percentage score.

From upload to report

  1. 01UploadPDF to text with pdf2json
  2. 02PrepareNLTK sentence split, punctuation stripped
  3. 03Find sourcesCopyleaks search, top 5 URLs scraped
  4. 04MatchHash, filter, Aho-Corasick, score

Hash, filter, then match.

Seven rolling hashes per three-word phrase feed two Bloom filters, so the exact Aho-Corasick pass only sees phrases both texts probably share.

Diagram of the matching engine: encode, Bloom filter 1, Bloom filter 2, Aho-Corasick

It still finds the copies.

Run locally on a sample essay, the unmodified scripts flagged both sentences copied from the first source and left the original ones alone. The run also showed a bug: shared global state makes every source after the first fail silently.

Terminal output of search.py listing two copied sentences and a 63.6% match

A product-style front end.

Feature cards for PDF, text and URL results and the match score, laid out with Bootstrap and revealed on scroll.

SherlockScan features section with PDF, Text, URL and Sherlock Score cards

Tools

  • Node.js
  • Express
  • Multer
  • Python
  • NLTK
  • BeautifulSoup
  • Bootstrap
  • ScrollReveal

The detection engine and pipeline scripts (search.py, aho.py, bloom_filter.py, scrape.py, checker.sh) come from Crypt0knights' open-source Plagiarism-Detector (MIT); I rebuilt the front end. Screenshots are from a local static build of the August 2022 code. The terminal output is a real local run on sample text, with the paid Copyleaks lookup stubbed out.

Next projectCoursaholicCoursaholic course picker: filtered CS course list with difficulty scores, three selected courses and scheduler options