tdo

Dicing the onion
git clone git@abtrout.com:tdo.git
Log | Files | Refs | README

commit c53dbc278c89a74361f379a21e76fe028686a475
parent eef434e314ef6b71370c426e7e443f19d29b2d2d
Author: david cochran <about.trout@gmail.com>
Date:   Mon, 31 Jan 2022 02:47:35 +0000

add layer2 solution

Diffstat:
Mbitwise.go | 21+++++++++++++++++++++
Mbitwise_test.go | 40++++++++++++++++++++++++++++++++++++++++
Acmd/layer2/decode.go | 25+++++++++++++++++++++++++
3 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/bitwise.go b/bitwise.go @@ -12,3 +12,24 @@ func FlipSecondBits(b byte) byte { func CycleRight(b byte) byte { return (b << 7) | (b >> 1) } + +func ParityCheck(b byte) bool { + p := bits.OnesCount8(b&0b11111110) % 2 + return p == int(b%2) +} + +func PackDataBytes(bs []byte) []byte { + if len(bs)%8 != 0 { + log.Fatalf("Failed to PackDataBytes: input slice of length %d, not a multiple of 8", len(bs)) + } + var out []byte + for i := 0; i < len(bs)/8; i++ { + for j := 0; j < 7; j++ { + k := i*8 + j // index in bs + left := (bs[k] >> 1) << (j + 1) + right := bs[k+1] >> (7 - j) + out = append(out, left|right) + } + } + return out +} diff --git a/bitwise_test.go b/bitwise_test.go @@ -33,3 +33,43 @@ func TestFlipSecondBits(t *testing.T) { } } } + +func TestParityCheck(t *testing.T) { + tests := []struct { + in byte + want bool + }{ + {0b10100011, true}, + {0b10100010, false}, + + {0b11111111, true}, + {0b11111110, false}, + + {0b00000000, true}, + {0b00000001, false}, + } + + for _, test := range tests { + if got := ParityCheck(test.in); got != test.want { + t.Errorf("ParityCheck(%08b) = %t; want %t", test.in, got, test.want) + } + } +} + +func TestPackDataBytes(t *testing.T) { + in := []byte{ + 0b11111110, 0b11111110, 0b11111110, 0b11111110, + 0b11111110, 0b11111110, 0b11111110, 0b11111110, + 0b11111110, 0b11111110, 0b11111110, 0b11111110, + 0b11111110, 0b11111110, 0b11111110, 0b11111110, + } + want := []byte{ + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, 0b11111111, 0b11111111, + 0b11111111, 0b11111111, + } + if got := PackDataBytes(in); !bytes.Equal(got, want) { + t.Errorf("PackDataBytes(%#v) = %#v (len %d); want %#v (len %d)", in, got, len(got), want, len(want)) + } +} diff --git a/cmd/layer2/decode.go b/cmd/layer2/decode.go @@ -0,0 +1,25 @@ +package main + +import ( + "log" + "os" + + "github.com/abtrout/tdo" +) + +func main() { + bs, err := tdo.DecodePipedInput() + if err != nil { + log.Fatalf("Failed to read layer input: %v", err) + } + var filtered []byte + for _, b := range bs { + if tdo.ParityCheck(b) { + filtered = append(filtered, b) + } + } + out := tdo.PackDataBytes(filtered) + if _, err := os.Stdout.Write(out); err != nil { + log.Fatalf("Failed to write decoded output: %v", err) + } +}