Navigate ulfschneider.io

Here is my blog. If you like it, you may want to subscribe to my RSS feed.

2026: All posts

Bookmark

How AI text watermarking works by James Padolsey is an exceptionally readable explanation. Only the holder of the key that was used to place the watermark can detect it!

[Watermark] detection is private, probabilistic, and about processing, not authorship.

  • Only the key-holder can check. Your teacher, editor, or favourite "AI detector" website cannot run this test; a genuine check needs the provider's secret key, or a checking service the provider runs. Google runs an early-access detector portal for SynthID; Anthropic says detection tooling is forthcoming.
  • A watermark check is not an "AI detector." Tools like GPTZero guess from style and are famously unreliable. A watermark is the opposite: a deliberate, key-gated statistical test. Don't let the two blur.
  • A found mark means "processed by", not "written by". Anthropic's own documentation notes that human text merely proofread or translated by Claude picks up the mark. And absence proves even less: old models or heavy editing yield clean results on genuine AI text.
  • Short and low-choice text carries little mark. Evidence grows with length, and text with only one right continuation (code, quotations, lists of facts) offers the dice too little slack to hide anything in.
  • Certain marks outlive a rewrite. Schemes keyed on the word itself rather than its neighbours hold up far better: a same-meaning rewrite keeps enough of the words that much of the mark survives. (Their weakness is different: a colouring reused everywhere can be reverse-engineered from enough output.) Others hide in the meaning, and a same-meaning rewrite partly preserves them; the only answer we know there is outline-level regeneration.
Bookmark

Use Email address obfuscation: What works in 2026? by Spencer Mortensen to keep your email address away from spammers.

This could be a case for a web component combining multiple of the presented techniques. Unfortunately, what really works requires JavaScript, which can be an issue. My favorite pattern so far is 2.10 User Interaction, because it provides decent protection against spammers without additional library dependencies. I am using it with the Intersection Observer API and CSS class name selectors .oma for obfuscated email address and .oml for obfuscated email link.

// email obfuscation
const mObserver = new IntersectionObserver(decode)
function decode(entries, observer) {
  const parts = ["d", "o", "n", "a", "l", "d", "@", "d", "u", "c", "k", ".", "c", "o", "m"]
  for (const e of entries) {
    if (e.isIntersecting && e.target.classList.contains("oml")) {
      e.target.setAttribute("href", "mai" + "lto" + ":" + parts.join(""))
      mObserver.unobserve(e.target)
    }
    if (e.isIntersecting && e.target.classList.contains("oma")) {
      e.target.innerText = parts.join("")
      mObserver.unobserve(e.target)
    }
  }
}
function observe() {
  for (o of document.querySelectorAll(".oml,.oma")) {
    mObserver.observe(o)
  }
}
if (document.readyState == "loading") {
  document.addEventListener("DOMContentLoaded", observe)
} else {
  observe()
}

To challenge the crawler a bit more, you could put that script into a dedicated file mail.js, and load it from inside of your head, like:

<script>
  //challenge the crawler!
  const s = document.createElement("script")
  s.src = "/js/mail.js"
  document.head.appendChild(s)
</script>

This will require the crawler to

  • execute JS,
  • discover the dynamic script,
  • load the script, and
  • execute it,

to get your email address.

Bookmark

jwt.io/introduction is a good introduction to JWTs.

Tool-wise authgear.com/tools/jwt-jwe-debugger is probably a good choice, as it runs completely in the web browser. Authgear claims:

Your data security is our top priority. All encoding, decoding, encryption and decryption happen in this browser. This tool does not store or send your JWT and JWE outside of the browser.

I find these resources useful for learning Go