The specimen is yours · language

The Encoding Your Text File Admits To

Drop a text file. Your browser will prove which Unicode forms its complete bytes satisfy, show the surviving readings, and keep a statistical favorite separate from what the author actually meant.

A byte string can be accepted by more than one encoding and say different things under each. That is not an algorithm failing to think hard enough. It is missing evidence. For a fixed list of encodings every computation here terminates; what the bytes do not contain is a label saying which reading was intended.

Standards fact

Does the complete byte string obey a named encoding grammar?

Statistical guess

Which candidate looks most like the detector's learned patterns?

Authorial intent

Which encoding did the writer or program mean? Bytes alone may not say.

Published anchor · runs before your file

Unicode Table 3-7, reproduced first

Unicode 17.0 prints three test vectors beside its nine legal UTF-8 forms. The independent state machine used on your file and the browser's fatal UTF-8 decoder both run them now.

printed bytesstandard saysTable 3-7 machinefatal TextDecoderresult

Nine boundary probes, derived from the rows rather than printed beside them

Three printed vectors cannot separate a correct Table 3-7 from a wrong one. The offline verifier corrupts each row six ways a person actually gets it wrong and shows that a pass or fail verdict on the printed vectors alone catches only two of the six. These probes each sit one byte outside a single row limit, which is what closes the gap. They are derived here, not quoted, and are labelled as such.

byteswhich limit it probesderived expectationTable 3-7 machineresult

The four printed U+FFFD tables, which discriminate where a boolean cannot

Unicode 17.0 section 3.9.6 prints Tables 3-8 to 3-11: what a replacing decoder should emit for ill-formed input. This page reproduces them with its own maximal-subpart routine, which never calls TextDecoder, and with the browser's replacement decoder. Table 3-11 is the discriminating row: nine bytes give four U+FFFD under maximal-subpart substitution and eight under naive per-byte substitution, so it separates two rules that a reject-or-accept test reports identically. The standard calls this substitution practice recommended and explicitly not required for conformance; the normative neighbour is the weaker rule in 3.9.5 that a converter must not consume bytes that begin a well-formed sequence.

printed tableinput bytesprinted outputlocal maximal-subpart routineresult

Running the published vectors.

Anchor: The Unicode Standard, Version 17.0, Chapter 3, definition D92 and Table 3-7, with Tables 3-8 to 3-11 from section 3.9.6. The printed outcomes are C0 AF ill-formed, E0 9F 80 ill-formed, and F4 80 83 92 well-formed. RFC 3629 agrees byte for byte and says so without claiming authority: its section 4 states that the authoritative definition is in the Unicode Standard and that its own grammar is believed to describe the same thing.

Layer one · your complete file

Put the bytes on the bench

TXT, CSV, TSV, Markdown, JSON, XML, subtitles and logs are all welcome. Binary input is allowed too, but a valid encoding grammar does not prove the bytes are text.

A ceiling, added after measurement rather than designed in. Review of this page found that twelve simultaneous decodings with a tracked source span per character cost about 350 bytes of browser memory per input byte. Headless Chromium measurements: 262,144 bytes cost 109 MB and 263 ms, 1,048,576 bytes cost 349 MB and 1,029 ms, 8,388,608 bytes cost 2,510 MB and 7,686 ms, and 16,777,216 bytes crashed the renderer outright, which is a failure no code on this page could have caught or explained. So a file larger than 262,144 bytes is now refused before a single byte is read, and the refusal prints the limit and the file's own size. Sampling a prefix instead would silently answer a different question, and the whole point of the instrument is that it reads all of the file or none of it.

Waiting for the published anchor.

post-load resource requests0 resources already loaded before observer0 network stateStarting observer.

The page's inline Content Security Policy says connect-src 'none'; form-action 'none'; worker-src 'none'. The file is read by File.arrayBuffer() into page memory. There is no upload function. Open your browser's Network panel before choosing a file if you want the browser's own account.

Why the score stays in the second column

A published detector result, with its walls left standing

Pomikálek and Suchomel's 2011 chared paper used byte trigrams, about a thousand Web pages per language, labels taken from meta tags, and five-fold cross-validation with the language already known. It called the evaluation preliminary and did not compare against other systems. Those accuracies do not transfer to chardet 2.2.0 or to an arbitrary file dropped here.

Open the paper's complete Table 1, transcribed as printed

Each language has a Web frequency and a cross-validated accuracy. The paper prints n/a when its table gives no accuracy. Nothing in this transcription is a result from the detector running above.

encodingCzechEnglishGermanGreekItalianNorwegian
freqaccuracyfreqaccuracyfreqaccuracyfreqaccuracyfreqaccuracyfreqaccuracy
utf-860.2%100.0%56.9%95.8%54.6%100.0%68.5%100.0%54.2%100.0%63.0%100.0%
windows-125032.2%100.0%0.3%n/a0.1%n/a0.2%n/a0.0%n/a0.1%n/a
windows-12520.4%n/a9.4%97.5%6.5%97.3%3.1%75.8%7.1%95.7%7.0%97.4%
windows-12530.0%n/a0.0%n/a0.0%n/a14.3%99.3%0.0%n/a0.0%n/a
iso-8859-11.0%89.5%32.8%90.9%37.1%85.8%1.7%71.2%37.9%85.1%29.3%88.2%
iso-8859-26.0%99.6%0.0%n/a0.1%n/a0.0%n/a0.1%n/a0.1%n/a
iso-8859-70.0%n/a0.0%n/a0.0%n/a12.0%97.2%0.0%n/a0.0%n/a
iso-8859-150.0%n/a0.0%n/a1.2%85.6%0.0%n/a0.0%n/a0.4%n/a
training docs801668773879771740
w. avg accuracy99.2%93.5%93.7%97.9%93.3%95.7%

The next table isolates the two summary rows and adds one derived column. Error rate is not printed by the paper. It is calculated here as 100 minus weighted average accuracy.

languagetraining documentsweighted average accuracyderived error rate
Czech80199.2%0.8%
English66893.5%6.5%
German77393.7%6.3%
Greek87997.9%2.1%
Italian77193.3%6.7%
Norwegian74095.7%4.3%

Selected low cells from the printed table expose the confusions: ISO-8859-1 was 71.2% for Greek, 85.1% for Italian, and 85.8% for German. The error rates above are derived here as 100 minus the paper's printed weighted average.

The moat is inspectable

Nothing leaves the device

The policy in this document's head blocks connections, forms, workers, frames, objects and media. The instrument contains no fetch, XMLHttpRequest, WebSocket, beacon, analytics or storage call. Font CSS, scripts and icons are same-origin. The byte array exists only in this page's memory until the page closes or another file replaces it.

Resource names observed after instrument load:

none

A zero here is the page's own report. The stronger check is yours: open Developer Tools, select Network, choose a file, and watch that no request carries its name, bytes, hash or text.

What this does not prove

The missing label stays missing