Skip to content

Instantly share code, notes, and snippets.

@kylepls
Created May 27, 2023 21:36
Show Gist options
  • Save kylepls/769cfc2f65dce5b973ab547e46cecf3a to your computer and use it in GitHub Desktop.
Save kylepls/769cfc2f65dce5b973ab547e46cecf3a to your computer and use it in GitHub Desktop.
PsAndQs Encoder
import java.io.*;
import java.nio.charset.StandardCharsets;
/**
* Encode streams into Ps and Qs.
* Why? Because it's mannerly.
* P = 0
* Q = 1
*/
public class PsAndQs {
public static void main(String[] args) throws IOException {
String inputText = "hello world";
System.out.printf("Encoding: %s%n", inputText);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PsAndQs.EncoderStream out = new PsAndQs.EncoderStream(baos);
out.write(inputText.getBytes(StandardCharsets.UTF_8));
String encoded = baos.toString();
System.out.printf("Encoded Text: %s%n", encoded);
PsAndQs.DecoderStream decoderStream = new PsAndQs.DecoderStream(new ByteArrayInputStream(encoded.getBytes(StandardCharsets.UTF_8)));
System.out.printf("Decoded: %s%n", new String(decoderStream.readAllBytes()));
}
private static final byte[] BIT_MASKS =
new byte[]{0b1000000, 0b1000000, 0b100000, 0b10000, 0b1000, 0b100, 0b10, 0b1};
public static class EncoderStream extends FilterOutputStream {
protected EncoderStream(OutputStream out) {
super(out);
}
@Override
public void write(int b) throws IOException {
for (byte mask : BIT_MASKS) {
if ((b & mask) == mask) {
out.write('q');
} else {
out.write('p');
}
}
}
}
public static class DecoderStream extends FilterInputStream {
private boolean eos;
private boolean closed;
public DecoderStream(InputStream in) {
super(in);
}
@Override
public void close() throws IOException {
if (!closed) {
super.close();
closed = true;
eos = true;
}
}
@Override
public int read() throws IOException {
ensureOpen();
byte read = readByte();
if (eos) {
return -1;
} else {
return read;
}
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (eos) {
return -1;
}
int i = off;
int v;
while (i < off + len && (v = read()) != -1) {
b[i] = (byte) v;
i++;
}
return i - off;
}
private void ensureOpen() throws IOException {
if (closed) {
throw new IOException("Stream closed");
}
}
private byte readByte() throws IOException {
byte value = 0;
for (int i = 0; i < 8; i++) {
int read = in.read();
if (read == 'q') {
value |= BIT_MASKS[i];
} else if (read == 'p') {
// empty
} else if (read == -1) {
eos = true;
} else {
throw new IllegalArgumentException("Invalid character " + read);
}
}
return value;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment