yijing: initial commit, encoding only
This commit is contained in:
commit
e556a9624c
7
yijing/README.md
Normal file
7
yijing/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
A sha256 digest in hex
|
||||||
|
|
||||||
|
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852
|
||||||
|
|
||||||
|
A sha256 digest in git status in Yi Jing
|
||||||
|
|
||||||
|
䷸䷻䷌䷄䷐䷩䷯䷼䷇䷁䷙䷚䷾䷿䷜䷈䷦䷖䷿䷹䷉䷂䷞䷮䷐䷞䷖䷤䷦䷹䷌䷌䷩䷉䷝䷙䷆䷷䷥䷒䷮䷅☲¦
|
110
yijing/yijing.go
Normal file
110
yijing/yijing.go
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
// Copyright 2014 Emery Hemingway. All rights reserved.
|
||||||
|
// Use of this source code is governed by the GPLv3+.
|
||||||
|
|
||||||
|
// Package yijing64 implements radix 64 Yijing encoding and decoding.
|
||||||
|
package yijing
|
||||||
|
|
||||||
|
// ䷀ 0xE4 0xB7 0x80
|
||||||
|
// ䷿ 0xE4 0xB7 0xBF
|
||||||
|
|
||||||
|
// ☰ 0xE2 0x98 0xb0
|
||||||
|
// ☷ 0xE2 0x98 0xb8
|
||||||
|
|
||||||
|
// ǀ 0xC7 0x80
|
||||||
|
// ¦ 0xC2 0xa6
|
||||||
|
|
||||||
|
// full block is 0xE2, 0x96, 0x88
|
||||||
|
|
||||||
|
// EncodedLen returns the length of an encoding of n source bytes.
|
||||||
|
func EncodedLen(n int) (l int) {
|
||||||
|
if n == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
l = ((n * 4) / 3) * 3
|
||||||
|
|
||||||
|
switch n % 3 {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
l += 4
|
||||||
|
case 2:
|
||||||
|
l += 5
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode encodes src into EncodedLen(len(src))
|
||||||
|
// bytes of dst. As a convenience, it returns the number
|
||||||
|
// of bytes written to dst, but this value is always EncodedLen(len(src)).
|
||||||
|
// Encode implements Yi Jing encoding.
|
||||||
|
func Encode(dst, src []byte) (n int) {
|
||||||
|
for len(src) > 0 {
|
||||||
|
dst[0] = 0xE4
|
||||||
|
dst[1] = 0xB7
|
||||||
|
dst[2] = 0x80 | (src[0] >> 2)
|
||||||
|
|
||||||
|
switch len(src) {
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
dst[3] = 0xE4
|
||||||
|
dst[4] = 0xB7
|
||||||
|
dst[5] = 0x80 | ((src[0] & 0x03) << 4) | (src[1] >> 4)
|
||||||
|
|
||||||
|
dst[6] = 0xE2
|
||||||
|
dst[7] = 0x98
|
||||||
|
dst[8] = 0xB0 | ((src[1] & 0x0F) >> 1)
|
||||||
|
|
||||||
|
if (src[1] & 0xFE) == 0 {
|
||||||
|
dst[9] = 0xC7
|
||||||
|
dst[10] = 0x80
|
||||||
|
} else {
|
||||||
|
dst[9] = 0xC2
|
||||||
|
dst[10] = 0xA6
|
||||||
|
}
|
||||||
|
return n + 11
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (src[0] & 0x02) == 0 {
|
||||||
|
dst[3] = 0xC7
|
||||||
|
dst[4] = 0x80
|
||||||
|
} else {
|
||||||
|
dst[3] = 0xC2
|
||||||
|
dst[4] = 0xA6
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src[0] & 0x01) == 0 {
|
||||||
|
dst[5] = 0xC7
|
||||||
|
dst[6] = 0x80
|
||||||
|
} else {
|
||||||
|
dst[5] = 0xC2
|
||||||
|
dst[6] = 0xA6
|
||||||
|
}
|
||||||
|
return n + 7
|
||||||
|
}
|
||||||
|
|
||||||
|
dst[3] = 0xE4
|
||||||
|
dst[4] = 0xB7
|
||||||
|
dst[5] = 0x80 | ((src[0] & 0x03) << 4) | (src[1] >> 4)
|
||||||
|
|
||||||
|
dst[6] = 0xE4
|
||||||
|
dst[7] = 0xB7
|
||||||
|
dst[8] = 0x80 | ((src[1] & 0x0F) << 2) | (src[2] >> 4)
|
||||||
|
|
||||||
|
dst[9] = 0xE4
|
||||||
|
dst[10] = 0xB7
|
||||||
|
dst[11] = 0x80 | (src[2] & 0x3F)
|
||||||
|
|
||||||
|
n += 12
|
||||||
|
|
||||||
|
src = src[3:]
|
||||||
|
dst = dst[12:]
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeToString returns the Yi Jing encoding of src.
|
||||||
|
func EncodeToString(src []byte) string {
|
||||||
|
dst := make([]byte, EncodedLen(len(src)))
|
||||||
|
Encode(dst, src)
|
||||||
|
return string(dst)
|
||||||
|
}
|
54
yijing/yijing_test.go
Normal file
54
yijing/yijing_test.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package yijing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type encDecTest struct {
|
||||||
|
enc string
|
||||||
|
dec []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
var encDecTests = []encDecTest{
|
||||||
|
{"", []byte{}},
|
||||||
|
{"䷀ǀǀ", []byte{0x00}},
|
||||||
|
{"䷿¦¦", []byte{0xFF}},
|
||||||
|
{"䷀䷀☰ǀ", []byte{0x00, 0x00}},
|
||||||
|
{"䷿䷿☷¦", []byte{0xFF, 0xFF}},
|
||||||
|
{"䷀䷀䷀䷀", []byte{0x00, 0x00, 0x00}},
|
||||||
|
{"䷕䷕䷕䷕", []byte{0x55, 0x55, 0x55}},
|
||||||
|
{"䷪䷪䷪䷪", []byte{0xAA, 0xAA, 0xAA}},
|
||||||
|
{"䷿䷿䷿䷿", []byte{0xFF, 0xFF, 0xFF}},
|
||||||
|
{"䷀䷀䷀䷀䷀䷀䷀䷀", []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||||
|
{"䷿䷿䷿䷿䷿䷿䷿䷿", []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncode(t *testing.T) {
|
||||||
|
for i, test := range encDecTests {
|
||||||
|
dst := make([]byte, EncodedLen(len(test.dec)))
|
||||||
|
n := Encode(dst, test.dec)
|
||||||
|
if n != len(dst) {
|
||||||
|
t.Errorf("#%d: bad return value: got: %d want: %d", i, n, len(dst))
|
||||||
|
}
|
||||||
|
if string(dst) != test.enc {
|
||||||
|
t.Errorf("#%d: got: %q want: %q", i, dst, test.enc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkEncode(b *testing.B) {
|
||||||
|
var c byte
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
srcBuf := make([]byte, 27)
|
||||||
|
dstBuf := make([]byte, EncodedLen(27))
|
||||||
|
for l := 0; l < 28; l++ {
|
||||||
|
src := srcBuf[:l]
|
||||||
|
for ; c < 255; c++ {
|
||||||
|
for j := 0; j < l; j++ {
|
||||||
|
src[j] = c
|
||||||
|
Encode(dstBuf, src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user