Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why did a cleaned numeric field become byte zero?

Our byte constructors turn 256 into 0, -1 into 255 and 1.9 into 1. They also turn the marked nonnumeric input into 0 before cleanup. Validate an integer in the allowed range before byte conversion.

Tested October 20, 2026 · v24.19.0 · 4 measured runs

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked byte

Measured inputs and outputs

These are locally constructed test strings, not evidence that Claude inserts these characters. We executed the saved homepage script snapshot with a minimal DOM harness and compared exact strings. The invisible-checkbox state and dash mode appear in each row. The observations below test this page's specific question. Destination observations run independently on the exact input and cleaned strings in the recorded Node runtime. We make no detector-score or statistical-watermark removal claim.

Before and after observations; full code points and strings are in the JSON download.
Fixture and modeInput string and code pointsOutput and cleaner statusObserved before / after
Marked byte
direct string / keep / invisible true
"2​55"
U+0032 U+200B U+0035 U+0035
"255"
Removed 1 invisible character
{"number":"NaN","typedByte":[0],"bufferByte":[0]}
{"number":"255","typedByte":[255],"bufferByte":[255]}
Overflow byte
direct string / keep / invisible true
"256"
U+0032 U+0035 U+0036
"256"
No selected invisible characters found
{"number":"256","typedByte":[0],"bufferByte":[0]}
{"number":"256","typedByte":[0],"bufferByte":[0]}
Negative byte
direct string / keep / invisible true
"-1"
U+002D U+0031
"-1"
No selected invisible characters found
{"number":"-1","typedByte":[255],"bufferByte":[255]}
{"number":"-1","typedByte":[255],"bufferByte":[255]}
Fraction byte
direct string / keep / invisible true
"1.9"
U+0031 U+002E U+0039
"1.9"
No selected invisible characters found
{"number":"1.9","typedByte":[1],"bufferByte":[1]}
{"number":"1.9","typedByte":[1],"bufferByte":[1]}

A successful byte construction can hide invalid input

The marked text 2 plus U+200B plus 55 converts through Number to NaN. Nevertheless, constructing a one-element Uint8Array from that string yields byte zero, and Buffer.from with a numeric-element array gives the same byte. After cleanup, the value becomes 255 and both constructions yield 255. A caller checking only whether construction throws would miss the invalid original field. We record Number separately from the resulting byte so the zero cannot be misread as evidence that the original field explicitly contained zero or that the cleaner inserted a zero.

Range and integer checks are independent of cleanup

The overflow control 256 produces zero, the negative control -1 produces 255, and the fractional control 1.9 produces one. All three strings are unchanged by the cleaner. These observations isolate numeric-element conversion from marker removal. A finite numeric result alone is insufficient if the intended contract requires a whole byte between zero and 255. Our controls include finite values violating each remaining requirement. The data records actual resulting bytes rather than describing the operation loosely as a truncation, because the negative and overflow cases show why that shorthand can obscure the accepted output.

Distinguish numeric elements from text bytes

The observer uses new Uint8Array([s]) and Buffer.from([s]), with s as one array element. It does not pass the string as the direct text argument to Buffer.from. Those are different APIs with different purposes. If the goal is encoding the characters of a message, select an explicit text encoder instead of a numeric byte-element constructor. If the goal is importing a decimal byte value, validate the complete field, require an integer and check the allowed range before constructing the array. Preserve a validation failure instead of converting it to a plausible byte.

What the byte matrix establishes

These four measurements do not decode a real binary file, inspect a network packet or test a device protocol. They also do not imply that every typed array uses the same range behavior; the element type in the script is specifically unsigned eight-bit. Our UTF-8 guides address encoded character sequences and budgets, whereas this page addresses coercion of individual numeric elements. The runtime and saved script identify the precise conversion path. Character cleanup cannot recover a value after information has already been collapsed into a byte, and no byte in this synthetic record is evidence of a Claude watermark.

Reproduce this test

Save reproduce.cjs and tested-app.js in the same folder. Run the command below with Node.js. The harness prints its runtime, script SHA-256 and every measured row. Compare those rows with the original record. Using a newer script or runtime creates a new experiment; retain the version information with your rerun.

node reproduce.cjs

Reference and next check

ECMAScript ToUint8 provides the relevant primary definition. The table and fixture analysis are original measurements. For broader inspection, use our Unicode inspector. Read the scope distinction before interpreting cleanup as a watermark result.