Stuffed-Na(a)N: stuff your NaNs

2 months ago 6

 MIT/ NPM Version

A photo of a garlic naan

Joy via Wikimedia

Have you ever done this by mistake?

console.log(0 / 0) // Output: NaN

Or maybe this?

console.log(Math.asin(2)) // Output: NaN

Have you been annoyed by NaN propagation?

const a = NaN console.log((a * 2) - 5) // Output: NaN

With stuffed-naan, you can finally make use of NaNs. Just stuff NaN Na(a)Ns with your data!

import { encode, decode } from 'stuffed-naan'; const encoded = encode("Hello world"); console.log(encoded); // Output: [NaN, NaN, NaN] console.log(decode(encoded)); // Output: Hello world

To quote Sun Tzu, "If you can't beat the enemy, use the enemy's advantage to your advantage". Na(a)Ns preserve data even when used in mathematical operations:

import { encode, decode } from 'stuffed-naan'; const encoded = encode("Hello world"); console.log(decode(encoded.map(x => x * 2))); // Output: Hello world

stuffed-naan is compact. Community Edition achieves a compression ratio of -25%. That means, for every 1024 bytes of data, you get 1368 bytes of float64 Na(a)Ns back! This is an industry-beating level of Na(a)N compression. For even better compression, consider the Enterprise Edition.

stuffed-naan is blazing fast. Thanks to advanced byte-manipulation capabilities available in ECMAScript® 2026, the overhead of stuffing is minimal. Na(a)Nification of a thousand small objects takes 1–3ms.

stuffed-naan is privacy-first. It's a first-of-its-kind privacy-preserving encoding, since an array of Na(a)Ns can't be copypasted without losing the information. This makes stuffed-naan indispensable to protect your customers' PII. Contact stuffed-naan DPO to learn more.

Or you can do this in your browser console:

const stuffedNaan = await import('https://unpkg.com/stuffed-naan'); stuffedNaan.encode("hello world");

Enterprise Edition includes:

  • ✅ 6% more efficient encoding
  • ✅ Support for big-endian processors, such as IBM zSeries
  • ✅ A dedicated Customer Success Manager

Contact sales for pricing.

  • ⚠️ Public benchmark history
  • ⚠️ Fuzzing
  • ⚠️ Rewrite in Rust
  • ⚠️ Formal verification with Kani

JS numbers are IEEE 754 floating point numbers, 64-bit long. They consist of a sign bit, an exponent, and a mantissa.

Here's how it all looks in memory:

Memory layout of a float64 from Wikipedia

When mathematical operations on floats are applied incorrectly (for example, 0/0), they return special values called Not a Number, or NaN for short. NaNs are represented as floating point numbers with the exponent set to all 1s and at least one non-zero bit in the fraction part.

Which means I can commit crimes and smuggle data in the fraction part. IEEE is not going to stop me!

This trick is silly, but it works. Of course, I couldn't resist overdoing the naan pun.

Support your local curry house! (Or, better yet, Come Back Alive)

Bluesky / Twitter / Web

Read Entire Article