How to generate a valid file of any exact size, in the browser

작성자

카테고리:

← 피드로
DEV Community · Byte Rivet · 2026-08-05 개발(SW)
Cover image for How to generate a valid file of any exact size, in the browser

Byte Rivet

I needed a 10 MB PDF to test an upload limit. Not “about 10 MB” — exactly 10,485,760 bytes. Every generator I found gave me fixed sizes or made me wait for a server download.

So I looked into doing it in the browser. The interesting part wasn’t the size. It was keeping the file valid while hitting an arbitrary byte count.

The naive approach breaks the file

The obvious move is: make a real file, then append junk bytes until you hit the target.

const blob = new Blob([realPdf, padding]); // ← corrupt

Enter fullscreen mode Exit fullscreen mode

For most formats this produces a broken file. A PDF reader follows the cross-reference table to a byte offset; trailing garbage after %%EOF can throw it off. A PNG decoder walks length-prefixed chunks; extra bytes at the end aren’t a valid chunk.

The trick is that every format already reserves a legal place for extra data. You just have to put the padding there.

Padding where the spec allows it

  • PNG → a tEXt metadata chunk. It has a length prefix and a CRC-32, so decoders read exactly its declared length and skip the rest. Perfectly valid.
  • PDF → an unreferenced content stream. Same mechanism PDF writers use for incremental updates — the xref table just doesn’t point at it.
  • ZIP / DOCX / XLSX → a stored (uncompressed) entry inside the archive.
  • JPEGCOM comment segments, up to 65,533 bytes each.

For PNG, the padded chunk needs a correct CRC or the decoder rejects it:

function pngChunk(type, data) {
  const body = concat(type, data);
  const crc  = crc32(body);           // must be correct
  return concat(uint32(data.length), body, uint32(crc));
}

Enter fullscreen mode Exit fullscreen mode

Get the CRC right and the file opens everywhere — the padding is invisible.

Why the browser part matters

Because nothing crosses the network, size barely affects speed. Assembling a 100 MB file is a memory operation, not a download — it lands in tens of milliseconds. And the file never leaves your machine, so there’s no upload, no storage, nothing to log.

I verified the output against real parsers — pypdf reads the PDF text, Pillow decodes the PNG, openpyxl opens the XLSX. They’re genuinely valid files, just padded.

I turned this into a free tool (ByteRivet) that does 19 formats at any exact size, all in-browser. But the padding-without-corruption idea is the reusable part — worth knowing whenever you need a fixture at a precise size.

What’s the weirdest exact-size requirement you’ve hit in testing?

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다