Skip to content

Commit 6b5727d

Browse files
committed
fixed
1 parent 2b361fb commit 6b5727d

3 files changed

Lines changed: 195 additions & 1 deletion

File tree

base92/base92.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func NewEncoding(encoder string) *Encoding {
5959
* Encoder
6060
*/
6161

62-
// EncodeToString encodes binary bytes into a Base92 string.
62+
// Encode encodes binary bytes.
6363
func (enc *Encoding) Encode(bin []byte) []byte {
6464
size := len(bin)
6565

chaocipher/chaocipher.go

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package chaocipher
2+
3+
import (
4+
"unsafe"
5+
"reflect"
6+
"errors"
7+
"strings"
8+
"unicode/utf8"
9+
)
10+
11+
const (
12+
lEncodeStd = "HXUCZVAMDSLKPEFJRIGTWOBNYQ"
13+
rEncodeStd = "PTLNBQDEOYSFAVZKGJRIHWXUMC"
14+
)
15+
16+
// StdEncoding is the standard chaocipher encoding.
17+
var StdEncoding = NewEncoding(lEncodeStd, rEncodeStd)
18+
19+
/*
20+
* Encodings
21+
*/
22+
23+
// An Encoding is a radix 62 encoding/decoding scheme, defined by a 62-character alphabet.
24+
type Encoding struct {
25+
lAlphabet string
26+
rAlphabet string
27+
}
28+
29+
// NewEncoding returns a new padded Encoding defined by the given alphabet,
30+
// which must be a 62-byte string that does not contain the padding character
31+
// or CR / LF ('\r', '\n').
32+
func NewEncoding(lAlphabet, rAlphabet string) *Encoding {
33+
if len(lAlphabet) != 26 || len(rAlphabet) != 26 {
34+
panic("go-encoding/chaocipher: encoding alphabet is not 26-bytes long")
35+
}
36+
37+
for i := 0; i < len(lAlphabet); i++ {
38+
if lAlphabet[i] == '\n' || lAlphabet[i] == '\r' {
39+
panic("go-encoding/chaocipher: encoding lAlphabet contains newline character")
40+
}
41+
}
42+
for i := 0; i < len(rAlphabet); i++ {
43+
if rAlphabet[i] == '\n' || rAlphabet[i] == '\r' {
44+
panic("go-encoding/chaocipher: encoding rAlphabet contains newline character")
45+
}
46+
}
47+
48+
e := new(Encoding)
49+
e.lAlphabet = lAlphabet
50+
e.rAlphabet = rAlphabet
51+
52+
return e
53+
}
54+
55+
/*
56+
* Encoder
57+
*/
58+
59+
// Encode encodes src using the encoding enc.
60+
func (enc *Encoding) Encode(src []byte) []byte {
61+
if len(src) == 0 {
62+
return nil
63+
}
64+
65+
dst, err := enc.chao(string(src), true)
66+
if err != nil {
67+
return nil
68+
}
69+
70+
return []byte(dst)
71+
}
72+
73+
// EncodeToString returns the chao encoding of src.
74+
func (enc *Encoding) EncodeToString(src []byte) string {
75+
buf := enc.Encode(src)
76+
return string(buf)
77+
}
78+
79+
/*
80+
* Decoder
81+
*/
82+
83+
// Decode decodes src using the encoding enc.
84+
func (enc *Encoding) Decode(src []byte) ([]byte, error) {
85+
if len(src) == 0 {
86+
return nil, nil
87+
}
88+
89+
dst, err := enc.chao(string(src), false)
90+
if err != nil {
91+
return nil, err
92+
}
93+
94+
return []byte(dst), nil
95+
}
96+
97+
// DecodeString returns the bytes represented by the chao string s.
98+
func (enc *Encoding) DecodeString(s string) ([]byte, error) {
99+
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
100+
bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
101+
return enc.Decode(*(*[]byte)(unsafe.Pointer(&bh)))
102+
}
103+
104+
func (enc *Encoding) chao(text string, encrypt bool) (string, error) {
105+
len := len(text)
106+
if utf8.RuneCountInString(text) != len {
107+
return "", errors.New("go-cryptobin/chaocipher: Text contains non-ASCII characters")
108+
}
109+
110+
left := enc.lAlphabet
111+
right := enc.rAlphabet
112+
113+
eText := make([]byte, len)
114+
temp := make([]byte, 26)
115+
116+
for i := 0; i < len; i++ {
117+
var index int
118+
if encrypt {
119+
index = strings.IndexByte(right, text[i])
120+
eText[i] = left[index]
121+
} else {
122+
index = strings.IndexByte(left, text[i])
123+
eText[i] = right[index]
124+
}
125+
126+
if i == len-1 {
127+
break
128+
}
129+
130+
for j := index; j < 26; j++ {
131+
temp[j-index] = left[j]
132+
}
133+
for j := 0; j < index; j++ {
134+
temp[26-index+j] = left[j]
135+
}
136+
137+
store := temp[1]
138+
for j := 2; j < 14; j++ {
139+
temp[j-1] = temp[j]
140+
}
141+
142+
temp[13] = store
143+
left = string(temp[:])
144+
145+
for j := index; j < 26; j++ {
146+
temp[j-index] = right[j]
147+
}
148+
for j := 0; j < index; j++ {
149+
temp[26-index+j] = right[j]
150+
}
151+
152+
store = temp[0]
153+
for j := 1; j < 26; j++ {
154+
temp[j-1] = temp[j]
155+
}
156+
157+
temp[25] = store
158+
store = temp[2]
159+
for j := 3; j < 14; j++ {
160+
temp[j-1] = temp[j]
161+
}
162+
163+
temp[13] = store
164+
right = string(temp[:])
165+
}
166+
167+
return string(eText[:]), nil
168+
}

chaocipher/chaocipher_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package chaocipher
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func Test_Check(t *testing.T) {
8+
ciphertext := "OAHQHCNYNXTSZJRRHJBYHQKSOUJY"
9+
plaintext := "WELLDONEISBETTERTHANWELLSAID"
10+
11+
encoded := StdEncoding.EncodeToString([]byte(plaintext))
12+
if ciphertext != encoded {
13+
t.Errorf("Encrypt error: act=%s, old=%s\n", encoded, ciphertext)
14+
}
15+
16+
// ==========
17+
18+
decoded, err := StdEncoding.DecodeString(ciphertext)
19+
if err != nil {
20+
t.Fatal(err)
21+
}
22+
23+
if plaintext != string(decoded) {
24+
t.Errorf("Decrypt error: act=%s, old=%s\n", string(decoded), plaintext)
25+
}
26+
}

0 commit comments

Comments
 (0)