Code Golf is the art/science of creating wonderful little demos in an artificially constrained environment. This year the js1024 competition was looking for entries with the theme of "Creepy".
I am not a serious bit-twiddler. I can't create JS shaders which produce intricate 3D worlds in a scrap of code. But I can use slightly obscure JavaScript APIs!
There's something deliciously creepy about Numbers Stations - the weird radio frequencies which broadcast seemingly random numbers and words. Are they spies communicating? Commands for nuclear missiles? Long range radio propagation tests? Who knows!
So I decided to build one. Play with the demo.
Obviously, even the most extreme opus compression can't fit much audio into 1KB. Luckily, JavaScript has you covered! Most modern browsers have a built-in Text-To-Speech (TTS) API.
Here's the most basic example:
JavaScript
m = new SpeechSynthesisUtterance; m.text = "Hello"; speechSynthesis.speak(m);
Run that JS and your computer will speak to you!
In order to make it creepy, I played about with the rate (how fast or slow it speaks) and the pitch (how high or low).
JavaScript
m.rate=Math.random(); m.pitch=Math.random()*2;
It worked disturbingly well! High pitched drawls, rumbling gabbling, the languid cadence of a chattering friend. All rather creepy.
But what could I make it say? Getting it to read out numbers is pretty easy - this will generate a random integer:
JavaScript
s = Math.ceil( Math.random()*1000 );
But a list of words would be tricky. There's not much space in 1,024 bytes for anything complex. The rules say I can't use any external resources; so are there any internal sources of words? Yes!
JavaScript
Object.getOwnPropertyNames( globalThis );
That gets all the properties of the global object which are available to the browser! Depending on your browser, that's over 1,000 words!
But there's a slight problem. Many of them are quite "computery" words like "ReferenceError", "URIError", "Float16Array". I wanted all the single words - that is, anything which only has one capital letter and that's at the start.
JavaScript
const l = (n) => { return ((n.match(/[A-Z]/g) || []).length === 1 && (n.charAt(0).match(/[A-Z]/g) || []).length === 1); }; // Get a random result from the filter s = Object.getOwnPropertyNames( globalThis ).filter( l ).sort( ()=>.5-Math.random() )[0]
Rather pleasingly, that brings back creepy words like "Event", "Atomics", and "Geolocation".
Of course, Numbers Stations don't just broadcast in English. The TTS system can vocalise in multiple languages.
JavaScript
// Set the language to Russian m.lang = "ru-RU";
OK, but where do we get all those language strings from? Again, they're built in and can be retrieved randomly.
JavaScript
var e = window.speechSynthesis.getVoices(); m.lang = e[ (Math.random()*e.length) |0 ]
If you pass the TTS the number 555 and ask it to speak German, it will read out fünfhundertfünfundfünfzig.
And, if you tell the TTS to speak an English word like "Worker" in a foreign language, it will pronounce it with an accent.
Randomly altering the pitch, speed, and voice to read out numbers and dissociated words produces, I think, a rather creepy effect.
If you want to test it out, you can press this button. I find that it works best in browsers with a good TTS engine - let me know how it sounds on your machine.
With the remaining few bytes at my disposal, I produced a quick-and-dirty random pattern using Unicode drawing blocks. It isn't very sophisticated, but it does have a little random animation to it.
You can play with all the js1024 entries - I would be delighted if you voted for mine.
7 thoughts on “1KB JS Numbers Station”
Mike
Chrome 138.0 on Android - silence for four or five seconds then, mostly just weird with occasional bursts of something which feels like it would be creepy if it went on longer. Sometimes sounds like a voice which would ask Professor Falcon if he wanted to play a nice game of chess. I assume there being no way to make it stop without reloading the page or closing the browser tab is a creepy enhancing feature rather than a bug.
Safari on iPadOS 18.5 - Silence. The button doesn’t even acquire the state to show it’s active like it does in Chrome on Android. Total fail. I’d love to offer some help with making it work but last time I tried to work out how to make Safari on iPadOS tell me anything about what was going on behind the scenes in terms of errors and such I concluded it might be possible if I purchased a Mac to connect the iPad to and decided not to do that.
I sometimes go to https://priyom.org to see if there is a numbers station broadcasts scheduled soon and if so listen to it live. So far I’ve only heard stations which broadcast what I assume is morse code.
@Edent
Wonderfully odd. 🙂
Reply to original comment on mas.to
|SARAH ROSE TAYLOR
The demo works very well on my Samsung A8 tablet (Chrome). The voices sound quite natural (except for the s l o w paced ones).
1KB JavaScript Numbers Station | Hacker News
Reply to original comment on news.ycombinator.com
|Terence Eden built a neat and weird 1023 byte JavaScript demo that simulates a numbers station using the browser SpeechSynthesisUtterance, which I hadn't realized is supported by every modern browser …
Reply to original comment on simonwillison.net
|Developer Terence Eden created an eerie digital version of Cold War-era numbers stations using nothing but built-in browser features and 1KB of JavaScript code.
Reply to original comment on premium.boingboing.net
|The one where I make the web browser read it for me
Reply to original comment on dbushell.com
|More comments on Mastodon.