Base32 Encoder probably works

This commit is contained in:
Netscape Navigator 2020-08-17 07:55:12 -05:00
parent 161cc8924d
commit 4a57024bab
3 changed files with 205 additions and 1 deletions

1
.gitignore vendored
View File

@ -1,3 +1,2 @@
pigeon
pigeon-cli
*scratchpad*

139
pigeon/util.go Normal file
View File

@ -0,0 +1,139 @@
package pigeon
import (
"bytes"
"crypto/ed25519"
"encoding/binary"
"fmt"
"os"
"strings"
"github.com/richardlehane/crock32"
)
// Version is the current version of Pigeon CLI
const Version = "0.0.0"
// CreateKeypair makes a new ED25519 key pair. Just a thin
// wrapper around crypto/ed25519.
func CreateKeypair() (ed25519.PublicKey, ed25519.PrivateKey) {
pub, priv, err := ed25519.GenerateKey(nil)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return pub, priv
}
var decodeTable = map[uint16]rune{
0b00000: '0',
0b00001: '1',
0b00010: '2',
0b00011: '3',
0b00100: '4',
0b00101: '5',
0b00110: '6',
0b00111: '7',
0b01000: '8',
0b01001: '9',
0b01010: 'A',
0b01011: 'B',
0b01100: 'C',
0b01101: 'D',
0b01110: 'E',
0b01111: 'F',
0b10000: 'G',
0b10001: 'H',
0b10010: 'J',
0b10011: 'K',
0b10100: 'M',
0b10101: 'N',
0b10110: 'P',
0b10111: 'Q',
0b11000: 'R',
0b11001: 'S',
0b11010: 'T',
0b11011: 'V',
0b11100: 'W',
0b11101: 'X',
0b11110: 'Y',
0b11111: 'Z',
}
// GetNthBase32Char retrieves the Crockford base 32 character
// at a particular index
func GetNthBase32Char(n uint16, data []byte) rune {
// TODO: Validate that `len(data)` is smaller than uint16
// max
length := uint16(len(data))
startingBit := n * 5
startingByte := startingBit / 8
lShift := startingBit % 8
byte1 := data[startingByte]
var byte2 byte
if (n + 1) > length {
byte2 = 0b00000000
} else {
byte2 = data[startingByte+1]
}
chunk := binary.BigEndian.Uint16([]byte{byte1, byte2})
return decodeTable[(chunk<<lShift)>>11]
}
// ExtractNthPentad returns the base32 string for the nth handful
// of a *[]byte array. A handful represents 5 bits.
// 0.upto(255){|n| puts "Pentad ##{n} starts at byte #{n / 8}, lShift #{n.remainder(8)}"}
func ExtractNthPentad(n uint16, data []byte) rune {
// start := n / 8
// lShift := 8 * 5
// byte1 := data[start]
// length := uint16(len(data)) - 1
// var byte2 byte
// if (n + 1) > length {
// byte2 = 0b00000000
// } else {
// byte2 = data[start+1]
// }
// twoBytes := binary.BigEndian.Uint16([]byte{byte1, byte2})
// shiftedLeft := twoBytes << lShift
// pentad := int(shiftedLeft >> (16 - 5))
// fmt.Printf(`
// start %d
// lShift %d
// byte1 %b
// length %d
// byte2 %b
// twoBytes %b
// shiftedLeft %b
// pentad %b
// `, start, lShift, byte1, length, byte2, twoBytes, shiftedLeft, pentad)
// return decodeTable[pentad]
return '?'
}
// B32Encode converts a byte array into a Crockford Base 32
// string.
func B32Encode(data []byte) string {
fmt.Println("==========")
var b bytes.Buffer
length := len(data)
passes := length / 8
for i := 0; i < passes; i++ {
start := (i * 8)
end := start + 8
slice := data[start:end]
int64 := binary.BigEndian.Uint64(slice)
str := strings.ToUpper(crock32.Encode(int64))
fmt.Printf("Chunk %d is %s\n", i, str)
b.WriteString(str)
}
return b.String()
}
// B32Decode takes a Crockford Base32 string and converts it
// to a byte array.
func B32Decode(input string) []byte {
return []byte("WIP")
}

66
pigeon/util_test.go Normal file
View File

@ -0,0 +1,66 @@
package pigeon
import (
"fmt"
"testing"
)
type testCase struct {
decoded []byte
encoded string
}
var tests = []testCase{
testCase{
decoded: []byte{59, 73, 66, 126, 252, 150, 123, 166, 113, 107, 198, 52, 255, 236, 72, 112, 9, 146, 232, 12, 69, 165, 210, 202, 156, 63, 51, 62, 106, 207, 182, 107},
encoded: "7D4M4ZQWJSXTCWBBRRTFZV28E04S5T0C8PJX5JMW7WSKWTPFPSNG",
},
testCase{
decoded: []byte{143, 151, 30, 105, 79, 74, 193, 242, 224, 97, 106, 227, 223, 99, 236, 225, 145, 236, 152, 143, 230, 159, 247, 50, 72, 147, 217, 248, 255, 67, 126, 116},
encoded: "HYBHWTAF9B0Z5R31DBHXYRZCW68YS64FWTFZECJ8JFCZHZT3FST0",
},
testCase{
decoded: []byte{100, 138, 58, 29, 215, 203, 249, 249, 62, 224, 216, 70, 191, 13, 224, 150, 174, 81, 39, 125, 64, 93, 9, 192, 175, 93, 64, 75, 181, 93, 81, 22},
encoded: "CJ53M7EQSFWZJFQ0V13BY3F0JTQ529VX81EGKG5FBN04QDAXA4B0",
},
testCase{
decoded: []byte{145, 30, 158, 33, 248, 234, 78, 70, 108, 212, 167, 42, 151, 249, 37, 177, 36, 250, 110, 73, 89, 241, 190, 70, 7, 142, 119, 158, 15, 232, 228, 115},
encoded: "J4F9W8FRX974CV6MMWN9FY95P4JFMVJ9B7RVWHG7HSVSW3Z8WHSG",
},
testCase{
decoded: []byte{37, 190, 191, 20, 201, 161, 145, 108, 193, 112, 198, 34, 70, 92, 202, 167, 162, 124, 60, 25, 10, 67, 41, 140, 96, 103, 124, 71, 72, 191, 144, 0},
encoded: "4PZBY569M68PSGBGRRH4CQ6AMYH7RF0S191JK330CXY4EJ5ZJ000",
},
testCase{
decoded: []byte{233, 132, 69, 72, 63, 230, 64, 151, 188, 152, 73, 210, 186, 131, 153, 16, 14, 45, 110, 197, 208, 121, 102, 71, 232, 141, 240, 85, 238, 138, 91, 47},
encoded: "X624AJ1ZWS09FF4R979BN0WS2072TVP5T1WPCHZ8HQR5BVMABCQG",
},
testCase{
decoded: []byte{70, 145, 156, 235, 127, 126, 254, 123, 13, 86, 173, 10, 182, 10, 39, 151, 200, 255, 56, 48, 38, 61, 155, 72, 1, 117, 232, 111, 145, 93, 184, 104},
encoded: "8T8SSTVZFVZ7P3APNM5BC2H7JZ4FYE1G4RYSPJ01EQM6Z4AXQ1M0",
},
testCase{
decoded: []byte{40, 63, 195, 179, 116, 218, 206, 16, 126, 171, 14, 202, 210, 155, 187, 6, 117, 172, 181, 137, 46, 251, 109, 24, 107, 252, 33, 95, 206, 56, 31, 26},
encoded: "50ZW7CVMVB710ZNB1V5D56XV0STTSDC95VXPT63BZGGNZKHR3WD0",
},
testCase{
decoded: []byte{16, 249, 237, 62, 116, 10, 80, 20, 123, 50, 75, 103, 228, 127, 214, 26, 199, 49, 83, 34, 66, 24, 242, 155, 240, 60, 18, 25, 205, 187, 156, 76},
encoded: "23WYTFKM19818YSJ9DKY8ZYP3B3K2MS288CF56ZG7G91KKDVKH60",
},
testCase{
decoded: []byte{233, 110, 203, 25, 190, 221, 178, 24, 29, 138, 26, 65, 46, 246, 187, 122, 92, 164, 70, 199, 71, 11, 113, 163, 218, 251, 157, 151, 127, 152, 213, 192},
encoded: "X5QCP6DYVPS1G7CA390JXXNVF9EA8HP78W5Q38YTZEESEZWRTQ00",
},
}
func TestGetNthBase32Char(t *testing.T) {
fmt.Println("What we want:")
fmt.Println(tests[1].encoded)
hmm := tests[1].decoded
count := 10 // (len(hmm) * 8) / 5
for i := 0; i < count; i++ {
result := GetNthBase32Char(uint16(i), hmm)
fmt.Printf("%s", string(result))
}
fmt.Println("\n====")
}