# Exercise: text as Unicode clock faces

[2017-03-15]

In this blog post, we explore how arbitrary ASCII text can be encoded as Unicode clock faces:

``````> clocksToPlain('🕔🕘🕖🕕🕖🕜🕖🕜🕖🕟🕒🕑')
'Hello!'
``````

I’m explaining ideas by Maggie Pint and @FakeUnicode.

## Unicode clock faces  #

The following times are available as clock faces in Unicode:

• Full hours:
• CLOCK FACE ONE OCLOCK (U+1F550): 🕐
• CLOCK FACE TWO OCLOCK (U+1F551): 🕑
• ···
• CLOCK FACE TWELVE OCLOCK (U+1F55B): 🕛
• Half-hours:
• CLOCK FACE ONE-THIRTY (U+1F55C): 🕜
• CLOCK FACE TWO-THIRTY (U+1F55D): 🕝
• ···
• CLOCK FACE TWELVE-THIRTY (U+1F567): 🕧

## Interpreting clock faces as Unicode characters  #

The idea is as follows: the clock faces give you hex digits from 0 to F (you get the range 0–7 twice). Therefore, two clocks encode an 8-bit hex number, which can be interpreted as a Unicode character.

If you want to, you can stop reading here and implement `clocksToPlain()` yourself. The next subsection gives you a little help. The subsection after that gives you solutions.

### Encoding and decoding via `escape()` and `unescape()`#

For decoding clock-encoded text, we can get help from `unescape()`:

``````> escape('🕔🕘')
'%uD83D%uDD54%uD83D%uDD58'
``````

You can see that each 21-bit code points is encoded as two 16-bit code units. For example, the code point U+1F554 is encoded as `'%uD83D%uDD54'`:

``````> '\u{D83D}\u{DD54}'
'🕔'
> '\u{D83D}\u{DD54}' === '\u{1F554}'
true
``````

The pair of clocks gives you the two hex digits 4 and 8. Once you have them, you can use `escape()`:

``````> unescape('%48')
'H'
``````

### `clocksToPlain()`#

Thus, a compact way of decoding clock faces is:

``````function clocksToPlain(clocks) {
return unescape(
escape(clocks).replace(/u.{9}(.).{11}/g, '\$1'));
}

console.log(clocksToPlain('🕔🕘🕖🕕🕖🕜🕖🕜🕖🕟🕒🕑'));
// Hello!
``````

A more self-descriptive version looks like this:

``````function clocksToPlain(clocks) {
const digits = [...clocks].map(ch => {
const codePointHex = ch.codePointAt(0).toString(16);
return codePointHex[codePointHex.length-1];
});
return mapTuple(digits, 2, (digitPair) => {
const codePoint = Number.parseInt(digitPair.join(''), 16);
return String.fromCodePoint(codePoint);
}).join('');
}

function mapTuple(arr, tupleSize, func) {
const result = [];
let start = 0;
while (start < arr.length) {
const end = Math.min(arr.length, start + tupleSize);
result.push(func(arr.slice(start, end), start, arr));
start = end;
}
return result;
}

console.log(clocksToPlain('🕔🕘🕖🕕🕖🕜🕖🕜🕖🕟🕒🕑'));
// Hello!
``````

Alternatively, you can use `String.prototype.match()` to group characters, but I liked the more universal `mapTuple()`.

``````> 'abcde'.match(/../g)
[ 'ab', 'cd' ]
``````

## Encoding text as clock faces  #

If you want to produce clock text, you can use the following function.

``````function plainToClocks(plain) {
return [...plain].map(ch => {
const MAX_DIGITS = 6;
const hexCode = ch.codePointAt(0).toString(16)
// We are assuming that ch.codePointAt(0) < 256
return digitToClock(hexCode)+digitToClock(hexCode);
}).join('');
}

function digitToClock(hexDigit) {
const codePoint = Number.parseInt('1F55'+hexDigit, 16);
return String.fromCodePoint(codePoint);
}

console.log(plainToClocks('Hello!'));
// 🕔🕘🕖🕕🕖🕜🕖🕜🕖🕟🕒🕑
``````

I’m using the spread operator (`...`) to split the string `plain` into code units.