Skip to content

Commit

Permalink
Extra stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
timruffles committed Jun 11, 2018
1 parent bd4f902 commit bb1051a
Show file tree
Hide file tree
Showing 12 changed files with 859 additions and 14 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@ Encodes every byte as an emoji in utf8, so 32 bits! 25% efficient.

## Demo

Requires node with ES6 module support.
Requires node >= 10.

Binary file

node base-lol.mjs < targets/max.jpg > max.base-lol
node base-lol.mjs --decode < max.base-lol > max-decoded.jpg
diff targets/max.jpg max-decoded.jpg

Something readable:

ƒ cat targets/smiley.svg
<svg xmlns="http://www.w3.org/2000/svg"><circle fill="#FF0" cx="6" cy="6" r="6"/><circle cx="3" cy="4" r="1"/><circle cx="7" cy="4" r="1"/><path d="M2,6 C2,6 3,12 8,6"/></svg>
ƒ node dist/base-lol.js < targets/smiley.svg
🐼😲😵😦🐠😷😬😫😭😲🐽🐢😧😳😳😯🐺🐯🐯😶😶😶🐮😶🐳🐮😮😱😦🐯🐲🐰🐰🐰🐯😲😵😦🐢🐾🐼😢😨😱😢😫😤🐠😥😨😫😫🐽🐢🐣😅😅🐰🐢🐠😢😷🐽🐢🐶🐢🐠😢😸🐽🐢🐶🐢🐠😱🐽🐢🐶🐢🐯🐾🐼😢😨😱😢😫😤🐠😢😷🐽🐢🐳🐢🐠😢😸🐽🐢🐴🐢🐠😱🐽🐢🐱🐢🐯🐾🐼😢😨😱😢😫😤🐠😢😷🐽🐢🐷🐢🐠😢😸🐽🐢🐴🐢🐠😱🐽🐢🐱🐢🐯🐾🐼😯😠😳😧🐠😣🐽🐢😌🐲🐬🐶🐠😂🐲🐬🐶🐠🐳🐬🐱🐲🐠🐸🐬🐶🐢🐯🐾🐼🐯😲😵😦🐾
ƒ node dist/base-lol.js < targets/smiley.svg | node dist/base-lol.js --decode
<svg xmlns="http://www.w3.org/2000/svg"><circle fill="#FF0" cx="6" cy="6" r="6"/><circle cx="3" cy="4" r="1"/><circle cx="7" cy="4" r="1"/><path d="M2,6 C2,6 3,12 8,6"/></svg>

3 changes: 0 additions & 3 deletions demo-page.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
'use strict';

import { encode, decode, decodeString, encodeString } from './base-lol.mjs';

// wait for document to be completed
document.addEventListener('DOMContentLoaded', main);

function main() {
Expand Down
91 changes: 91 additions & 0 deletions dist/base-lol.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var stream = _interopDefault(require('stream'));
var util = _interopDefault(require('util'));
var fs = _interopDefault(require('fs'));

/**
* - Always encoded as UTF-8 - as efficient as UTF-16 for non-BMP,
* and a good standard
*/

// use the most recognisable emojis for ascii/utf8 text
const asciiTextStart = "😀".codePointAt(0);
const asciiTextEnd = asciiTextStart + 128;

// 256 char run after rat
const lowStart = "🐀".codePointAt(0);
const lowEnd = lowStart + 64;
const highStart = lowEnd + 1;
const highEnd = highStart + 127;

function encode(byte) {
if (byte < 65) {
return String.fromCodePoint(byte + lowStart);
}if (byte >= 128) {
return String.fromCodePoint(byte + highStart - 128);
} else {
// ascii printable
return String.fromCodePoint(asciiTextStart + byte - 65);
}
}

function decode(codePoint) {
if (codePoint >= asciiTextStart && codePoint <= asciiTextEnd) {
return codePoint - asciiTextStart + 65;
} else if (codePoint >= lowStart && codePoint <= lowEnd) {
return codePoint - lowStart;
} else if (codePoint >= highStart && codePoint <= highEnd) {
return codePoint - highStart + 128;
} else {
throw Error(`character out of range '${codePoint}'`);
}
}

const pipeline = util.promisify(stream.pipeline);

const binaryToEmoji = new stream.Transform({
transform(chunk, encoding, callback) {
const asString = [...chunk.values()].map(encode).join('');
callback(null, asString);
}
});

const emojiToBinary = new stream.Transform({
transform(chunk, encoding, callback) {
const init = () => {
this.emoji = {
buffer: Buffer.alloc(4),
index: 0
};
};

if (!this.emoji) {
init();
}

// each emoji is 4 bytes
for (let i = 0; i < chunk.length; i++) {
this.emoji.buffer[this.emoji.index] = chunk[i];
this.emoji.index += 1;
if (this.emoji.index === 4) {
this.push(Buffer.from([decode(this.emoji.buffer.toString('utf8').codePointAt(0))]));
init();
}
}
callback();
}
});

const main = () => {
const stream$$1 = process.argv.some(f => f === '--decode') ? emojiToBinary : binaryToEmoji;

pipeline(process.stdin, stream$$1, fs.createWriteStream('/dev/stdout')).catch(e => {
console.error(e.stack);
process.exit(1);
});
};

main();
92 changes: 92 additions & 0 deletions dist/demo-lol-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
(function (stream,util,fs) {
'use strict';

stream = stream && stream.hasOwnProperty('default') ? stream['default'] : stream;
util = util && util.hasOwnProperty('default') ? util['default'] : util;
fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs;

/**
* - Always encoded as UTF-8 - as efficient as UTF-16 for non-BMP,
* and a good standard
*/

// use the most recognisable emojis for ascii/utf8 text
const asciiTextStart = "😀".codePointAt(0);
const asciiTextEnd = asciiTextStart + 128;

// 256 char run after rat
const lowStart = "🐀".codePointAt(0);
const lowEnd = lowStart + 64;
const highStart = lowEnd + 1;
const highEnd = highStart + 127;

function encode(byte) {
if (byte < 65) {
return String.fromCodePoint(byte + lowStart);
}if (byte >= 128) {
return String.fromCodePoint(byte + highStart - 128);
} else {
// ascii printable
return String.fromCodePoint(asciiTextStart + byte - 65);
}
}

function decode(codePoint) {
if (codePoint >= asciiTextStart && codePoint <= asciiTextEnd) {
return codePoint - asciiTextStart + 65;
} else if (codePoint >= lowStart && codePoint <= lowEnd) {
return codePoint - lowStart;
} else if (codePoint >= highStart && codePoint <= highEnd) {
return codePoint - highStart + 128;
} else {
throw Error(`character out of range '${codePoint}'`);
}
}

const pipeline = util.promisify(stream.pipeline);

const binaryToEmoji = new stream.Transform({
transform(chunk, encoding, callback) {
const asString = [...chunk.values()].map(encode).join('');
callback(null, asString);
}
});

const emojiToBinary = new stream.Transform({
transform(chunk, encoding, callback) {
const init = () => {
this.emoji = {
buffer: Buffer.alloc(4),
index: 0
};
};

if (!this.emoji) {
init();
}

// each emoji is 4 bytes
for (let i = 0; i < chunk.length; i++) {
this.emoji.buffer[this.emoji.index] = chunk[i];
this.emoji.index += 1;
if (this.emoji.index === 4) {
this.push(Buffer.from([decode(this.emoji.buffer.toString('utf8').codePointAt(0))]));
init();
}
}
callback();
}
});

const main = () => {
const stream$$1 = process.argv.some(f => f === '--decode') ? emojiToBinary : binaryToEmoji;

pipeline(process.stdin, stream$$1, fs.createWriteStream('/dev/stdout')).catch(e => {
console.error(e.stack);
process.exit(1);
});
};

main();

}(stream,util,fs));
Loading

0 comments on commit bb1051a

Please sign in to comment.