Three Ways to Hide a Comment in a Markdown Note, and Where Each One Shows Up Anyway
No way of writing a comment in Markdown is hidden everywhere. The same private line — <!-- private: call Sam about the raise --> — was removed by GitHub, published in the page source by Hugo with one setting switched on, and printed on the page as text by markdown-it's defaults. The renderer decides, not the syntax.
The question is old and still busy. Stack Overflow's "Comments in Markdown" was asked in January 2011 and had about 1.4 million views, a score of 2,346 and 26 answers when we read it on 2026-10-26.1 The answers list three ways to hide a line — and rarely say where each one leaks.
That gap matters for notes more than for documentation. A private aside typed into a note is safe while the note stays in the editor that hides it. Then the note gets published as a web page, pushed to a repository, exported to Word, or opened in a different app — and each of those reads the file with its own rules.
So we measured it. On 2026-10-26 we ran three comment syntaxes through ten Markdown tools in 15 settings, with pinned versions and a script short enough to print below. The result is a table, the spec reason behind each cell, and a short check to run before a note leaves your hands.
Where does a hidden comment in a Markdown note end up?
It ends up wherever the tool that reads the file puts it. A private aside can be removed from the output, kept in the page's HTML source where anyone can read it with View Source, printed on the page as text, or deleted from the file by a converter. Which one happens depends on the tool and one setting.
Take a grocery note with one private line in the middle:
Buy bread.
<!-- private: call Sam about the raise -->
Buy milk.
In an editor that hides comments, you see two lines — the view you checked. The file still holds three.
Four outcomes are possible once another tool reads it. The table later in this piece uses these letters:
- X — removed. The output has no trace of the line.
- H — in the HTML source. Invisible on the page, readable by anyone who opens View Source or saves the page.
- T — printed as text. The private line appears on the page, word for word.
- D — deleted from the file. A converter rewrites the note and the line is gone from the Markdown itself.
Only X is what most people mean by "hidden." H is the quiet one — the page looks clean, so nobody checks the source.
MITRE's weakness catalogue has an entry for this pattern in web code — CWE-615, "Inclusion of Sensitive Information in Source Code Comments" — and notes that "some programmers tend to leave important data, such as: filenames related to the web application, old links or links which were not meant to be browsed by users, old code fragments, etc."2 A note published as a page inherits the same exposure.
Why doesn't Markdown have a real comment syntax?
Markdown never defined one. John Gruber's original syntax handed everything it did not cover to HTML, so the HTML comment became the default answer. Two workarounds followed: a link definition that points nowhere, popularised on Stack Overflow in 2014, and Obsidian's %% markers, which Obsidian defines for itself.
Gruber's rule is one sentence: "For any markup that is not covered by Markdown’s syntax, you simply use HTML itself."3 A comment is not covered — so <!-- --> is the literal reading of that rule. It works on screen almost everywhere. Its weakness is that it is HTML — and HTML is exactly what a publishing tool is built to pass along.
The second way came from users who wanted a comment that did not reach the output at all. The accepted answer on the Stack Overflow thread, by a user named Magnus, put it plainly: "If you want a comment that is strictly for yourself (readers of the converted document should not be able to see it, even with 'view source') you could (ab)use the link labels (for use with reference style links) that are available in the core Markdown specification."4
That answer has a score of 2,398. The trick looks like this:
[//]: # (private: call Sam about the raise)
It defines a link label called // that points at #, with the comment stored as the link's title. Nothing in the note ever uses the label, so a conforming parser has nothing to draw.
The third way is local to one app. Obsidian's help page says: "You can add comments by wrapping text with %%. Comments are only visible in Editing view."5 It is the tidiest of the three to type — and the only one with no meaning in the Markdown spec.
Why "use an HTML comment" is only half an answer
On 2026-10-08 Obsidian's help page gained a practical sentence: "The %% syntax is specific to Obsidian. To hide text in other apps, use an HTML comment, <!-- -->."56 It is sound advice for what most people want — a line that does not show on screen. It covers less ground than it appears to.
The advice holds for the screen in most of the tools we tried. Of the 13 settings in our table that produce a page or a document, 11 kept the HTML comment off the visible page — either by removing it or by passing it into the source. That is a fair basis for a one-line tip in a help article.
Two gaps sit outside that line.
The first is the page source: a renderer that passes HTML through keeps the full text of the comment in the published page. The second is that some parsers do not pass HTML at all. They print it. markdown-it, the JavaScript library Eleventy builds on, turns the comment into visible text with its default settings, and so does micromark.
Obsidian's same update adds a warning worth keeping: "If you start a block comment and never close it, Reading view hides the rest of the note."5 That sentence is about Obsidian's own view, which we did not test. It is still a good reminder that a comment marker is a parser instruction, and a parser follows it literally.
None of this is a fault in the advice. A help page answers the common case in a sentence. This piece is the long version of that sentence, with each exception named.
How a Markdown parser decides what to do with each comment
A parser classifies each line before anything is drawn. Under the CommonMark specification, a line beginning <!-- starts a raw HTML block, [//]: # (…) is a link reference definition that produces no output, and %% … %% is an ordinary paragraph. A second step — the HTML renderer and its safety settings — decides what raw HTML becomes.
The spec's words for the first case are direct: "An HTML block is a group of lines that is treated as raw HTML (and will not be escaped in HTML output)."7 A line that begins with <!-- is the spec's type 2 HTML block, which runs until a line containing -->. So by the spec, the comment goes into the HTML untouched — outcome H.
The second case is defined by absence. "A link reference definition does not correspond to a structural element of a document."8 It only feeds labels to links elsewhere. A definition no link uses leaves nothing behind, which is outcome X — as long as the parser recognises it as a definition.
The third case is simpler still — %% appears nowhere in the spec, so a line wrapped in it is a paragraph of text. Outcome T, in every tool that does not know Obsidian's convention.
line in the note what the parser sees what the HTML step can do
<!-- private --> -> raw HTML block (type 2) -> pass it into the source,
strip it, or escape it as text
[//]: # (private) -> link reference definition -> nothing to output
%% private %% -> ordinary paragraph -> print it like any text
The variation lives in the right-hand column.
Many renderers add a switch on top of the spec, because raw HTML in user content is a security risk. markdown-it's safety guide is explicit about its choice: "Don't enable HTML." It goes on: "We think it's the best choice and use it by default."9 With HTML off, markdown-it does not drop the comment. It escapes it, so the page shows <!-- private: call Sam about the raise --> as readable text.
Our earlier piece on Markdown edge cases that break editors first showed markdown-it escaping a <div> under the same default. This piece adds what that default does to a comment — it prints the private line.
How we tested: the note and the script
We wrote one note with all three syntaxes, plus variants, and rendered it with nine JavaScript configurations, two Python ones, GitHub's renderer, Hugo with two settings, pandoc and Prettier. Every library version is pinned below. The core comparison is a short Node script anyone can rerun.
The test note — the same "Buy bread / Buy milk" frame, with each private line in its own block:
Buy bread.
<!-- private: call Sam about the raise -->
[//]: # (private: call Sam about the raise)
%% private: call Sam about the raise %%
Buy milk.
The JavaScript side runs the note through each library and prints the HTML. Versions on 2026-10-26: markdown-it 14.3.3 (and 15.0.3, the current major), marked 18.1.1, micromark 4.0.3, commonmark.js 0.31.2 and showdown 2.1.0.
// compare.mjs: npm i markdown-it marked micromark commonmark showdown
import MarkdownIt from 'markdown-it';
import { marked } from 'marked';
import { micromark } from 'micromark';
import * as commonmark from 'commonmark';
import showdown from 'showdown';
import fs from 'node:fs';
const note = fs.readFileSync(process.argv[2], 'utf8');
const cm = (opts) => (s) =>
new commonmark.HtmlRenderer(opts).render(new commonmark.Parser().parse(s));
const renderers = {
'markdown-it (default)': (s) => new MarkdownIt().render(s),
'markdown-it (html: true)': (s) => new MarkdownIt({ html: true }).render(s),
'marked (default)': (s) => marked.parse(s),
'micromark (default)': (s) => micromark(s),
'commonmark.js (default)': cm({}),
'commonmark.js (safe: true)': cm({ safe: true }),
'showdown (default)': (s) => new showdown.Converter().makeHtml(s),
};
for (const [name, render] of Object.entries(renderers)) {
console.log(`--- ${name}\n${render(note)}`);
}
Run it with node compare.mjs note.md. The markdown-it default prints <p><!-- private: call Sam about the raise --></p>; commonmark.js prints <!-- private: call Sam about the raise --> between the paragraphs; showdown prints the [//]: # line as a paragraph.
The other rows used each tool's own entry point. In Python, markdown-it-py 3.0.0 with its default and commonmark presets. For GitHub, the public POST /markdown endpoint in gfm mode. For Hugo 0.168.0, a one-page site built twice — once with defaults, once with this setting:
[markup.goldmark.renderer]
unsafe = true
For pandoc 3.12.1, conversions to HTML, back to Markdown, and to Word. The round trip that matters is one line:
pandoc -f gfm -t gfm note.md
Prettier 3.9.10 formatted the same note with --parser markdown. Each run used a fresh copy of the note, and the outputs were saved verbatim.10
Results: what 15 settings did with each comment
The HTML comment had three different outcomes: removed, kept in page source, or printed as text. The link-reference comment, written correctly, was removed by every HTML renderer except showdown, and pandoc deleted it from the file on a round trip. Obsidian's %% was printed as visible text by every renderer and export outside Obsidian.
X = removed · H = in page HTML source, invisible on screen · T = printed as visible text · D = deleted from the output file
| Tool and setting (tested 2026-10-26) | <!-- … --> | [//]: # (…) | %% … %% |
|---|---|---|---|
| commonmark.js 0.31.2, default (the reference implementation) | H | X | T |
commonmark.js, safe: true | X | X | T |
markdown-it 14.3.3 and 15.0.3, default (html: false) | T | X | T |
markdown-it, html: true or commonmark preset | H | X | T |
markdown-it-py 3.0.0, default and commonmark | H | X | T |
| micromark 4.0.3, default | T | X | T |
| marked 18.1.1, default | H | X | T |
| showdown 2.1.0, default | H | T | T |
GitHub POST /markdown, gfm mode | X | X | T |
| Hugo 0.168.0, default | X | X | T |
Hugo 0.168.0, unsafe = true | H | X | T |
| pandoc 3.12.1, to HTML | H | X | T |
| pandoc 3.12.1, Markdown to Markdown | kept | D | kept |
| pandoc 3.12.1, to Word (.docx) | X | X | T |
| Prettier 3.9.10, format | kept | kept | kept |
commonmark.js in safe mode does not leave the text: it writes <!-- raw HTML omitted --> in its place. The Prettier row is a formatter, not a renderer, so "kept" there means the line is unchanged in the file — it rewrote the link-reference title from parentheses to double quotes, which is still a valid definition.
Four patterns stand out.
The HTML comment is a setting, not a syntax. Hugo shows it most clearly. With its default, the comment never reaches the built page. With unsafe = true, the full text sits in the HTML. Hugo's documentation describes that switch as "Whether to render raw HTML mixed within Markdown. This is unsafe unless the content is under your control. Default is false."11 Sites turn it on to allow inline HTML — and comments ride along.
Defaults point in opposite directions. markdown-it's default prints the comment as text. Eleventy, which uses markdown-it under the hood, flips that default; its documentation lists "html: true (markdown-it default is false)".12 Two sites built on the same library can do opposite things with the same note.
GitHub hides it from one view. GitHub's documentation says: "You can tell GitHub to hide content from the rendered Markdown by placing the content in an HTML comment."13 Its rendering pipeline sanitises the HTML, "aggressively removing things that could harm you and your kin."14 Our test confirmed the rendered output had no comment. The words "rendered Markdown" carry the weight — the .md file, its raw view, and its history still contain the line.
%% is visible outside Obsidian. It printed as text in all 14 Markdown-to-HTML configurations we ran, in pandoc's HTML output, and inside the Word document pandoc produced. If you publish or share a note from outside Obsidian, every %% comment in it is on the page.
Why the link-reference comment is fragile
The [//]: # form only works when a parser accepts it as a link reference definition, and three small writing habits stop that. In all 12 renderer configurations we ran on the full set of variants, the private text was printed on the page when the line had no blank line above it or had nested parentheses.
Here are the three failures, each with the spec reason.
1. No blank line above it. Written directly under a paragraph line, it joins the paragraph:
Buy bread.
[//]: # (private: call Sam about the raise)
The spec is one sentence: "A link reference definition cannot interrupt a paragraph."15 Every configuration — 12 of 12 — printed the private line as part of "Buy bread." GitHub even added a line break before it.
2. Unescaped parentheses inside the comment. A natural aside like (private: call Sam (urgent)) breaks the title. The spec allows a parenthesised title to contain "a ( or ) character only if it is backslash-escaped."16 With the inner pair unescaped, the line is no longer a definition. Twelve of 12 printed it.
3. A blank line inside the comment. A two-paragraph aside ends the definition at the blank line. Eleven of 12 printed both halves; marked was the only one that swallowed it.
The fix for all three is mechanical. Put a blank line above the comment, keep it on one line, and wrap the text in double quotes instead of parentheses: [//]: # "private: call Sam (urgent)". All six renderers we retested on the writing day — the four JavaScript libraries, markdown-it-py and GitHub — accepted that form. Escaping the inner parentheses as \( and \) satisfies the spec, but marked 18.1.1 still printed it.
Then there is showdown — it does not recognise the trick even when it is written correctly. showdown 2.1.0 printed [//]: # (private: call Sam about the raise) as a paragraph, and printed the [comment]: <> (…) variant too.
One correction to an old caveat. A 2015 answer in the same Stack Overflow thread said CommonMark handled only the # form, not the <> form.17 In 2026 every configuration that supports the trick — commonmark.js included — consumed [comment]: <> (private note) cleanly. The blank-line rule from that answer still holds.
What happens to comments when you export or reformat a note
Converters treat comments differently from renderers. pandoc 3.12.1 kept HTML comments and %% lines when it rewrote a note as Markdown, but deleted the [//]: # line from the output file. Prettier kept all three. Exported to Word, pandoc dropped both standard comment forms and printed %% into the document.
The deletion is the result that surprised us most. The link-reference form is the most "hidden" of the three in an HTML page — it produces nothing. That same property is why it disappears: pandoc rebuilds the note from its parsed structure, and a definition no link uses leaves nothing to write back. Run pandoc -f gfm -t gfm on the test note and the output reads:
Buy bread.
<!-- private: call Sam about the raise -->
%% private: call Sam about the raise %%
Buy milk.
The note-to-self is gone.
It is gone without a warning, from the Markdown, after a conversion most people would describe as "no change." The same happened with pandoc's own Markdown and CommonMark writers. Prettier, by contrast, preserved the line, so the loss belongs to pandoc's Markdown writers in our test — not to every formatter.
The Word export ran the other way. Both standard comment forms were absent from the document's XML, which is outcome X. The %% line was printed into the document as a paragraph — so a note shared as a .docx carries every Obsidian-style comment in plain sight.
Two exports we did not test deserve a flag. Google Docs can now open Markdown files directly, and our piece on what Google Docs rewrites in your Markdown found that its documentation does not specifically address HTML comments.
Jekyll's default converter, kramdown, documents its own comment extension — {::comment} … {:/comment}, described as "Treat the body text as a comment which does not show in the output."18 We did not run kramdown, so we make no claim about how it handles the other forms.
Trade-offs and what this test does not show
This is one day's measurement of named versions, not a permanent law. Defaults change between releases, Obsidian itself was documented rather than run, and a hidden-on-screen line was always readable to anyone with the file. The table answers "what does this tool do with this setting"; it cannot answer "is my note private."
Obsidian was not tested. Its behaviour in the table is what its help page documents. We did not measure how Obsidian handles [//]: #, or what a page published from Obsidian contains.
Versions drift. Each row names a version — the next release may differ. markdown-it's html: false default held across 14.3.3 and 15.0.3. That is evidence of a stable choice, not a promise.
Some forms were not covered. Template-level comments, such as Liquid's {% comment %} in Jekyll, sit outside Markdown and outside this test.
The file is the file. Every outcome in the table is about one view of the note. The Markdown source holds the comment in all of them except pandoc's round trip.
Public files get read. A 2019 NDSS study of public GitHub code was about API keys rather than comments, but its finding sets the scale: "We find that not only is secret leakage pervasive — affecting over 100,000 repositories— but that thousands of new, unique secrets are leaked every day."19
This is an old pattern. In 2004, Simon Byers mined published documents for hidden text and concluded that "user behavior - in combination with default program settings - creates an uncomfortable state of affairs for Microsoft Word users concerned about information security."20 Swap Word for a static site generator and the sentence still fits — hidden on screen is not the same as removed from the file.
An AI assistant with access to the note reads the comment whether or not any view shows it — that half has its own piece, your own notes can carry a prompt injection.
How to check a note for hidden comments before you publish it
Search the note for all three comment forms before it leaves your hands, then decide line by line. If something is private, move it to a note you will not publish. If it must stay in the file, assume every tool that reads the file can read it. A single grep finds all three forms.
The search, tested on a scratch folder that also held an ordinary link definition and a "50% off" line, neither of which it flagged:
grep -rnE '<!--|^\[[^]]*\]: *(#|<>)|%%' notes/
It reports the file, the line number and the line for every HTML comment, every [label]: # or [label]: <> comment, and every %% marker. Point it at the folder you are about to publish — not your whole archive.
Then work through what it finds:
- Private content: move it to a separate note that stays out of the publish folder. Deleting the line is the only outcome every tool agrees on.
- Notes to yourself you want to keep: prefer
<!-- -->only if you know your publisher's setting — removed on GitHub and in Hugo's default, published in source underunsafe = trueor Eleventy's default, printed as text in markdown-it's default. - Link-reference comments: check for a blank line above each one and for inner parentheses, and do not run the note through pandoc's Markdown writer if you want them kept.
%%comments: treat them as visible outside Obsidian. Plugin data stored in%%blocks behaves the same way, as our piece on plugin syntax that outlives the plugin found with Kanban's settings block.
If you publish notes as a site, the setting to check is your generator's raw-HTML option; publishing your notes as a static site covers the setup itself.
If the search finds nothing, you are done. The check takes seconds — and it replaces an assumption with a list.
Frequently Asked Questions
How do I write a comment in Markdown?
Markdown has no official comment syntax. The common choices are an HTML comment, <!-- note -->; a link reference definition, [//]: # (note), on its own line after a blank line; and Obsidian's %% note %%. None is hidden in every tool. Which one stays hidden depends on the renderer and its settings.78
Are HTML comments visible in Markdown?
On screen, usually not. In page source, often yes. commonmark.js, marked, showdown and markdown-it-py pass the comment into the HTML, where View Source shows it. markdown-it's JavaScript default and micromark's default print it as visible text. GitHub and Hugo's default remove it. Tested 2026-10-26.910
Does GitHub show HTML comments in Markdown files?
Not in the rendered view. GitHub's documentation says an HTML comment hides content "from the rendered Markdown," and its renderer removed both block and inline comments in our test. The .md file, its raw view and its commit history still contain the text, so a comment in a public repository is public.13
How do I comment out content in Hugo?
An HTML comment works with Hugo's default settings: Hugo 0.168.0 removed it from the built page. If your site sets [markup.goldmark.renderer] unsafe = true to allow inline HTML, the comment is published in the page source. The link-reference form [//]: # (…) produced nothing in both modes.11
Does the Obsidian %% comment work in other apps?
No. Obsidian's help page says the %% syntax "is specific to Obsidian." Every renderer and export we tried printed %% … %% as ordinary text: all 14 Markdown-to-HTML configurations, pandoc's HTML output, and a Word document exported with pandoc. Obsidian recommends an HTML comment for other apps.5
Which Markdown comment is ignored by HTML converters?
The link reference definition, [//]: # (comment), produced no output in every HTML renderer we tried except showdown. It needs a blank line above it and no blank line inside, and it is safest with the text in double quotes rather than parentheses. pandoc's Markdown-to-Markdown conversion deleted it from the file entirely.815
A comment marker is a request to one reader of the file. Every other reader decides for itself.
Hidden is a property of a view, never of the file.
MNMNOTE keeps your notes as open Markdown on your own device, so every line you wrote stays plain text you can inspect. mnmnote.com
References
Footnotes
-
Stack Overflow, "Comments in Markdown," question 4823468, asked 2011-01-28; view count, score and answer count read via the Stack Exchange API on 2026-10-26. https://stackoverflow.com/questions/4823468/comments-in-markdown ↩
-
MITRE, CWE-615, "Inclusion of Sensitive Information in Source Code Comments," Common Weakness Enumeration (last updated April 30, 2026). Accessed 2026-10-26. https://cwe.mitre.org/data/definitions/615.html ↩
-
Gruber, J., "Markdown: Syntax," section "Inline HTML," Daring Fireball. Accessed 2026-10-26. https://daringfireball.net/projects/markdown/syntax ↩
-
Magnus, accepted answer to "Comments in Markdown," Stack Overflow, 2014-01-02. Accessed 2026-10-26. https://stackoverflow.com/a/20885980 ↩
-
Obsidian Help, "Basic formatting syntax," section "Comments." Accessed 2026-10-26. https://raw.githubusercontent.com/obsidianmd/obsidian-help/master/en/Editing%20and%20formatting/Basic%20formatting%20syntax.md ↩ ↩2 ↩3 ↩4
-
obsidianmd/obsidian-help, commit 0540159c71, "Comments syntax (#1142)," GitHub, 2026-10-08. Accessed 2026-10-26. https://github.com/obsidianmd/obsidian-help/commit/0540159c71 ↩
-
MacFarlane, J., CommonMark Spec 0.31.2, §4.6 "HTML blocks," 2024-01-28. Accessed 2026-10-26. https://spec.commonmark.org/0.31.2/#html-blocks ↩ ↩2
-
MacFarlane, J., CommonMark Spec 0.31.2, §4.7 "Link reference definitions," 2024-01-28. Accessed 2026-10-26. https://spec.commonmark.org/0.31.2/#link-reference-definitions ↩ ↩2 ↩3
-
markdown-it, "Safety,"
docs/safety.md, GitHub. Accessed 2026-10-26. https://github.com/markdown-it/markdown-it/blob/master/docs/safety.md ↩ ↩2 -
MNMNOTE, comment-rendering test run, 2026-10-26: markdown-it 14.3.3 and 15.0.3, marked 18.1.1, micromark 4.0.3, commonmark.js 0.31.2, showdown 2.1.0, markdown-it-py 3.0.0, GitHub
POST /markdown(gfm), Hugo 0.168.0, pandoc 3.12.1, Prettier 3.9.10. The test note and comparison script are reproduced in this post. Release pages: https://github.com/gohugoio/hugo/releases/tag/v0.168.0 · https://github.com/jgm/pandoc/releases/tag/3.12.1 · https://github.com/prettier/prettier/releases/tag/3.9.10 ↩ ↩2 -
Hugo documentation, "Configure markup,"
renderer.unsafe(last updated October 10, 2026). Accessed 2026-10-26. https://gohugo.io/configuration/markup/ ↩ ↩2 -
Eleventy documentation, "Markdown," Markdown Options. Accessed 2026-10-26. https://www.11ty.dev/docs/languages/markdown/ ↩
-
GitHub Docs, "Basic writing and formatting syntax," section "Hiding content with comments." Accessed 2026-10-26. https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax ↩ ↩2
-
github/markup, README, GitHub. Accessed 2026-10-26. https://github.com/github/markup/blob/master/README.md ↩
-
MacFarlane, J., CommonMark Spec 0.31.2, §4.7 "Link reference definitions" (paragraph-interruption rule). Accessed 2026-10-26. https://spec.commonmark.org/0.31.2/#link-reference-definitions ↩ ↩2
-
MacFarlane, J., CommonMark Spec 0.31.2, §6.3, "link title." Accessed 2026-10-26. https://spec.commonmark.org/0.31.2/#link-title ↩
-
Volynkin, N., answer to "Comments in Markdown," Stack Overflow, 2015-08-24. Accessed 2026-10-26. https://stackoverflow.com/a/32190021 ↩
-
kramdown documentation, "Syntax," section "Extensions." Accessed 2026-10-26. https://kramdown.gettalong.org/syntax.html ↩
-
Meli, M., McNiece, M. R. & Reaves, B., "How Bad Can It Git? Characterizing Secret Leakage in Public GitHub Repositories," NDSS Symposium 2019. Accessed 2026-10-26. https://www.ndss-symposium.org/ndss-paper/how-bad-can-it-git-characterizing-secret-leakage-in-public-github-repositories/ ↩
-
Byers, S., "Information leakage caused by hidden data in published documents," IEEE Security & Privacy 2(2):23–27, March 2004, doi:10.1109/MSECP.2004.1281241. Accessed 2026-10-26. https://doi.org/10.1109/MSECP.2004.1281241 ↩