尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Online signature verification. Enroll a handwritten signature, then detect forgeries by how it was written, not just how it looks.
Everything runs in the browser: capture, feature extraction, matching and storage. There is no backend and nothing is uploaded.查看完整 README ↗Online signature verification. Enroll a handwritten signature, then detect forgeries by how it was written, not just how it looks.
Live: forgerydetection.vercel.app ·
Everything runs in the browser: capture, feature extraction, matching and storage. There is no backend and nothing is uploaded.
Most signature checkers compare two pictures. That is offline verification, and it is the easy case for a forger: an outline can be traced. AntiForge does online verification. Every pointer sample is recorded with a high-resolution timestamp (and pressure on pens), so the system knows where the pen was, when, and how fast it was moving. A forger who traces a shape produces the right picture at the wrong speed, with the wrong rhythm.
The engine is about 500 lines of dependency-free TypeScript in src/lib/engine. The same code runs in the page and in the benchmark.
SignaturePad records Pointer Events, including coalesced events, with event.timeStamp, pressure and pointer type. A stroke is one pen-down to pen-up segment.preprocess.ts). Each stroke is resampled on a uniform 100 Hz grid, then the whole signature is centred on its centroid and scaled by its RMS radius, so where and how large it was drawn carry no weight. Per-sample velocity, speed and direction are derived by central differences; pressure is normalised per signature. Channels are multiplied by calibrated scales so they are commensurate.dtw.ts). Dynamic Time Warping with a Sakoe-Chiba band around the diagonal of the (non-square) cost matrix, Euclidean local cost, normalised by the sum of the lengths. Three matchers run: all channels, shape only (x, y, dirX, dirY) and dynamics only (vx, vy, speed, pressure), so the decision can tell "right shape, wrong motion" apart.template.ts). Three or more references (five recommended). The template stores the pairwise DTW distances between references under each matcher. That intra-writer spread is the yardstick for everything checked later; an outlying reference is flagged in the UI so the user can redo it.verify.ts). A query's distances to the references are expressed relative to the writer's own spread (ln(d_min / μ), ln(d_mean / μ), a nearest-neighbour ratio, a z-score, the same for each channel group) plus the pen-down time ratio and stroke-count difference. A logistic model fitted on SVC2004 turns these into a probability; the threshold sits at the equal-error point of the fitting set.Results come back with the per-reference distances, the writer's spread, and human-readable factors (shape, motion, pen-down time, stroke count, speed), which the UI shows next to a real-time replay of the attempt and its closest enrolled signature, coloured by pen speed.
Numbers below are produced by pnpm bench against the public SVC2004 corpus and written to bench/results/summary.json. The landing page reads the same file.
Protocol. For each of the 40 writers per task: enroll from genuine samples 1–5; test on genuine samples 6–20 (15 trials), skilled forgeries 21–40 (20 trials, made by people who studied and practised the signature), and one genuine sample from each other writer (39 random forgeries). Task 1 has x, y and time; Task 2 adds pen pressure. All figures use one global threshold for every writer, which is what the app ships. "Per-writer EER" assumes an ideal threshold per writer and is given only because that is how much of the literature reports.
| Skilled-forgery EER | Random-forgery EER | AUC (skilled) | Per-writer EER | |
|---|---|---|---|---|
| Task 1 (x, y, t) | 10.7 % | 2.8 % | 0.958 | 6.5 % |
| Task 2 (+ pressure) | 9.3 % | 1.3 % | 0.972 | 3.0 % |
Held-out generalisation (model fitted on one task's writers, scored on the other's): skilled EER 10.3 % (fit Task 1 → Task 2) and 12.5 % (fit Task 2 → Task 1). The shipped model is fitted on both tasks; the decision threshold is 0.44.
For context, published DTW-based systems on the released SVC2004 set report skilled-forgery EERs of roughly 3–7 % with more elaborate normalisation and user-specific classifiers; simple global-threshold systems typically land in the 8–15 % range. SVC2004 was captured on a tablet, so real-world error rates with a mouse or trackpad will be worse.
Reproduce:
pnpm bench:fetch # downloads Task1.zip / Task2.zip into bench/data (git-ignored)
pnpm bench # evaluates the shipped calibration, rewrites bench/results/
pnpm bench:calibrate # additionally refits feature scales + decision model into src/lib/engine/calibration.json
bench/run.ts also takes --band, --smooth, --drop, --weight, --norm, --features and --lambda for experiments. The constants in calibration.json are generated; do not hand-edit them.
src/lib/engine/ preprocess → dtw → template → verify; calibration.json (generated)
src/app/ Next.js App Router pages: /, /enroll, /verify, /identities
src/components/ SignaturePad (capture), SignatureReplay, VerdictCard, RocChart
src/lib/store.ts IndexedDB persistence (idb-keyval) with JSON export/import
bench/ SVC2004 reader, metrics (ROC/EER/AUC), logistic fit, runner
Stack: Next.js 16 (static export), React 19, TypeScript, Tailwind CSS 4, Vitest. Runtime dependencies are react, next, idb-keyval and lucide-react.
Requires Node.js 20.9+ and pnpm.
git clone https://github.com/davoA07/AntiForge.git
cd AntiForge
pnpm install
pnpm dev # http://localhost:3000
pnpm test # engine + bench unit tests
pnpm build # static export to out/
No environment variables. Deploys to Vercel on push to main.
David Aydenjian — Computer Science student focused on machine learning. GitHub @davoA07 · LinkedIn
Originally prototyped at JCH 4.0; rebuilt from scratch in September 2026.
MIT — see LICENSE. SVC2004 is distributed by HKUST for research use and is not included in this repository.