Skip to content

perf: replace base64.h with simdutf SIMD-accelerated codec#50

Closed
GrzywN wants to merge 1 commit into
craftzdog:masterfrom
GrzywN:feat/simdutf-codec
Closed

perf: replace base64.h with simdutf SIMD-accelerated codec#50
GrzywN wants to merge 1 commit into
craftzdog:masterfrom
GrzywN:feat/simdutf-codec

Conversation

@GrzywN

@GrzywN GrzywN commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #42

Replaces the René Nyffenegger base64.h codec with simdutf v8.2.0 — the same SIMD-accelerated base64 library used internally by Node.js, Bun, and Deno. The library is vendored as an amalgamated single-file (simdutf.h + simdutf.cpp), keeping the same zero-external-dependency setup as before.

Encode (base64FromArrayBuffer) calls simdutf::binary_to_base64 directly.

Decode (base64ToArrayBuffer) mirrors V8's Uint8Array.fromBase64 implementation via simdutf::base64_to_binary_safe with loose last-chunk handling and decode_up_to_bad_char=true.

Behaviour changes (TC39-compliant)

Input Before After
Mid-string padding (SQ==QU0=) silently decoded → [73, 65, 77] throws Invalid base64
\n without removeLinebreaks silently ignored throws Invalid base64
\n with removeLinebreaks=true stripped, decoded stripped, decoded ✓
URL-safe chars (-_) accepted accepted ✓
Missing = padding accepted (loose) accepted (loose) ✓

Files changed

File Change
cpp/simdutf.h new — amalgamated header (v8.2.0)
cpp/simdutf.cpp new — amalgamated implementation
cpp/base64.h deleted
cpp/react-native-quick-base64.cpp replace codec calls
android/CMakeLists.txt base64.hsimdutf.cpp in sources
example/src/tests/corrupt.ts update for TC39 behaviour
example/src/tests/linebreaks.ts use MIME-style line-wrapped test data

iOS podspec (cpp/**/*.{h,cpp}) picks up simdutf.h/.cpp automatically — no podspec changes needed.

Screenshots

Android emulator iPhone 16e simulator

Closes craftzdog#42

Replace the René Nyffenegger base64.h codec with simdutf v8.2.0
(used by Node.js, Bun, Deno). Encode uses binary_to_base64 directly;
decode mirrors V8's Uint8Array.fromBase64 via base64_to_binary_safe
(loose, decode_up_to_bad_char=true).

Behaviour changes (now TC39-compliant):
- mid-string padding (e.g. SQ==QU0=) is rejected instead of silently decoded
- \n in input without removeLinebreaks=true throws instead of being ignored
@GrzywN

GrzywN commented Mar 18, 2026

Copy link
Copy Markdown
Contributor Author

The SQ==QU0= behaviour change is backed by the TC39 Uint8Array.fromBase64 spec (Stage 4, shipping in V8 & SpiderMonkey). The FromBase64 algorithm (§ 10.3) rejects any characters after a = padding sequence — making mid-string padding a hard error, not an implementation choice. RFC 4648 § 3.5 establishes the same rule at the wire level.

simdutf::base64_to_binary_safe with loose + decode_up_to_bad_char=true mirrors exactly what V8's ArrayBufferFromBase64 does internally, so toByteArray & Uint8Array.fromBase64 now produce identical results for the same input.

@craftzdog

Copy link
Copy Markdown
Owner

Amazing. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Suggestion] Switch native implementation to simdutf

2 participants