Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>QR Text TransferNew to Visual Studio Code? Get it now.
QR Text Transfer

QR Text Transfer

ten9miq

|
2 installs
| (0) | Free
Transfer long text offline by compressing it with Brotli and automatically splitting it across multiple QR codes.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

QR Text Transfer

English | 日本語

QR Text Transfer converts text selected in VS Code into one or more QR codes so it can be transferred to a smartphone or another PC. QR generation, compression, and restoration are performed locally without using a network, cloud storage, or a shared clipboard.

Key features

  • Compress long text with Brotli and split it automatically across multiple QR codes.
  • Restore scanned QTXT1 packets in any order and detect missing, mixed, or corrupted data.
  • Preserve UTF-8 text including Japanese, emoji, line endings, tabs, spaces, source code, and JSON.
  • Generate directly readable QR codes in plain text mode without compression or the QTXT1 protocol.
  • Adjust the maximum QR version to balance scan readability against the number of QR codes.

Demos

Generate QR codes

Generating QR codes from selected text

Decode a scanned QR transfer

Decoding scanned QR packets into the restored text

Encode text

  1. Select text in an active editor.
  2. Run QR Text Transfer: Encode Selection to QR from the Command Palette or editor context menu.
  3. If there is no selection, confirm that you want to encode the entire document.
  4. Scan each displayed QR code. Use Previous / Next, First / Last, or the Left / Right arrow keys to navigate multi-packet transfers.

The WebView shows the original byte count, encoded payload size, compression method, Base45 usage, protocol, QR count, configured maximum QR version, and the actual version of the displayed QR code.

Use the Maximum QR version slider to regenerate the current mode with a limit from 4 to 40. The slider starts at qrTextTransfer.maxQrVersion, applies changes after a short delay, and caches recent mode/version combinations. It affects only the current WebView and does not change the VS Code setting.

Command titles, settings, notifications, errors, and the QR WebView are displayed in Japanese when the VS Code display language is Japanese. Other display languages use English.

Plain text mode

Enable Plain text QR (no QTXT1 protocol, compression, or Base45) in the WebView to generate QR codes containing the original text directly. Plain QR generation starts only when the checkbox is enabled; a loading indicator is shown while it runs. Unchecking it returns to QTXT1 mode, reusing an already generated result when available.

To start directly in plain text mode, run QR Text Transfer: Encode Selection as Plain Text QR. The WebView opens with the checkbox enabled and generates only the plain QR. Brotli compression, Base45 conversion, QTXT1 packet creation, and protocol QR generation are not performed unless you later disable the checkbox.

Plain text mode uses the original text as the QR input. Non-ASCII characters are represented by their UTF-8 bytes by the QR library, and a scanner returns text directly rather than a QTXT1: packet. The extension splits the text at Unicode code-point boundaries so every plain QR stays at or below qrTextTransfer.maxQrVersion. Scan multiple QR codes in display order and concatenate the scanned strings without adding separators. Because there are no IDs, sequence numbers, totals, or checksums, plain chunks cannot detect missing, reordered, mixed, or corrupted scans.

Decode a transfer

Paste the QR scanner results into an editor with one QTXT1: packet per line. Packet order does not matter and blank or unrelated lines are ignored.

  • Select the packet lines and run QR Text Transfer: Decode QR Transfer, or
  • Run the command with no selection and choose the Clipboard or the entire active document.

The restored text opens in a new untitled editor. Identical duplicate packets are accepted. Missing, conflicting, mixed-transfer, corrupted, and unsupported packets produce an error instead of partial output.

Privacy

All encoding, compression, QR generation, and decoding are performed locally. This extension does not upload transferred text to any external service.

The extension has no telemetry, analytics, cloud storage, or external API calls. The qrcode dependency generates QR images inside the extension host.

QTXT1 protocol overview

QTXT1 mode uses this local pipeline:

Text → UTF-8 → Brotli or raw bytes → chunks → Base45 → QTXT1 packets → QR

The smaller of Brotli-compressed and raw UTF-8 data is selected. Every packet uses the QR Alphanumeric mode, error correction level L by default, an eight-hex-digit transfer ID, sequence metadata, and a CRC32 checksum over the complete binary payload.

Why Base45

Brotli produces arbitrary binary bytes, but QR scanner results need to survive as ordinary text that can be copied through an editor or clipboard. Base45 converts those bytes to a restricted, text-safe alphabet that exactly matches the characters available in QR Alphanumeric mode:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:

Base45 produces a longer string than Base64, but QR Alphanumeric mode stores it in fewer QR data bits than standard Base64 in Byte mode.

Encoding QR mode Characters (1,000 input bytes) QR data bits Binary bytes per packet (v30-L)
Base45 Alphanumeric mode 1,500 (+50.0%) 8,250 bits 1,657 bytes
Standard Base64 Byte mode 1,336 (+33.6%) 10,688 bits 1,278 bytes

The 1,000-byte comparison excludes the QR mode and character-count indicators. It uses 11 bits per two Alphanumeric characters and 8 bits per Byte-mode character.

The per-packet comparison includes the same 34-character QTXT1 header. The hypothetical Base64 packet uses an Alphanumeric segment for the header and a Byte-mode segment for the Base64 data.

Under these default conditions, Base45 carries about 29.7% more binary data per packet than standard Base64.

Raw QR Byte mode can be slightly denser than Base45 in theory, but arbitrary binary scanner output is not reliably portable through text fields, editors, or clipboards. Base45 deliberately trades a small amount of theoretical density for predictable text handling and broad scanner interoperability. Compressing before Base45 reduces the expansion for compressible text.

QTXT1:<ID>:<SEQ>:<TOTAL>:<TYPE>:<CRC>:<BASE45_DATA>

For example, the following valid single-packet transfer represents the raw UTF-8 text AB:

QTXT1:42BF2FDB:001:001:N:30694C07:BB8

Packet fields

Field Format Role
QTXT1 Fixed uppercase text Protocol identifier and version. QTXT identifies QR Text Transfer and 1 is the protocol version. A decoder rejects unsupported versions instead of guessing their format.
ID 8 uppercase hexadecimal digits Random 32-bit transfer ID generated once for the complete transfer. Every packet in that transfer has the same ID. It detects packets accidentally mixed from different transfers; it is not an authentication value.
SEQ 3 decimal digits One-based sequence number of this chunk, from 001 through TOTAL. The decoder uses it to restore the original order, so QR codes may be scanned in any order.
TOTAL 3 decimal digits Total number of chunks in the transfer. It must be identical in every packet and is limited to 001–999. The decoder compares the received sequence numbers with this value to report missing packets.
TYPE B or N Encoding of the complete binary payload before it was split. B means Brotli-compressed UTF-8; N means raw UTF-8 because Brotli was not smaller. Every packet must have the same type.
CRC 8 uppercase hexadecimal digits CRC32 of the complete binary payload selected by TYPE, calculated before chunk splitting and Base45 encoding. The same CRC is repeated in every packet. After joining the chunks, the decoder verifies it before decompression. CRC32 detects transfer errors but does not provide cryptographic authentication.
BASE45_DATA RFC 9285 Base45 characters Base45 representation of this packet's binary chunk. Its alphabet is 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./: so the final packet can use QR Alphanumeric mode. Each chunk is Base45-decoded separately and then concatenated in SEQ order.

The colon (:) separates header fields and is also a valid Base45 character. This is unambiguous because the decoder parses the fixed-format header fields first and treats the remaining text as BASE45_DATA.

In QTXT1 mode, the extension dynamically calculates the maximum Alphanumeric length that fits the selected maximum QR version and error correction level, including the 34-character header within that limit.

With the default maximum QR version 30 and error correction level L, the final packet limit is 2,520 characters including the header.

Decode validation order

The decoder does not produce partial output. It performs these checks in order:

  1. Extract lines containing the QTXT1: prefix and parse every packet.
  2. Require the same ID, TOTAL, TYPE, and CRC in all packets.
  3. Accept byte-for-byte identical duplicate packets, but reject duplicates with conflicting data.
  4. Compare SEQ values with TOTAL and report every missing sequence number.
  5. Sort by SEQ, Base45-decode each chunk, and concatenate the binary chunks.
  6. Verify the CRC32 of the complete joined payload.
  7. Brotli-decompress when TYPE is B; leave the payload unchanged when it is N.
  8. Decode UTF-8 strictly and open the restored text in a new untitled editor.

Settings:

  • qrTextTransfer.errorCorrectionLevel: L (default), M, Q, or H
  • qrTextTransfer.maxQrVersion: maximum QR Code version from 4 to 40 for both modes (default 30)
  • qrTextTransfer.brotliQuality: Brotli quality from 0 to 11 (default 11)

Transfer size limits

There is no fixed limit measured in Unicode characters. The effective limit is based on the size of the binary payload selected after comparing raw UTF-8 with Brotli-compressed data.

With the default maximum QR version 30 and error correction level L:

  • The fixed QTXT1 header uses 34 characters.
  • The calculated maximum QTXT1 packet length is 2,520 alphanumeric characters.
  • Up to 2,486 Base45 characters remain for data.
  • One packet carries at most 1,657 binary bytes.
  • One transfer contains at most 999 packets.
  • The selected binary payload can therefore be at most 1,655,343 bytes (about 1.58 MiB).

If Brotli is not smaller and raw UTF-8 is used, this corresponds roughly to 1.65 million ASCII characters, 551,000 common Japanese characters at three UTF-8 bytes each, or 413,000 four-byte emoji. Natural-language text and source code often compress, so their original text can be larger as long as the selected compressed payload stays within the binary limit.

qrTextTransfer.maxQrVersion can be configured from 4 to 40. In QTXT1 mode, the extension calculates the largest alphanumeric packet that fits the selected maximum version and error correction level, then includes the 34-character header within that limit. Changing either setting therefore changes the effective transfer-size limit.

Compression occurs before the extension checks whether more than 999 packets would be required. Extremely large input can therefore consume noticeable time and memory before the extension reports the transfer-size error.

In plain text mode, the extension finds the longest Unicode code-point prefix that fits qrTextTransfer.maxQrVersion for the UTF-8 byte length, QR segment mode, and selected error correction level. It reuses the resulting length for subsequent chunks to reduce repeated capacity searches. Short chunks can use a lower QR version, but no generated QR exceeds the configured maximum. Plain text mode does not use compression or the 999-packet QTXT1 limit, but very large input can require many QR codes and substantial generation time and memory.

Known limitations

  • The extension displays QR codes but does not scan or recognize QR images.
  • QTXT1 scanner results must preserve packet text exactly and place each packet on its own line. Plain text mode returns text chunks directly and is not handled by the QTXT1 decoder command; multiple chunks must be scanned in order and concatenated manually.
  • Transfers are not encrypted. Anyone who scans every QR packet can reconstruct the text.
  • Sequence and total fields support at most 999 packets.
  • Camera quality, display scaling, glare, focus, and scanner behavior require manual testing on the intended devices.

Development

Requirements: Node.js 20 or later and npm.

npm install
npm test
npm run compile

The test suite covers RFC 9285 Base45 vectors, compression choice, CRC32, packet validation, shuffled and duplicate packets, error cases, whitespace, Japanese, emoji, source code, JSON, long lines, and at least 100 KB of mixed Japanese text.

Building a VSIX

The publisher and repository URL in package.json are configured for this repository. Before Marketplace publication, ensure that the ten9miq publisher ID is registered and accessible to the publishing account. Then run:

npm install
npm test
npm run package

The resulting .vsix can be installed with Extensions: Install from VSIX... in VS Code.

License

MIT. QR generation uses qrcode, which is also MIT-licensed. No source code from other QR extensions is included.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft