package nu.marginalia.bbpc; public class BrailleBlockPunchCards { private static final char brailleBlockBase = '\u2800'; public static String printBits(long val, int bits) { StringBuilder builder = new StringBuilder(); for (int b = 0; b < bits; b+=8, val>>>=8) { builder.append((char)(brailleBlockBase + bin2brail(val))); } return builder.toString(); } /* The braille block in unicode U2800 is neat because it contains * 8 "bits", but for historical reasons, they're addressed in a bit * of an awkward way. Braille used to be a 2x6 grid, but it was extended * to 2x8. * It's addressed as follows * * 0 3 * 1 4 * 2 5 * 6 7 <-- extended braille * * * We want to use it as a dot matrix to represent bits. To do that we need * to do this transformation: * * 0 1 2 3 4 5 6 7 native order bits * | | | \ _\__\/ | * | | | / \ \ \ | * 0 1 2 6 3 4 5 7 braille order bits * * 01 02 04 08 10 20 40 80 * 01+02+04 +80 : &0x87 * << 10+20+40 : &0x70, <<1 * 08 >> >> >> : &0x08, >>3 * * Or in other words we do * (v & 0x87) * | ((v & 0x70) >> 1) * | ((v & 0x08) << 3) * * Thanks for coming to my TED talk. */ private static char bin2brail(long v) { return (char)((v & 0x87) | ((v & 0x70) >> 1) | ((v & 0x08) << 3)); } }