TSV breaks in transit for one reason: the tab is invisible
A tab-separated file has no quoting rules and no escape character. Column boundaries are single U+0009 bytes, and rows end at a newline. That simplicity is the point, and it is also the weakness. Every layer between your file and its destination treats whitespace as something it may reformat.
A web form trims it. A YAML parser rewrites it. A JSON string survives fine until someone pretty-prints the payload. Email clients and chat apps convert runs of tabs into spaces before the message leaves. The receiving side sees a table with the right rows and one column, and nobody notices until a report comes out empty.
Base64 removes the question. The 64 characters in the alphabet are letters, digits, plus, and slash, all of which survive anything that handles text at all. Whatever bytes go in come back out, tabs included, spacing included, trailing spaces on the last cell included.
Check the grid before you encode
Encoding hides mistakes as effectively as it protects data. A row missing a tab and a row with the right structure produce Base64 strings that look equally plausible, and the difference surfaces on the far end. The preview table exists for that reason: it splits your input the same way the decoder will, and marks anything that does not line up.
- Ragged rows hold a different number of columns from the header. Load the Uneven row widths sample and one row comes up short while another carries an extra field. Most importers align by position, so a short row shifts every value after the gap into the wrong column.
- Empty cells are marked separately from missing ones. Two tabs in a row is a deliberate blank. A row that simply ends early is truncated data. TSV writes both as nothing, and the preview separates them.
- Padded cells carry leading or trailing spaces. Spreadsheet exports collect these constantly. A key of
"North "will not match"North"in a join, and Base64 preserves the space perfectly. - No tabs at all means the paste lost its separators somewhere upstream. The row count looks right and the column count reads 1. Go back to the source rather than encoding it.
None of these stop the encoding. They are your data, and you may have reasons for all of them. The check tells you what the decoder will see.
Line endings change the bytes, so they change the string
Base64 encodes bytes, not lines. A file saved on Windows ends rows with 0D 0A. The same file on Linux or macOS ends them with 0A. Both decode to the same table, and the two Base64 strings share almost nothing.
YQliCmMJZA==YQliDQpjCWQ=Set the Line endings control when the string has to match a value produced somewhere else. Checksum comparisons, cache keys, signed request bodies, and test fixtures all fail on a mismatch that reads as identical data. LF is the safer default for anything crossing a network. CRLF belongs in files handed to older Windows tooling that opens them in Notepad.
Mixed endings inside one paste are worth fixing before anything else. The status line flags them, and forcing one style is the fix.
What the options do
Standard against URL safe
The standard alphabet ends with + and /. Both are reserved in a URL, so a Base64 string dropped into a query parameter gets mangled: the plus becomes a space in form decoding, and the slash reads as a path separator in some routers. The URL-safe variant from RFC 4648 section 5 swaps them for - and _, which no URL layer touches.
Use URL safe for query strings, path segments, filenames, and JWT payloads. Use standard everywhere else, since it is what base64_decode in PHP, base64.b64decode in Python, and atob in the browser expect without a translation step.
Padding
Base64 works in groups of three bytes. When the total is not divisible by three, one or two = characters mark the shortfall. Most decoders infer the length and accept a string without them, which is why JWTs drop padding entirely. Some do not, and PHP's decoder in strict mode is one of them. Leave the box ticked unless the format you are targeting asks for unpadded output.
Wrapping
One long line is right for JSON, headers, and query strings. The 76 column option matches MIME from RFC 2045, and 64 columns matches PEM. Pick a wrap only when the receiver expects it, then strip the newlines again before decoding if the decoder is strict about whitespace.
UTF-8 BOM
Excel needs the three byte marker EF BB BF at the start of a file to open it as UTF-8 rather than the system code page. Without it, accented names and CJK text arrive as mojibake. Tick the box when the decoded bytes will be written to a file someone opens in Excel. Leave it off when a parser reads them, because the marker turns up as a stray character on the first header name and quietly breaks a column match.
Size, and the 33 percent tax
Four Base64 characters carry three source bytes, so the encoded form runs roughly 33 percent longer, plus padding and any newlines you add. The meters show the real figures for your input rather than the rule of thumb.
Watch the byte count rather than the character count when your data has accents or CJK text. Load the Accents and CJK sample: ü costs two bytes, 東 costs three, and an emoji costs four. The source looks short and the encoded string does not.
Base64 is not compression and it is not encryption. The string is longer than the source, and anyone with a decoder reads it back in a second. A customer export encoded into a Base64 blob in a log file or a URL is still a plain customer export. Encrypt first when the content is sensitive, then encode the ciphertext.
Where the string goes next
The common destinations, and what each one wants:
- A JSON field. Standard alphabet, one line, padding kept. Base64 sidesteps the tab and newline escaping that would otherwise fill the value with
\tand\nsequences. - An HTTP header. Headers hold no line breaks and no raw tabs, so the encoding is mandatory rather than convenient. Keep it on one line and watch the size, since most servers cap a single header near 8 KB.
- A data URI. The box above builds
data:text/tab-separated-values;base64,…for you. Point an anchorhrefat it with adownloadattribute and the browser saves the table as a file with no server involved. - A config file or environment variable. A multi-line table becomes one value that survives shell quoting, Docker build arguments, and CI secret storage.
- A database column. Fine for a small snapshot. Past a few kilobytes, a real table beats a blob you have to decode before you can query it.
Decoding it back
Every language ships a decoder, and the one line version is usually enough:
$tsv = base64_decode($b64, true);if ($tsv === false) { }import base64
tsv = base64.b64decode(b64).decode('utf-8')const bytes = Uint8Array.from(atob(b64), c => c.charCodeAt(0));const tsv = new TextDecoder().decode(bytes);echo "$B64" | base64 --decode > data.tsvThe JavaScript case deserves a note. Calling atob and using the result as text works only for ASCII, because atob returns a binary string where each character is one byte. Skip the TextDecoder step and a name like Zürich comes back as Zürich. The same asymmetry applies when encoding, which is why this page runs bytes through TextEncoder rather than handing a string to btoa.
After every encode here, the result is decoded again and compared against the source. The status line reports the match, so a silent character mangling shows up before the string leaves the page.
Where this page stops
File input is capped at 2 MB. Everything runs in this tab with no upload, and a browser textarea holding a multi-megabyte table becomes slow to type in long before the encoder struggles. Command line base64 handles a large export in a fraction of the time.
Nothing here converts between formats. The table is encoded exactly as pasted, so a CSV pasted in gets encoded as CSV, commas and all. TSV to CSV handles that conversion, and the shape check only understands tabs.
There is no delimiter guessing. Pipe-separated and semicolon-separated data will encode without complaint and report one column, since a tab is the only separator this page recognises.
Quoted fields containing literal tabs are not supported, because TSV has no quoting rules. The IANA specification tells you to strip tabs from field values rather than escape them. Data holding real tabs inside a cell needs CSV or a different format.
Nothing persists. Close the tab and the input is gone, so save what you need before you leave.
Nearby pages
Going the other direction, Base64 to TSV decodes a string back into a table. For a table you want as structured data instead, TSV to JSON and TSV to XML parse the columns properly. CSV to Base64 covers the comma-separated equivalent, and Base64 validator checks a string someone sent you before you try to decode it.
