A quine is more similar to (but not quite the same as) an uncompressed image containing a QR code with a compressed copy of the same image, which has its own challenges; but like, a cryptographic hash function (such as SHA2) is designed explicitly to make this hard... if you had chosen a simple checksum instead it would be trivial to create an image containing the text of a checksum of the image: a compression function (particularly a tiny custom one designed for this one time use, that removes barely any entropy at all) is predictable enough to be manipulated. (edit: I hadn't looked at this one, though; but now that I see its code, apparently it is just cheating by accessing its own code via the DOM; it doesn't need to do that, and it doesn't even really feel like a "quine" to me given this implementation.)
For anyone wondering how is this possible I've made a quick research and the method is in the description part of this youtube video: https://www.youtube.com/watch?v=ufq2Eb78kSU
In short, Youtube API's resume upload function can be abused to achieve this.
As others have pointed out, it's not quite a quine and just some silly JavaScript that reads out its source from the DOM and feeds it back into a copy of Itty Bitty's URL generation algorithm.
I put those two together, and imagined a new form of app distribution, which I call "Fondant".
1. Click a data URI bookmarklet. That is a bootloader, with the parser code for a picture. It presents a button to upload a picture.
2. Select a picture from the camera roll, which is the app.
3. To save, generate a picture and save that to the camera roll.
This could be used to transfer other file types (e.g. a music player with a mixtape) over universally-supported photo sharing platforms.
Unfortunately, the iPhone recompresses JPGs when clicking Save to Camera Roll, and the lost quality means the photo isn't parseable the next time. I did some experiments, and turned a blue/green checkerboard pattern into grey after 50 repeated Saves.
I still think there's potential in the idea; if someone wants to work together on it then please get in touch. I'll also write up my experiments if you comment and ask for it.
The PICO-8 "fantasy console" is a playful old-school computer style emulator that passes it's programs through images. You might even look into it's algorithms [1]. I think it'd be perfect.
Encoding goes
E(T), E(E(T)), etc. let K be the per-char encoding overhead, so E(T) = KT: complexity is O(K^N * T) where N is number of levels and T is length of text at level 0!
It seems that due to the extra text from https://itty.bitty.site each iteration increases the size of the next link. I wonder how the urls are generated and if this is a linear or exponential increase.
My guess is 1st-degree polynomial. There’s a constant addition with each iteration, plus the contents appear to be base64(ish)-encoded into the next URL, which multiplies the length by a constant.
I did something similar with https://tinysite.adamdrake.com where I have a website that fits into a single ipv4 datagram (at least it did when I was using my own HTTP server).
When I moved it to AWS Lambda there was some size introduced from TLS and also from some headers that AWS API Gateway adds which seem, unfortunately, impossible to easily drop (e.g., if you make the headers empty in the response, APIGW will copy them into another header and still add its own).
I might pull that service off of AWS APIGW/Lambda, in which case the size as an artifact of AGIGW would disappear again.
My second reaction (after "awesome!") was that I'd love for this to support some kind of optional identifier+hmac functionality. That's not necessary for when you are fully in control of where people get the links of course, but as soon as someone starts sharing links to "your" content they can by definition modify it as well. It'd be cool if I could share a page that says "by chias" and that can prove it.
Then again, that would require itty-bitty to know that I exist, store my key somewhere, have some kind of auth system for me to log in and set my key... and now we're talking usernames, passwords, recovery email addresses, etc. etc., and I love the concept of services offered to people that explicitly don't do any of that. So third reaction is that it's great as-is :)
The data URI scheme is standard and widely supported, does not rely on the host bitty.site being reachable and does not need JavaScript. One can even create data URIs with a small shell script that is given a filename argument:
I wonder how large a website using this scheme can practically be to work on most browsers. I know of at least one browser that limited URLs to 100 characters, but it's almost 30 years old…
The HN frontpage bitty that I posted in another comment is around 8K. [1]
I also did a reddit one that works on my browsers[2] (copy/paste URL into new tab) at 26K (!). Which is apparently too much for HN. (Where's my free 5GB of storage for signing up?!)
What would such a cross-site scripting vuln do? There isn't anything to steal.
Moreover you wouldn't use this for anything where you aren't in control of where people get the links from, because as soon as someone else starts sharing it they can of course edit it too.
I disagree. It's more similar to how you can "inject" your scripts into fiddle.jshell.net (via JSFiddle), googleusercontent.com (via Google Translate), etc.
Might a bad actor user something like this, combined with a homograph domain, to conceal malicious content in the URL and prevent a crawler discovering the malicious content (ignoring the fact that the homograph might be detected/redflagged on its own).
(use case might be a homograph phishing site, with a fakelogin and the target for the captured input being obfuscated into the URL)
I do something similar in a bookmarklet to give myself a nice looking notepad. It's essentially a padded content editable div, with a prepopulated H1. This lets me print it out or save it as a document when needed. Which is never.
That's one of my favorite "stupid HTML tricks". I wonder who first figured it out? I can't find the original blog post (if it even was) and now it's a known thing:
It's a legit pattern. Compression of binary data. Encoding to base64 string. And packing into data uri. Golang out of the box has packages for handling the entire pipeline.
You get a small performance hit on page load from decoding. But its still performant and bandwidth-saving. For network constrained users this is a solution. Also consider the scenario where you are bootstrapping. Serving static content from a single server instance or S3. But still want to target a global audience ;)
So if one must think about it in terms of client/server (my mind works like this), since the website data is contained in the URI itself, then the server/site where you clicked on the URL from, can perhaps we thought of as the "web server" per se. Just a way for me to think about it. This is pretty crazy though, neat stuff.
No, the page content is never sent to the server. all the server does is serve a static HTML page with some javascript. The javascript reads the compressed encoded data in the URL (the fragment which browsers never send to the server during a request) and then it decodes the data and writes the data to the current DOM.
All content data is stored in the link itself and never seen by the itty.bitty server.
My mind immediately went to stuff like tickets. Can't say how many times I've gotten stuck having my ticket checked at a concert or on a train simply because there's no connectivity and the page is no longer in cache on my phone. If all the data is in the URI then it could work as an option for entirely static data. I'd say this is useful for almost anything that fits in a one page PDF.
If you want the whole UI around rendering the content, sure, but you don't need that – it's just an iframe that sets a `data:` URI anyway. The link can just as well be the data URI itself. It'd be a very long link for any non trivial content, but it works just fine without any connectivity.
Seeing as tickets are typically sent in HTML emails anyway the scary looking URI can just be hidden behind a nice anchor tag or something anyway. When the recipient clicks the link, the page will open in a browser and render just fine without any connectivity. Graphics can be embedded in the same way, using `data:` URIs as image tag sources, or in embedded css.
Here's an example, turn off your connection and try this in your browser's address bar:
Unfortunately that comes with a bootstrapping problem: what if the first time you hit the link is when you aren't connected? If everything is embedded in the data URI and the link is in fact the data itself then it doesn't matter.
I think that's an acceptable requirement. After all, you wouldn't expect an app to work without downloading it. If instead of using lzma, gzip were used, I bet you'd be able to include some code that would unzip itself using the browser's unzip capability. I am not sure how much code that would take though.
Right, for an app that makes sense but the use case I mentioned was really just pure data. A ticket is rarely more than a qr code or some other identifier, whose veracity is then checked t the point of reading. In an arena full of people it’s not uncommon for cell towers to get overloaded, or you may be roaming if overseas and don’t want to waste data, or you’re on a moving train with no on board WiFi or if it has one it might not work right. In those cases (and it seems to happen to me a lot) I would’ve preferred that the ticket I received in my email was viewable offline, even if I’d never seen it before. With a data URI, that’s possible. It’s not an entirely contrived use case I don’t think.
Could you not register a URI format with the mobile OS to open an IttyBitty reader app that contains the rendering scripts?
Sure, initially that means only users who've noticed it would be able to benefit, but the app would be generic, not vendor-specific, so over time, it could become a standard & make it into the OS, at which point it becomes properly useful.
Edit: (sorry, I appear to have been rate-limited)
In reply to @mstated below:
---
Only really that itty bitty's compressed in the URL, not in the transport (& could be extended to add encryption).
It's absolutely true that, that may be tackling the wrong area - if data: were extended with compression/encryption options (not that itty bitty has encryption, but it's an option with the JS layer there) then the itty bitty decoder has nothing to do.
BUT, experiments like itty bitty might spur on ideas & standards changes for things like data: which to me makes it worthwhile.
(Self-contained, standardised, compressed [, encryptable?] content objects [in this case URL] renderable via ubiquitous web technologies feels like a win, itty bitty or not)
---
Also, if links are shared on html-based platforms, some block data: url's in links. Not sure of the justification, but reddit doesn't seem to render markdown formatted URLs with data: on them, as links. Not sure how to tackle that one - itty bitty sidesteps the restriction.
Why? The `data:` schema is already there and is well supported across platforms. All itty bitty does is take the base64 encoded fragment part of the URL and put it in an iframe, wrapping it in the `data:` scheme. No need to register anything new.
Only really that itty bitty's compressed in the URL, not in the transport (& could be extended to add encryption).
It's absolutely true that, that may be tackling the wrong area - if data: were extended with compression/encryption options (not that itty bitty has encryption, but it's an option with the JS layer there) then the itty bitty decoder has nothing to do.
BUT, experiments like itty bitty might spur on ideas & standards changes for things like data: which to me makes it worthwhile.
(Self-contained, standardised, compressed [, encryptable?] content objects [in this case URL] renderable via ubiquitous web technologies feels like a win, itty bitty or not)
---
Also, if links are shared on html-based platforms, some block data: url's in links. Not sure of the justification, but reddit doesn't seem to render markdown formatted URLs with data: on them, as links. Not sure how to tackle that one - itty bitty sidesteps the restriction.
So rather than paste the text.. Paste the link, which they then open, to fetch the render-Middleware from this site, to render the text in the browser? Rather than just allowing the message app render the text in-line or as an attachement?
Could you not put an encryption layer into a derrivative of this for some generic PGP end to end encryption, without involving/trusting a centralised provider..?
It is smaller then data urls becausde the base HTML and javascript is provided by the itty.bitty server and not part of the data url. Only the inner content is encoded. So it is much smaller then a data url but requires a server to serve the initial decoding HTML page.
The base HTML/javascript coming from the itty.bitty server does not make it smaller. As a matter of fact, it appears that the javascript provided by itty.bitty simply decompresses the URL fragment and then converts it into a data-URI and passes that to an iframe.
So it is smaller than a data URI - but only because it is compressed.
That's cool, I hadn't come across hashify before, but I'm not sure about "better" overall - depends how you're using it...
...itsy bitsy site's demo page gives a couple of nice additions
* I use markdown a Lot, but the inclusion of codepen.io makes it simple to compose richer docs, including svg's in a page etc. (I haven't read the hashify code - I'm assuming it does support full HTML, not just MD, but the demo doesn't make that clear)
* QR code link - is just using a 3rd party zXing tool, but, nice touch for the demo
* Compression - hashify URLs seem to be longer than the content (that might mean lower effective limits on content lent), relying on 3rd party lookups for shortening, meaning accessingv the content offline looks harder to achieve (afaict itty bitty just needs the JS to decode the url)
huh. I know a lot of early buffer overflows came via the URL back in the early 2000s and early IE days. I can understand why there shouldn't be a theoretical limit today, at least until your machine would run out of resources. 32GB url anyone?
Even if if just used it for my blog, an attacker can craft a URL which renders obscene content ("Hitler did nothing wrong"), then scatter that link everywhere on the web and get it crawled. Eventually it shows up in searches, but it's definitely "on my domain."
Furthermore, it's like running a public anonymous FTP, it'll just get used as a malware hosting tool as soon as it's found.
I don't follow. I have a Twitter profile. If someone else shares racist stuff on their Twitter profile, is it "on my domain?"
In any case, I'm skeptical that you would ever use this for a blog because the links are immutable. You'd have to either change your homepage every time you updated your blog, or you'd have to dynamically render your homepage in Javascript by querying another server - and if you're gonna do that, what's the point? Just host your own stuff then.
What this gives you is a way to share static content where your entire app/page can be distributed in the url with extremely minimal server interaction. There's no risk of malware or vandalism because there's nothing actually being hosted - the URL is the data. When you share it with someone you know exactly what they're going to see when they click on it.
I can think of a lot of uses I might have for this; even just minor things like sharing quick lists with family members. Updating the URL whenever I changed something would be annoying, but the benefits might outweigh the drawbacks.
Edit: Are you talking about domain forwarding? I could see how that would be problematic. It didn't occur me because I'm not sure what the advantage would be. I don't think I've ever been in a situation where it was too cumbersome for me to host static content somewhere, but not too cumbersome for me to buy a domain and edit its config whenever I published content.
I think that Google does actually wait for Javascript to finish running. I don't think that it indexes URLs with their query params though. Maybe I'm wrong about that.
Not sure why it would be a problem though even if it did - if you've ever hosted content on Instagram, Reddit, Facebook, Twitter, or, heck, even HackerNews, it seems like you'd have the exact same threat model.