├── LICENSE
├── README.md
├── README_CN.md
├── base100
├── base100.go
└── base100_test.go
├── base36
├── base36.go
└── base36_test.go
├── base45
├── base45.go
└── base45_test.go
├── base58
├── base58.go
├── base58_test.go
└── base58check.go
├── base62
├── base62.go
└── base62_test.go
├── base91
├── base91.go
└── base91_test.go
├── base92
├── base92.go
└── base92_test.go
├── baseenc
├── baseenc.go
└── baseenc_test.go
├── basex
├── basex.go
└── basex_test.go
├── bcd
├── bcd.go
├── bcd8421
│ ├── bcd.go
│ ├── bcd8421.go
│ ├── bcd8421_test.go
│ └── bcd_test.go
└── bcd_test.go
├── chaocipher
├── chaocipher.go
└── chaocipher_test.go
├── encoding
├── asn1.go
├── asn1_test.go
├── base100.go
├── base100_test.go
├── base32.go
├── base32_test.go
├── base36.go
├── base36_test.go
├── base45.go
├── base45_test.go
├── base58.go
├── base58_test.go
├── base62.go
├── base62_test.go
├── base64.go
├── base64_test.go
├── base85.go
├── base85_test.go
├── base91.go
├── base91_test.go
├── base92.go
├── base92_test.go
├── basex.go
├── basex_test.go
├── binary.go
├── binary_test.go
├── convert.go
├── csv.go
├── csv_test.go
├── data_set.go
├── encoding.go
├── encoding_from.go
├── encoding_test.go
├── encoding_to.go
├── encoding_use.go
├── encoding_use_test.go
├── gob.go
├── gob_test.go
├── hex.go
├── hex_test.go
├── json.go
├── json_test.go
├── morse.go
├── morse_test.go
├── puny.go
├── puny_test.go
├── quotedprintable.go
├── quotedprintable_test.go
├── safe_url.go
├── safe_url_test.go
├── serialize.go
├── serialize_test.go
├── xml.go
└── xml_test.go
├── example.md
├── go.mod
├── go.sum
├── leb128
├── leb128.go
└── leb128_test.go
├── logo.png
├── morse
├── morse.go
└── morse_test.go
├── puny
├── puny.go
├── puny_test.go
└── utils.go
└── quotedprintable
├── quotedprintable.go
├── quotedprintable_test.go
└── utils.go
/README.md:
--------------------------------------------------------------------------------
1 | ## go-encoding
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | [中文](README_CN.md) | English
10 |
11 |
12 | ### Desc
13 |
14 | * data encoding/decoding pkg
15 | * encodings has some (Hex/Base32/Base36/Base45/Base58/Base62/Base64/Base85/Base91/Base92/Base100/MorseITU/JSON)
16 |
17 |
18 | ### Download
19 |
20 | ~~~go
21 | go get -u github.com/deatil/go-encoding
22 | ~~~
23 |
24 |
25 | ### Get Starting
26 |
27 | ~~~go
28 | package main
29 |
30 | import (
31 | "fmt"
32 | "github.com/deatil/go-encoding/encoding"
33 | )
34 |
35 | func main() {
36 | oldData := "useData"
37 |
38 | // Base64 Encode
39 | base64Data := encoding.
40 | FromString(oldData).
41 | Base64Encode().
42 | ToString()
43 | fmt.Println("Base64 Encoded:", base64Data)
44 |
45 | // Base64 Decode
46 | base64DecodeData := encoding.
47 | FromString(base64Data).
48 | Base64Decode().
49 | ToString()
50 | fmt.Println("Base64 Decoded:", base64DecodeData)
51 | }
52 | ~~~
53 |
54 |
55 | ### Use encoding
56 |
57 | ~~~go
58 | base64Data := encoding.
59 | FromString(oldData). // input data
60 | Base64Encode(). // encoding/decoding type
61 | ToString() // output data
62 | ~~~
63 |
64 |
65 | ### Input and Output
66 |
67 | * Input:
68 | `FromBytes(data []byte)`, `FromString(data string)`, `FromReader(reader io.Reader)`
69 | * Output:
70 | `String() string`, `ToBytes() []byte`, `ToString() string`, `ToReader() io.Reader`
71 |
72 |
73 | ### Encoding Types
74 |
75 | * Decode:
76 | `Base32Encode()`, `Base32RawEncode()`, `Base32HexEncode()`,`Base32RawHexEncode()`, `Base32EncodeWithEncoder(encoder string)`, `Base32RawEncodeWithEncoder(encoder string)`,
77 | `Base45Encode()`,
78 | `Base58Encode()`,
79 | `Base62Encode()`,
80 | `Base64Encode()`, `Base64URLEncode()`, `Base64RawEncode()`, `Base64RawURLEncode()`, `Base64SegmentEncode()`, `Base64EncodeWithEncoder(encoder string)`,
81 | `Base85Encode()`,
82 | `Base91Encode()`,
83 | `Base100Encode()`,
84 | `Basex2Encode()`, `Basex16Encode()`, `Basex62Encode()`, `BasexEncodeWithEncoder(encoder string)`,
85 | `HexEncode()`,
86 | `MorseITUEncode()`,
87 | `SafeURLEncode()`,
88 | `SerializeEncode()`,
89 | `JSONEncode(data any)`, `JSONIteratorEncode(data any)`, `JSONIteratorIndentEncode(v any, prefix, indent string)`,
90 | `GobEncode(data any)`
91 |
92 | * Encode:
93 | `Base32Decode()`, `Base32RawDecode()`, `Base32HexDecode()`,`Base32RawHexDecode()`, `Base32DecodeWithEncoder(encoder string)`, `Base32RawDecodeWithEncoder(encoder string)`,
94 | `Base45Decode()`,
95 | `Base58Decode()`,
96 | `Base62Decode()`,
97 | `Base64Decode()`, `Base64URLDecode()`, `Base64RawDecode()`, `Base64RawURLDecode()`, `Base64SegmentDecode(paddingAllowed ...bool)`, `Base64DecodeWithEncoder(encoder string)`,
98 | `Base85Encode()`,
99 | `Base91Decode()`,
100 | `Base100Decode()`,
101 | `Basex2Decode()`, `Basex16Decode()`, `Basex62Decode()`, `BasexDecodeWithEncoder(encoder string)`,
102 | `HexDecode()`,
103 | `MorseITUDecode()`,
104 | `SafeURLDecode()`,
105 | `SerializeDecode()`,
106 | `JSONDecode(dst any)`, `JSONIteratorDecode(dst any)`,
107 | `GobDecode(dst any)`
108 |
109 |
110 | ### LICENSE
111 |
112 | * The library LICENSE is `Apache2`, using the library need keep the LICENSE.
113 |
114 |
115 | ### Copyright
116 |
117 | * Copyright deatil(https://github.com/deatil).
118 |
--------------------------------------------------------------------------------
/README_CN.md:
--------------------------------------------------------------------------------
1 | ## go-encoding
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 中文 | [English](README.md)
10 |
11 | ### 项目介绍
12 |
13 | * 常用的编码解码算法
14 | * 算法包括: (Hex/Base32/Base36/Base45/Base58/Base62/Base64/Base85/Base91/Base92/Base100/MorseITU/JSON)
15 |
16 |
17 | ### 下载安装
18 |
19 | ~~~go
20 | go get -u github.com/deatil/go-encoding
21 | ~~~
22 |
23 |
24 | ### 开始使用
25 |
26 | ~~~go
27 | package main
28 |
29 | import (
30 | "fmt"
31 | "github.com/deatil/go-encoding/encoding"
32 | )
33 |
34 | func main() {
35 | oldData := "useData"
36 |
37 | // Base64 编码
38 | base64Data := encoding.
39 | FromString(oldData).
40 | Base64Encode().
41 | ToString()
42 | fmt.Println("Base64 编码为:", base64Data)
43 |
44 | // Base64 解码
45 | base64DecodeData := encoding.
46 | FromString(base64Data).
47 | Base64Decode().
48 | ToString()
49 | fmt.Println("Base64 解码为:", base64DecodeData)
50 | }
51 | ~~~
52 |
53 |
54 | ### 格式说明
55 |
56 | ~~~go
57 | base64Data := encoding.
58 | FromString(oldData). // 输入数据
59 | Base64Encode(). // 编码方式/解码方式
60 | ToString() // 输出数据
61 | ~~~
62 |
63 |
64 | ### 输入输出数据
65 |
66 | * 输入数据:
67 | `FromBytes(data []byte)`, `FromString(data string)`, `FromReader(reader io.Reader)`
68 | * 输出数据:
69 | `String() string`, `ToBytes() []byte`, `ToString() string`, `ToReader() io.Reader`
70 |
71 |
72 | ### 常用解码编码
73 |
74 | * 编码方式:
75 | `Base32Encode()`, `Base32RawEncode()`, `Base32HexEncode()`,`Base32RawHexEncode()`, `Base32EncodeWithEncoder(encoder string)`, `Base32RawEncodeWithEncoder(encoder string)`,
76 | `Base45Encode()`,
77 | `Base58Encode()`,
78 | `Base62Encode()`,
79 | `Base64Encode()`, `Base64URLEncode()`, `Base64RawEncode()`, `Base64RawURLEncode()`, `Base64SegmentEncode()`, `Base64EncodeWithEncoder(encoder string)`,
80 | `Base85Encode()`,
81 | `Base91Encode()`,
82 | `Base100Encode()`,
83 | `Basex2Encode()`, `Basex16Encode()`, `Basex62Encode()`, `BasexEncodeWithEncoder(encoder string)`,
84 | `HexEncode()`,
85 | `MorseITUEncode()`,
86 | `SafeURLEncode()`,
87 | `SerializeEncode()`,
88 | `JSONEncode(data any)`, `JSONIteratorEncode(data any)`, `JSONIteratorIndentEncode(v any, prefix, indent string)`,
89 | `GobEncode(data any)`
90 |
91 | * 解码方式:
92 | `Base32Decode()`, `Base32RawDecode()`, `Base32HexDecode()`,`Base32RawHexDecode()`, `Base32DecodeWithEncoder(encoder string)`, `Base32RawDecodeWithEncoder(encoder string)`,
93 | `Base45Decode()`,
94 | `Base58Decode()`,
95 | `Base62Decode()`,
96 | `Base64Decode()`, `Base64URLDecode()`, `Base64RawDecode()`, `Base64RawURLDecode()`, `Base64SegmentDecode(paddingAllowed ...bool)`, `Base64DecodeWithEncoder(encoder string)`,
97 | `Base85Encode()`,
98 | `Base91Decode()`,
99 | `Base100Decode()`,
100 | `Basex2Decode()`, `Basex16Decode()`, `Basex62Decode()`, `BasexDecodeWithEncoder(encoder string)`,
101 | `HexDecode()`,
102 | `MorseITUDecode()`,
103 | `SafeURLDecode()`,
104 | `SerializeDecode()`,
105 | `JSONDecode(dst any)`, `JSONIteratorDecode(dst any)`,
106 | `GobDecode(dst any)`
107 |
108 |
109 | ### 开源协议
110 |
111 | * 本软件包遵循 `Apache2` 开源协议发布,在保留本软件包版权的情况下提供个人及商业免费使用。
112 |
113 |
114 | ### 版权
115 |
116 | * 本软件包所属版权归 deatil(https://github.com/deatil) 所有。
117 |
--------------------------------------------------------------------------------
/base100/base100.go:
--------------------------------------------------------------------------------
1 | package base100
2 |
3 | const (
4 | first = 0xf0
5 | second = 0x9f
6 |
7 | shift = 55
8 | divisor = 64
9 |
10 | third = 0x8f
11 | forth = 0x80
12 | )
13 |
14 | // InvalidInputError is returned when Decode fails
15 | type InvalidInputError struct {
16 | message string
17 | }
18 |
19 | func (e InvalidInputError) Error() string {
20 | return e.message
21 | }
22 |
23 | // ErrInvalidLength is returned when length of string being decoded is
24 | // not divisible by four
25 | var ErrInvalidLength = InvalidInputError{"go-encoding/base100: len(data) should be divisible by 4"}
26 |
27 | // ErrInvalidData is returned if data is not a valid base100 string
28 | var ErrInvalidData = InvalidInputError{"go-encoding/base100: data is invalid"}
29 |
30 | // Encode tranforms bytes into base100 utf-8 encoded string
31 | func Encode(data []byte) string {
32 | result := make([]byte, len(data)*4)
33 | for i, b := range data {
34 | result[i*4+0] = first
35 | result[i*4+1] = second
36 | result[i*4+2] = byte((uint16(b)+shift)/divisor + third)
37 | result[i*4+3] = (b+shift)%divisor + forth
38 | }
39 |
40 | return string(result)
41 | }
42 |
43 | // Decode transforms base100 utf-8 encoded string into bytes
44 | func Decode(data string) ([]byte, error) {
45 | if len(data)%4 != 0 {
46 | return nil, ErrInvalidLength
47 | }
48 |
49 | result := make([]byte, len(data)/4)
50 | for i := 0; i != len(data); i += 4 {
51 | if data[i+0] != first || data[i+1] != second {
52 | return nil, ErrInvalidData
53 | }
54 |
55 | result[i/4] = (data[i+2]-third)*divisor +
56 | data[i+3] - forth - shift
57 | }
58 |
59 | return result, nil
60 | }
61 |
--------------------------------------------------------------------------------
/base100/base100_test.go:
--------------------------------------------------------------------------------
1 | package base100
2 |
3 | import "testing"
4 |
5 | func TestInvalidInput(t *testing.T) {
6 | if _, err := Decode("aaaa"); err != ErrInvalidData {
7 | t.Errorf("Expected ErrInvalidData but got %v", err)
8 | }
9 |
10 | if _, err := Decode("aaa"); err != ErrInvalidLength {
11 | t.Errorf("Expected ErrInvalidLength but got %v", err)
12 | }
13 | }
14 |
15 | func TestCoverError(t *testing.T) {
16 | const message = "are you happy now, code coverage?"
17 | err := InvalidInputError{message}
18 | if err.Error() != message {
19 | t.Errorf("(InvalidInputError).Error(): Expected %v, got %v", message, err.Error())
20 | }
21 | }
22 |
23 | var tests = []struct {
24 | name string
25 | text string
26 | emoji string
27 | }{
28 | {
29 | "ASCII",
30 | "hello",
31 | "👟👜👣👣👦",
32 | },
33 | {
34 | "Cyrillic",
35 | "РАШ Бэ",
36 | "📇💗📇💇📇💟🐗📇💈📈💄",
37 | },
38 | {
39 | "HelloUnicode",
40 | "Hello, 世界",
41 | "🐿👜👣👣👦🐣🐗📛💯💍📞💌💃",
42 | },
43 | }
44 |
45 | func TestDecode(t *testing.T) {
46 | for _, test := range tests {
47 | res, err := Decode(test.emoji)
48 | if err != nil {
49 | t.Errorf("%v: Unexpected error: %v", test.name, err)
50 | }
51 |
52 | if string(res) != test.text {
53 | t.Errorf("%v: Expected to get '%v', got '%v'", test.name, test.text, string(res))
54 | }
55 | }
56 | }
57 |
58 | func TestEncode(t *testing.T) {
59 | for _, test := range tests {
60 | res := Encode([]byte(test.text))
61 |
62 | if res != test.emoji {
63 | t.Errorf("%v: Expected to get '%v', got '%v'", test.name, test.emoji, res)
64 | }
65 | }
66 | }
67 |
68 | func TestFlow(t *testing.T) {
69 | text := []byte("the quick brown fox 😂😂👌👌👌 over the lazy dog привет")
70 |
71 | res, err := Decode(Encode(text))
72 |
73 | if err != nil {
74 | t.Errorf("Unexpected error: %v", err)
75 | }
76 |
77 | if string(res) != string(text) {
78 | t.Errorf("Expected to get '%v', got '%v'", string(text), string(res))
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/base36/base36.go:
--------------------------------------------------------------------------------
1 | package base36
2 |
3 | import (
4 | "github.com/deatil/go-encoding/baseenc"
5 | )
6 |
7 | // encodeStd is the standard base36 encoding alphabet
8 | const encodeStd = "0123456789abcdefghijklmnopqrstuvwxyz"
9 |
10 | // StdEncoding is the default encoding enc.
11 | var StdEncoding = NewEncoding(encodeStd)
12 |
13 | /*
14 | * Encodings
15 | */
16 |
17 | // NewEncoding returns a new Encoding defined by the given alphabet, which must
18 | // be a 36-byte string that does not contain CR or LF ('\r', '\n').
19 | func NewEncoding(encoder string) *baseenc.Encoding {
20 | return baseenc.NewEncoding("base36", 36, encoder)
21 | }
22 |
--------------------------------------------------------------------------------
/base36/base36_test.go:
--------------------------------------------------------------------------------
1 | package base36
2 |
3 | import (
4 | "bytes"
5 | "reflect"
6 | "testing"
7 | )
8 |
9 | var cases = []struct {
10 | name string
11 | bin []byte
12 | }{
13 | {"nil", nil},
14 | {"empty", []byte{}},
15 | {"zero", []byte{0}},
16 | {"one", []byte{1}},
17 | {"two", []byte{2}},
18 | {"ten", []byte{10}},
19 | {"2zeros", []byte{0, 0}},
20 | {"2ones", []byte{1, 1}},
21 | {"64zeros", []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
22 | {"65zeros", []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
23 | {"ascii", []byte("c'est une longue chanson")},
24 | {"utf8", []byte("Garçon, un café très fort !")},
25 | }
26 |
27 | func Test_Encode(t *testing.T) {
28 | for _, c := range cases {
29 | t.Run(c.name, func(t *testing.T) {
30 | str := StdEncoding.EncodeToString(c.bin)
31 |
32 | ni := len(c.bin)
33 | if ni > 70 {
34 | ni = 70 // print max the first 70 bytes
35 | }
36 | na := len(str)
37 | if na > 70 {
38 | na = 70 // print max the first 70 characters
39 | }
40 | t.Logf("bin len=%d [:%d]=%v", len(c.bin), ni, c.bin[:ni])
41 | t.Logf("str len=%d [:%d]=%q", len(str), na, str[:na])
42 |
43 | got, err := StdEncoding.DecodeString(str)
44 | if err != nil {
45 | t.Errorf("Decode() error = %v", err)
46 | return
47 | }
48 |
49 | ng := len(got)
50 | if ng > 70 {
51 | ng = 70 // print max the first 70 bytes
52 | }
53 | t.Logf("got len=%d [:%d]=%v", len(got), ng, got[:ng])
54 |
55 | if (len(got) == 0) && (len(c.bin) == 0) {
56 | return
57 | }
58 |
59 | if !reflect.DeepEqual(got, c.bin) {
60 | t.Errorf("Decode() = %v, want %v", got, c.bin)
61 | }
62 | })
63 | }
64 | }
65 |
66 | func Test_Encode2(t *testing.T) {
67 | for _, s := range SamplesStd {
68 | encoded := string(StdEncoding.Encode(s.sourceBytes))
69 | if len(encoded) == len(s.target) && encoded == s.target {
70 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
71 | } else {
72 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), encoded, len(encoded))
73 | }
74 | }
75 | }
76 |
77 | func Test_Decode2(t *testing.T) {
78 | for _, s := range SamplesStd {
79 | decoded, err := StdEncoding.Decode(s.targetBytes)
80 | if err != nil {
81 | t.Error(err)
82 | continue
83 | }
84 |
85 | if bytes.Equal(decoded, s.sourceBytes) {
86 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
87 | } else {
88 | str := string(decoded)
89 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
90 | }
91 | }
92 | }
93 |
94 | func Test_EncodeToString(t *testing.T) {
95 | for _, s := range SamplesStd {
96 | encoded := StdEncoding.EncodeToString([]byte(s.source))
97 | if len(encoded) == len(s.target) && encoded == s.target {
98 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
99 | } else {
100 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), encoded, len(encoded))
101 | }
102 | }
103 | }
104 |
105 | func Test_DecodeString(t *testing.T) {
106 | for _, s := range SamplesStd {
107 | decoded, err := StdEncoding.DecodeString(s.target)
108 | if err != nil {
109 | t.Error(err)
110 | continue
111 | }
112 |
113 | if bytes.Equal(decoded, s.sourceBytes) {
114 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
115 | } else {
116 | str := string(decoded)
117 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
118 | }
119 | }
120 | }
121 |
122 | func Test_EncodeWithCustomAlphabet(t *testing.T) {
123 | for _, s := range SamplesWithAlphabet {
124 | encoded := NewEncoding(s.alphabet).EncodeToString(s.sourceBytes)
125 | if encoded == s.target {
126 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
127 | } else {
128 | str := string(encoded)
129 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), str, len(str))
130 | }
131 | }
132 | }
133 |
134 | func Test_DecodeWithCustomAlphabet(t *testing.T) {
135 | for _, s := range SamplesWithAlphabet {
136 | decoded, err := NewEncoding(s.alphabet).DecodeString(s.target)
137 | if err != nil {
138 | t.Error(err)
139 | continue
140 | }
141 | if bytes.Equal(decoded, s.sourceBytes) {
142 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
143 | } else {
144 | str := string(decoded)
145 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
146 | }
147 | }
148 | }
149 |
150 | func Test_DecodeError(t *testing.T) {
151 | for _, s := range SamplesErr {
152 | decoded, err := StdEncoding.DecodeString(s.target)
153 | if err != nil {
154 | t.Logf("%s: \"%c\"", err.Error(), err)
155 | continue
156 | }
157 |
158 | str := string(decoded)
159 | t.Errorf("An error should have occurred, instead of returning \"%s\"", str)
160 | }
161 | }
162 |
163 | func NewSample(source, target string) *Sample {
164 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target)}
165 | }
166 |
167 | func NewSampleWithAlphabet(source, target, alphabet string) *Sample {
168 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target), alphabet: alphabet}
169 | }
170 |
171 | type Sample struct {
172 | source string
173 | target string
174 | sourceBytes []byte
175 | targetBytes []byte
176 | alphabet string
177 | }
178 |
179 | var SamplesStd = []*Sample{
180 | NewSample("", ""),
181 | NewSample("f", "2u"),
182 | NewSample("fo", "k8f"),
183 | NewSample("foo", "3zvxr"),
184 | NewSample("foob", "sf742q"),
185 | NewSample("fooba", "5m42kzfl"),
186 | NewSample("foobar", "13x8yd7ywi"),
187 |
188 | NewSample("su", "mt1"),
189 | NewSample("sur", "4i6ia"),
190 | NewSample("sure", "w1aa1x"),
191 | NewSample("sure.", "6bt53hny"),
192 | NewSample("asure.", "11zbcm20j2"),
193 | NewSample("easure.", "7sz7l367x2m"),
194 | NewSample("leasure.", "1ncbu0pxvv6em"),
195 |
196 | NewSample("=", "1p"),
197 | NewSample(">", "1q"),
198 | NewSample("?", "1r"),
199 | NewSample("11", "9pt"),
200 | NewSample("111", "1x3jl"),
201 | NewSample("1111", "dnd7ap"),
202 | NewSample("11111", "2p25vw35"),
203 | NewSample("111111", "j67dus6cx"),
204 |
205 | NewSample("Hello, World!", "fg3h7vqw7een6jwwnzmp"),
206 | NewSample("你好,世界!", "j0sguou3jtppn6fagdqrb3kre1z5"),
207 | NewSample("こんにちは", "1w6pjye0qjvyw4xul6ds5jfz"),
208 | NewSample("안녕하십니까", "jo9sbh1ov904nwwy5gosugf1cmfg"),
209 |
210 | NewSample(string([]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}), "0rwg9z1idsugqv3"),
211 | }
212 |
213 | var SamplesWithAlphabet = []*Sample{
214 | NewSampleWithAlphabet("", "", "0123456789ghijklmnopqrstuvwxyzabcdef"),
215 | NewSampleWithAlphabet("f", "2a", "0123456789ghijklmnopqrstuvwxyzabcdef"),
216 | NewSampleWithAlphabet("fo", "q8l", "0123456789ghijklmnopqrstuvwxyzabcdef"),
217 | NewSampleWithAlphabet("foo", "3fbdx", "0123456789ghijklmnopqrstuvwxyzabcdef"),
218 | NewSampleWithAlphabet("foob", "yl742w", "0123456789ghijklmnopqrstuvwxyzabcdef"),
219 | NewSampleWithAlphabet("fooba", "5s42qflr", "0123456789ghijklmnopqrstuvwxyzabcdef"),
220 | NewSampleWithAlphabet("foobar", "13d8ej7eco", "0123456789ghijklmnopqrstuvwxyzabcdef"),
221 |
222 | NewSampleWithAlphabet("su", "sz1", "0123456789ghijklmnopqrstuvwxyzabcdef"),
223 | NewSampleWithAlphabet("sur", "4o6og", "0123456789ghijklmnopqrstuvwxyzabcdef"),
224 | NewSampleWithAlphabet("sure", "c1gg1d", "0123456789ghijklmnopqrstuvwxyzabcdef"),
225 | NewSampleWithAlphabet("sure.", "6hz53nte", "0123456789ghijklmnopqrstuvwxyzabcdef"),
226 | NewSampleWithAlphabet("asure.", "11fhis20p2", "0123456789ghijklmnopqrstuvwxyzabcdef"),
227 | NewSampleWithAlphabet("easure.", "7yf7r367d2s", "0123456789ghijklmnopqrstuvwxyzabcdef"),
228 | NewSampleWithAlphabet("leasure.", "1tiha0vdbb6ks", "0123456789ghijklmnopqrstuvwxyzabcdef"),
229 |
230 | NewSampleWithAlphabet("=", "1v", "0123456789ghijklmnopqrstuvwxyzabcdef"),
231 | NewSampleWithAlphabet(">", "1w", "0123456789ghijklmnopqrstuvwxyzabcdef"),
232 | NewSampleWithAlphabet("?", "1x", "0123456789ghijklmnopqrstuvwxyzabcdef"),
233 | NewSampleWithAlphabet("11", "9vz", "0123456789ghijklmnopqrstuvwxyzabcdef"),
234 | NewSampleWithAlphabet("111", "1d3pr", "0123456789ghijklmnopqrstuvwxyzabcdef"),
235 | NewSampleWithAlphabet("1111", "jtj7gv", "0123456789ghijklmnopqrstuvwxyzabcdef"),
236 | NewSampleWithAlphabet("11111", "2v25bc35", "0123456789ghijklmnopqrstuvwxyzabcdef"),
237 | NewSampleWithAlphabet("111111", "p67jay6id", "0123456789ghijklmnopqrstuvwxyzabcdef"),
238 |
239 | NewSampleWithAlphabet("Hello, World!", "lm3n7bwc7kkt6pcctfsv", "0123456789ghijklmnopqrstuvwxyzabcdef"),
240 | NewSampleWithAlphabet("你好,世界!", "p0ymaua3pzvvt6lgmjwxh3qxk1f5", "0123456789ghijklmnopqrstuvwxyzabcdef"),
241 | NewSampleWithAlphabet("こんにちは", "1c6vpek0wpbec4dar6jy5plf", "0123456789ghijklmnopqrstuvwxyzabcdef"),
242 | NewSampleWithAlphabet("안녕하십니까", "pu9yhn1ub904tcce5muyaml1islm", "0123456789ghijklmnopqrstuvwxyzabcdef"),
243 | }
244 |
245 | var SamplesErr = []*Sample{
246 | NewSample("", "Hello, World!"),
247 | NewSample("", "哈哈"),
248 | NewSample("", "はは"),
249 | }
250 |
--------------------------------------------------------------------------------
/base45/base45_test.go:
--------------------------------------------------------------------------------
1 | package base45
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | type testPair struct {
8 | decoded string
9 | encoded string
10 | }
11 |
12 | type malformedTestPair struct {
13 | encoded string
14 | error error
15 | }
16 |
17 | var pairs = []testPair{
18 | {
19 | decoded: "AB",
20 | encoded: "BB8",
21 | },
22 | {
23 | decoded: "Hello!!",
24 | encoded: "%69 VD92EX0",
25 | },
26 | {
27 | decoded: "base-45",
28 | encoded: "UJCLQE7W581",
29 | },
30 | {
31 | decoded: "ietf!",
32 | encoded: "QED8WEX0",
33 | },
34 | {
35 | decoded: "Lorem ipsum dolor sit amet",
36 | encoded: "$T9ZKE ZD$ED$QE ZDGVC*VDBJEPQESUEBEC7$C",
37 | },
38 | }
39 |
40 | var malformedPairs = []malformedTestPair{
41 | {
42 | encoded: "A",
43 | error: InvalidLengthError{length: 1, mod: 1},
44 | },
45 | {
46 | encoded: "FAILEd",
47 | error: InvalidCharacterError{char: 'd', position: 5},
48 | },
49 | {
50 | encoded: "GGW",
51 | error: IllegalBase45ByteError{position: 0},
52 | },
53 | {
54 | encoded: ":::",
55 | error: IllegalBase45ByteError{position: 0},
56 | },
57 | {
58 | encoded: "ABC:::",
59 | error: IllegalBase45ByteError{position: 1},
60 | },
61 | }
62 |
63 | func testEqual(t *testing.T, msg string, args ...any) bool {
64 | t.Helper()
65 | if args[len(args)-2] != args[len(args)-1] {
66 | t.Errorf(msg, args...)
67 | return false
68 | }
69 | return true
70 | }
71 |
72 | func TestEncode(t *testing.T) {
73 | for _, p := range pairs {
74 | got := StdEncoding.EncodeToString([]byte(p.decoded))
75 | testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
76 | }
77 | }
78 |
79 | func TestDecode(t *testing.T) {
80 | for _, p := range pairs {
81 | got, err := StdEncoding.DecodeString(p.encoded)
82 | if err != nil {
83 | t.Failed()
84 | }
85 |
86 | testEqual(t, "Decode(%q) = %q, want %q", p.encoded, string(got), p.decoded)
87 | }
88 | }
89 |
90 | func TestDecodeMalformed(t *testing.T) {
91 | for _, p := range malformedPairs {
92 | _, err := StdEncoding.DecodeString(p.encoded)
93 | if err == nil {
94 | t.Failed()
95 | }
96 | switch err := err.(type) {
97 | case InvalidLengthError:
98 | testEqual(t, "Error(%s) = %s, want %s", p.error, err, p.error)
99 | case InvalidCharacterError:
100 | testEqual(t, "Error(%s) = %s, want %s", p.error, err, p.error)
101 | case IllegalBase45ByteError:
102 | testEqual(t, "Error(%s) = %s, want %s", p.error, err, p.error)
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/base58/base58.go:
--------------------------------------------------------------------------------
1 | package base58
2 |
3 | import (
4 | "unsafe"
5 | "reflect"
6 | "strconv"
7 | "math/big"
8 | )
9 |
10 | var bigRadix = [...]*big.Int{
11 | big.NewInt(0),
12 | big.NewInt(58),
13 | big.NewInt(58 * 58),
14 | big.NewInt(58 * 58 * 58),
15 | big.NewInt(58 * 58 * 58 * 58),
16 | big.NewInt(58 * 58 * 58 * 58 * 58),
17 | big.NewInt(58 * 58 * 58 * 58 * 58 * 58),
18 | big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58),
19 | big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58),
20 | big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58),
21 | bigRadix10,
22 | }
23 |
24 | var bigRadix10 = big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58) // 58^10
25 |
26 | const (
27 | alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
28 |
29 | alphabetIdx0 = '1'
30 | )
31 |
32 | type CorruptInputError int64
33 |
34 | func (e CorruptInputError) Error() string {
35 | return "go-encoding/base58: illegal base58 data at input byte " + strconv.FormatInt(int64(e), 10)
36 | }
37 |
38 | var StdEncoding = NewEncoding(alphabet)
39 |
40 | /*
41 | * Encodings
42 | */
43 |
44 | // An Encoding is a base 58 encoding/decoding scheme defined by a 58-character alphabet.
45 | type Encoding struct {
46 | encode [58]byte
47 | decodeMap [256]byte
48 | }
49 |
50 | // NewEncoding returns a new Encoding defined by the given alphabet, which must
51 | // be a 58-byte string that does not contain CR or LF ('\r', '\n').
52 | func NewEncoding(encoder string) *Encoding {
53 | if len(encoder) != 58 {
54 | panic("go-encoding/base58: encoding alphabet is not 58 bytes long")
55 | }
56 |
57 | for i := 0; i < len(encoder); i++ {
58 | if encoder[i] == '\n' || encoder[i] == '\r' {
59 | panic("go-encoding/base58: encoding alphabet contains newline character")
60 | }
61 | }
62 |
63 | e := new(Encoding)
64 | copy(e.encode[:], encoder)
65 |
66 | for i := 0; i < len(e.decodeMap); i++ {
67 | // 0xff indicates that this entry in the decode map is not in the encoding alphabet.
68 | e.decodeMap[i] = 0xff
69 | }
70 |
71 | for i := 0; i < len(encoder); i++ {
72 | e.decodeMap[encoder[i]] = byte(i)
73 | }
74 |
75 | return e
76 | }
77 |
78 | /*
79 | * Encoder
80 | */
81 |
82 | // Encode encodes src using the encoding enc.
83 | func (enc *Encoding) Encode(b []byte) []byte {
84 | x := new(big.Int)
85 | x.SetBytes(b)
86 |
87 | maxlen := int(float64(len(b))*1.365658237309761) + 1
88 | answer := make([]byte, 0, maxlen)
89 | mod := new(big.Int)
90 |
91 | for x.Sign() > 0 {
92 | x.DivMod(x, bigRadix10, mod)
93 | if x.Sign() == 0 {
94 | m := mod.Int64()
95 | for m > 0 {
96 | answer = append(answer, enc.encode[m%58])
97 | m /= 58
98 | }
99 | } else {
100 | m := mod.Int64()
101 | for i := 0; i < 10; i++ {
102 | answer = append(answer, enc.encode[m%58])
103 | m /= 58
104 | }
105 | }
106 | }
107 |
108 | for _, i := range b {
109 | if i != 0 {
110 | break
111 | }
112 |
113 | answer = append(answer, alphabetIdx0)
114 | }
115 |
116 | alen := len(answer)
117 | for i := 0; i < alen/2; i++ {
118 | answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i]
119 | }
120 |
121 | return answer
122 | }
123 |
124 | // EncodeToString returns the base58 encoding of src.
125 | func (enc *Encoding) EncodeToString(src []byte) string {
126 | answer := enc.Encode(src)
127 |
128 | return string(answer)
129 | }
130 |
131 | /*
132 | * Decoder
133 | */
134 |
135 | // Decode decodes src using the encoding enc. It writes at most DecodedLen(len(src))
136 | // bytes to dst and returns the number of bytes written. If src contains invalid base58
137 | // data, it will return the number of bytes successfully written and CorruptInputError.
138 | func (enc *Encoding) Decode(src []byte) ([]byte, error) {
139 | answer := big.NewInt(0)
140 | scratch := new(big.Int)
141 |
142 | b := string(src)
143 |
144 | for t := b; len(t) > 0; {
145 | n := len(t)
146 | if n > 10 {
147 | n = 10
148 | }
149 |
150 | total := uint64(0)
151 | for _, v := range t[:n] {
152 | if v > 255 {
153 | return []byte(""), CorruptInputError(v)
154 | }
155 |
156 | tmp := enc.decodeMap[v]
157 | if tmp == 255 {
158 | return []byte(""), CorruptInputError(v)
159 | }
160 |
161 | total = total*58 + uint64(tmp)
162 | }
163 |
164 | answer.Mul(answer, bigRadix[n])
165 | scratch.SetUint64(total)
166 | answer.Add(answer, scratch)
167 |
168 | t = t[n:]
169 | }
170 |
171 | tmpval := answer.Bytes()
172 |
173 | var numZeros int
174 | for numZeros = 0; numZeros < len(b); numZeros++ {
175 | if b[numZeros] != alphabetIdx0 {
176 | break
177 | }
178 | }
179 |
180 | flen := numZeros + len(tmpval)
181 | val := make([]byte, flen)
182 | copy(val[numZeros:], tmpval)
183 |
184 | return val, nil
185 | }
186 |
187 | // DecodeString returns the bytes represented by the base58 string s.
188 | func (enc *Encoding) DecodeString(s string) ([]byte, error) {
189 | sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
190 | bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
191 | return enc.Decode(*(*[]byte)(unsafe.Pointer(&bh)))
192 | }
193 |
194 |
--------------------------------------------------------------------------------
/base58/base58_test.go:
--------------------------------------------------------------------------------
1 | package base58
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 | )
7 |
8 | func Test_Encode(t *testing.T) {
9 | for _, s := range SamplesStd {
10 | encoded := StdEncoding.Encode([]byte(s.source))
11 | if bytes.Equal(encoded, s.targetBytes) {
12 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
13 | } else {
14 | str := string(encoded)
15 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), str, len(str))
16 | }
17 | }
18 | }
19 |
20 | func Test_EncodeToString(t *testing.T) {
21 | for _, s := range SamplesStd {
22 | encoded := StdEncoding.EncodeToString([]byte(s.source))
23 | if len(encoded) == len(s.target) && encoded == s.target {
24 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
25 | } else {
26 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), encoded, len(encoded))
27 | }
28 | }
29 | }
30 |
31 | func Test_Decode(t *testing.T) {
32 | for _, s := range SamplesStd {
33 | decoded, err := StdEncoding.Decode(s.targetBytes)
34 | if err != nil {
35 | t.Error(err)
36 | continue
37 | }
38 | if bytes.Equal(decoded, s.sourceBytes) {
39 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
40 | } else {
41 | str := string(decoded)
42 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
43 | }
44 | }
45 | }
46 |
47 | func Test_DecodeString(t *testing.T) {
48 | for _, s := range SamplesStd {
49 | decoded, err := StdEncoding.DecodeString(s.target)
50 | if err != nil {
51 | t.Error(err)
52 | continue
53 | }
54 | if bytes.Equal(decoded, s.sourceBytes) {
55 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
56 | } else {
57 | str := string(decoded)
58 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
59 | }
60 | }
61 | }
62 |
63 | func Test_EncodeWithCustomAlphabet(t *testing.T) {
64 | for _, s := range SamplesWithAlphabet {
65 | encoded := NewEncoding(s.alphabet).Encode([]byte(s.source))
66 | if bytes.Equal(encoded, s.targetBytes) {
67 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
68 | } else {
69 | str := string(encoded)
70 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), str, len(str))
71 | }
72 | }
73 | }
74 |
75 | func Test_DecodeWithCustomAlphabet(t *testing.T) {
76 | for _, s := range SamplesWithAlphabet {
77 | decoded, err := NewEncoding(s.alphabet).Decode(s.targetBytes)
78 | if err != nil {
79 | t.Error(err)
80 | continue
81 | }
82 | if bytes.Equal(decoded, s.sourceBytes) {
83 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
84 | } else {
85 | str := string(decoded)
86 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
87 | }
88 | }
89 | }
90 |
91 | func Test_DecodeError(t *testing.T) {
92 | for _, s := range SamplesErr {
93 | decoded, err := StdEncoding.Decode(s.targetBytes)
94 | if err != nil {
95 | t.Logf("%s: \"%c\"", err.Error(), err)
96 | continue
97 | }
98 |
99 | str := string(decoded)
100 | t.Errorf("An error should have occurred, instead of returning \"%s\"", str)
101 | }
102 | }
103 |
104 | func Test_CheckEncode(t *testing.T) {
105 | input := []byte("test-date")
106 | version := byte(12)
107 |
108 | res := CheckEncode(input, version)
109 |
110 | decoded, ver, _ := CheckDecode(res)
111 |
112 | if !bytes.Equal(decoded, input) {
113 | t.Errorf("input got: %s(%d), want: %s(%d)", string(decoded), len(decoded), string(input), len(input))
114 | }
115 |
116 | if ver != version {
117 | t.Errorf("version got: %d, want: %d", ver, version)
118 | }
119 | }
120 |
121 | func NewSample(source, target string) *Sample {
122 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target)}
123 | }
124 |
125 | func NewSampleWithAlphabet(source, target, alphabet string) *Sample {
126 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target), alphabet: alphabet}
127 | }
128 |
129 | type Sample struct {
130 | source string
131 | target string
132 | sourceBytes []byte
133 | targetBytes []byte
134 | alphabet string
135 | }
136 |
137 | var SamplesStd = []*Sample{
138 | NewSample("", ""),
139 | NewSample("f", "2m"),
140 | NewSample("fo", "8o8"),
141 | NewSample("foo", "bQbp"),
142 | NewSample("foob", "3csAg9"),
143 | NewSample("fooba", "CZJRhmz"),
144 | NewSample("foobar", "t1Zv2yaZ"),
145 |
146 | NewSample("su", "9nc"),
147 | NewSample("sur", "fnKT"),
148 | NewSample("sure", "3xB2TW"),
149 | NewSample("sure.", "E2XFRyo"),
150 | NewSample("asure.", "qXcNm9C1"),
151 | NewSample("easure.", "4qq4WqChgZ"),
152 | NewSample("leasure.", "K8aUZhGUNaR"),
153 |
154 | NewSample("=", "24"),
155 | NewSample(">", "25"),
156 | NewSample("?", "26"),
157 | NewSample("11", "4k8"),
158 | NewSample("111", "HXLk"),
159 | NewSample("1111", "2Fvv9e"),
160 | NewSample("11111", "6Ytyb9A"),
161 | NewSample("111111", "RVnQmh1a"),
162 |
163 | NewSample("Hello, World!", "72k1xXWG59fYdzSNoA"),
164 | NewSample("你好,世界!", "AVGu5T9j8gbKjDaBawMj5iGit"),
165 | NewSample("こんにちは", "7NAasPYBzpyEe5hmwr1KL"),
166 | NewSample("안녕하십니까", "Ap9GxMvMvB9xzEbvcweFMBLEX"),
167 | }
168 |
169 | var SamplesWithAlphabet = []*Sample{
170 | NewSampleWithAlphabet("", "", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
171 | NewSampleWithAlphabet("f", "Bv", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
172 | NewSampleWithAlphabet("fo", "HxH", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
173 | NewSampleWithAlphabet("foo", "kZky", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
174 | NewSampleWithAlphabet("foob", "Cl2KqJ", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
175 | NewSampleWithAlphabet("fooba", "MiTarv9", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
176 | NewSampleWithAlphabet("foobar", "3Ai5B8ji", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
177 |
178 | NewSampleWithAlphabet("su", "Jwl", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
179 | NewSampleWithAlphabet("sur", "pwUc", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
180 | NewSampleWithAlphabet("sure", "C7LBcf", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
181 | NewSampleWithAlphabet("sure.", "PBgQa8x", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
182 | NewSampleWithAlphabet("asure.", "zglXvJMA", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
183 | NewSampleWithAlphabet("easure.", "DzzDfzMrqi", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
184 | NewSampleWithAlphabet("leasure.", "UHjdirRdXja", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
185 |
186 | NewSampleWithAlphabet("=", "BD", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
187 | NewSampleWithAlphabet(">", "BE", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
188 | NewSampleWithAlphabet("?", "BF", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
189 | NewSampleWithAlphabet("11", "DuH", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
190 | NewSampleWithAlphabet("111", "SgVu", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
191 | NewSampleWithAlphabet("1111", "BQ55Jn", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
192 | NewSampleWithAlphabet("11111", "Fh38kJK", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
193 | NewSampleWithAlphabet("111111", "aewZvrAj", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
194 |
195 | NewSampleWithAlphabet("Hello, World!", "GBuA7gfREJphm9bXxK", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
196 | NewSampleWithAlphabet("你好,世界!", "KeR4EcJtHqkUtNjLj6WtEsRs3", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
197 | NewSampleWithAlphabet("こんにちは", "GXKj2YhL9y8PnErv61AUV", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
198 | NewSampleWithAlphabet("안녕하십니까", "KyJR7W5W5LJ79Pk5l6nQWLVPg", "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789"),
199 | }
200 |
201 | var SamplesErr = []*Sample{
202 | NewSample("", "Hello, World!"),
203 | NewSample("", "哈哈"),
204 | NewSample("", "はは"),
205 | }
206 |
--------------------------------------------------------------------------------
/base58/base58check.go:
--------------------------------------------------------------------------------
1 | package base58
2 |
3 | import (
4 | "errors"
5 | "crypto/sha256"
6 | )
7 |
8 | var ErrChecksum = errors.New("checksum error")
9 | var ErrInvalidFormat = errors.New("invalid format: version and/or checksum bytes missing")
10 |
11 | func checksum(input []byte) (cksum [4]byte) {
12 | h := sha256.Sum256(input)
13 | h2 := sha256.Sum256(h[:])
14 | copy(cksum[:], h2[:4])
15 | return
16 | }
17 |
18 | // Check Encode
19 | func CheckEncode(input []byte, version byte) string {
20 | b := make([]byte, 0, 1+len(input)+4)
21 | b = append(b, version)
22 | b = append(b, input...)
23 |
24 | cksum := checksum(b)
25 |
26 | b = append(b, cksum[:]...)
27 |
28 | return StdEncoding.EncodeToString(b)
29 | }
30 |
31 | // Check Decode
32 | func CheckDecode(input string) (result []byte, version byte, err error) {
33 | decoded, _ := StdEncoding.DecodeString(input)
34 | if len(decoded) < 5 {
35 | return nil, 0, ErrInvalidFormat
36 | }
37 |
38 | version = decoded[0]
39 | var cksum [4]byte
40 | copy(cksum[:], decoded[len(decoded)-4:])
41 | if checksum(decoded[:len(decoded)-4]) != cksum {
42 | return nil, 0, ErrChecksum
43 | }
44 |
45 | payload := decoded[1 : len(decoded)-4]
46 | result = append(result, payload...)
47 |
48 | return
49 | }
50 |
--------------------------------------------------------------------------------
/base62/base62.go:
--------------------------------------------------------------------------------
1 | package base62
2 |
3 | import (
4 | "math"
5 | "unsafe"
6 | "reflect"
7 | "strconv"
8 | )
9 |
10 | type CorruptInputError int64
11 |
12 | func (e CorruptInputError) Error() string {
13 | return "go-encoding/base62: illegal base62 data at input byte " + strconv.FormatInt(int64(e), 10)
14 | }
15 |
16 | const encodeStd = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
17 |
18 | // StdEncoding is the standard base62 encoding.
19 | var StdEncoding = NewEncoding(encodeStd)
20 |
21 | /*
22 | * Encodings
23 | */
24 |
25 | // An Encoding is a radix 62 encoding/decoding scheme, defined by a 62-character alphabet.
26 | type Encoding struct {
27 | encode [62]byte
28 | decodeMap [256]byte
29 | }
30 |
31 | // NewEncoding returns a new padded Encoding defined by the given alphabet,
32 | // which must be a 62-byte string that does not contain the padding character
33 | // or CR / LF ('\r', '\n').
34 | func NewEncoding(encoder string) *Encoding {
35 | if len(encoder) != 62 {
36 | panic("go-encoding/base62: encoding alphabet is not 62-bytes long")
37 | }
38 |
39 | for i := 0; i < len(encoder); i++ {
40 | if encoder[i] == '\n' || encoder[i] == '\r' {
41 | panic("go-encoding/base62: encoding alphabet contains newline character")
42 | }
43 | }
44 |
45 | e := new(Encoding)
46 | copy(e.encode[:], encoder)
47 |
48 | for i := 0; i < len(e.decodeMap); i++ {
49 | e.decodeMap[i] = 0xFF
50 | }
51 |
52 | for i := 0; i < len(encoder); i++ {
53 | e.decodeMap[encoder[i]] = byte(i)
54 | }
55 |
56 | return e
57 | }
58 |
59 | /*
60 | * Encoder
61 | */
62 |
63 | // Encode encodes src using the encoding enc.
64 | func (enc *Encoding) Encode(src []byte) []byte {
65 | if len(src) == 0 {
66 | return nil
67 | }
68 |
69 | // enc is a pointer receiver, so the use of enc.encode within the hot
70 | // loop below means a nil check at every operation. Lift that nil check
71 | // outside of the loop to speed up the encoder.
72 | _ = enc.encode
73 |
74 | rs := 0
75 | cs := int(math.Ceil(math.Log(256) / math.Log(62) * float64(len(src))))
76 | dst := make([]byte, cs)
77 |
78 | for i := range src {
79 | c := 0
80 | v := int(src[i])
81 |
82 | for j := cs - 1; j >= 0 && (v != 0 || c < rs); j-- {
83 | v += 256 * int(dst[j])
84 | dst[j] = byte(v % 62)
85 | v /= 62
86 | c++
87 | }
88 |
89 | rs = c
90 | }
91 |
92 | for i := range dst {
93 | dst[i] = enc.encode[dst[i]]
94 | }
95 |
96 | if cs > rs {
97 | return dst[cs-rs:]
98 | }
99 |
100 | return dst
101 | }
102 |
103 | // EncodeToString returns the base62 encoding of src.
104 | func (enc *Encoding) EncodeToString(src []byte) string {
105 | buf := enc.Encode(src)
106 | return string(buf)
107 | }
108 |
109 | /*
110 | * Decoder
111 | */
112 |
113 | // Decode decodes src using the encoding enc.
114 | // If src contains invalid base62 data, it will return the
115 | // number of bytes successfully written and CorruptInputError.
116 | // New line characters (\r and \n) are ignored.
117 | func (enc *Encoding) Decode(src []byte) ([]byte, error) {
118 | if len(src) == 0 {
119 | return nil, nil
120 | }
121 |
122 | // Lift the nil check outside of the loop. enc.decodeMap is directly
123 | // used later in this function, to let the compiler know that the
124 | // receiver can't be nil.
125 | _ = enc.decodeMap
126 |
127 | rs := 0
128 | cs := int(math.Ceil(math.Log(62) / math.Log(256) * float64(len(src))))
129 | dst := make([]byte, cs)
130 | for i := range src {
131 | if src[i] == '\n' || src[i] == '\r' {
132 | continue
133 | }
134 |
135 | c := 0
136 | v := int(enc.decodeMap[src[i]])
137 | if v == 255 {
138 | return nil, CorruptInputError(src[i])
139 | }
140 |
141 | for j := cs - 1; j >= 0 && (v != 0 || c < rs); j-- {
142 | v += 62 * int(dst[j])
143 | dst[j] = byte(v % 256)
144 | v /= 256
145 | c++
146 | }
147 |
148 | rs = c
149 | }
150 |
151 | if cs > rs {
152 | return dst[cs-rs:], nil
153 | }
154 |
155 | return dst, nil
156 | }
157 |
158 | // DecodeString returns the bytes represented by the base62 string s.
159 | func (enc *Encoding) DecodeString(s string) ([]byte, error) {
160 | sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
161 | bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
162 | return enc.Decode(*(*[]byte)(unsafe.Pointer(&bh)))
163 | }
164 |
--------------------------------------------------------------------------------
/base62/base62_test.go:
--------------------------------------------------------------------------------
1 | package base62
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 | )
7 |
8 | func TestEncode(t *testing.T) {
9 | for _, s := range SamplesStd {
10 | encoded := StdEncoding.Encode([]byte(s.source))
11 | if bytes.Equal(encoded, s.targetBytes) {
12 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
13 | } else {
14 | str := string(encoded)
15 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), str, len(str))
16 | }
17 | }
18 | }
19 |
20 | func TestEncodeToString(t *testing.T) {
21 | for _, s := range SamplesStd {
22 | encoded := StdEncoding.EncodeToString([]byte(s.source))
23 | if len(encoded) == len(s.target) && encoded == s.target {
24 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
25 | } else {
26 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), encoded, len(encoded))
27 | }
28 | }
29 | }
30 |
31 | func TestDecode(t *testing.T) {
32 | for _, s := range SamplesStd {
33 | decoded, err := StdEncoding.Decode(s.targetBytes)
34 | if err != nil {
35 | t.Error(err)
36 | continue
37 | }
38 | if bytes.Equal(decoded, s.sourceBytes) {
39 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
40 | } else {
41 | str := string(decoded)
42 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
43 | }
44 | }
45 | }
46 |
47 | func TestDecodeString(t *testing.T) {
48 | for _, s := range SamplesStd {
49 | decoded, err := StdEncoding.DecodeString(s.target)
50 | if err != nil {
51 | t.Error(err)
52 | continue
53 | }
54 | if bytes.Equal(decoded, s.sourceBytes) {
55 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
56 | } else {
57 | str := string(decoded)
58 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
59 | }
60 | }
61 | }
62 |
63 | func TestDecodeWithNewLine(t *testing.T) {
64 | for _, s := range SamplesWithNewLine {
65 | decoded, err := StdEncoding.Decode(s.targetBytes)
66 | if err != nil {
67 | t.Error(err)
68 | continue
69 | }
70 | if bytes.Equal(decoded, s.sourceBytes) {
71 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
72 | } else {
73 | str := string(decoded)
74 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
75 | }
76 | }
77 | }
78 |
79 | func TestDecodeError(t *testing.T) {
80 | for _, s := range SamplesErr {
81 | decoded, err := StdEncoding.Decode(s.targetBytes)
82 | if err != nil {
83 | t.Logf("%s: \"%c\"", err.Error(), err)
84 | continue
85 | }
86 | str := string(decoded)
87 | t.Errorf("An error should have occurred, instead of returning \"%s\"", str)
88 | }
89 | }
90 |
91 | func TestEncodeWithCustomAlphabet(t *testing.T) {
92 | for _, s := range SamplesWithAlphabet {
93 | encoded := NewEncoding(s.alphabet).Encode([]byte(s.source))
94 | if bytes.Equal(encoded, s.targetBytes) {
95 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
96 | } else {
97 | str := string(encoded)
98 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), str, len(str))
99 | }
100 | }
101 | }
102 |
103 | func TestDecodeWithCustomAlphabet(t *testing.T) {
104 | for _, s := range SamplesWithAlphabet {
105 | decoded, err := NewEncoding(s.alphabet).Decode(s.targetBytes)
106 | if err != nil {
107 | t.Error(err)
108 | continue
109 | }
110 | if bytes.Equal(decoded, s.sourceBytes) {
111 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
112 | } else {
113 | str := string(decoded)
114 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
115 | }
116 | }
117 | }
118 |
119 | func NewSample(source, target string) *Sample {
120 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target)}
121 | }
122 |
123 | func NewSampleWithAlphabet(source, target, alphabet string) *Sample {
124 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target), alphabet: alphabet}
125 | }
126 |
127 | type Sample struct {
128 | source string
129 | target string
130 | sourceBytes []byte
131 | targetBytes []byte
132 | alphabet string
133 | }
134 |
135 | var SamplesStd = []*Sample{
136 | NewSample("", ""),
137 | NewSample("f", "1e"),
138 | NewSample("fo", "6ox"),
139 | NewSample("foo", "SAPP"),
140 | NewSample("foob", "1sIyuo"),
141 | NewSample("fooba", "7kENWa1"),
142 | NewSample("foobar", "VytN8Wjy"),
143 |
144 | NewSample("su", "7gj"),
145 | NewSample("sur", "VkRe"),
146 | NewSample("sure", "275mAn"),
147 | NewSample("sure.", "8jHquZ4"),
148 | NewSample("asure.", "UQPPAab8"),
149 | NewSample("easure.", "26h8PlupSA"),
150 | NewSample("leasure.", "9IzLUOIY2fe"),
151 |
152 | NewSample("=", "z"),
153 | NewSample(">", "10"),
154 | NewSample("?", "11"),
155 | NewSample("11", "3H7"),
156 | NewSample("111", "DWfh"),
157 | NewSample("1111", "tquAL"),
158 | NewSample("11111", "3icRuhV"),
159 | NewSample("111111", "FMElG7cn"),
160 |
161 | NewSample("Hello, World!", "1wJfrzvdbtXUOlUjUf"),
162 | NewSample("你好,世界!", "1ugmIChyMAcCbDRpROpAtpXdp"),
163 | NewSample("こんにちは", "1fyB0pNlcVqP3tfXZ1FmB"),
164 | NewSample("안녕하십니까", "1yl6dfHPaO9hroEXU9qFioFhM"),
165 | }
166 |
167 | var SamplesWithAlphabet = []*Sample{
168 | NewSampleWithAlphabet("", "", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
169 | NewSampleWithAlphabet("f", "Bo", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
170 | NewSampleWithAlphabet("fo", "Gy7", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
171 | NewSampleWithAlphabet("foo", "cKZZ", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
172 | NewSampleWithAlphabet("foob", "B2S84y", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
173 | NewSampleWithAlphabet("fooba", "HuOXgkB", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
174 | NewSampleWithAlphabet("foobar", "f83XIgt8", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
175 |
176 | NewSampleWithAlphabet("su", "Hqt", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
177 | NewSampleWithAlphabet("sur", "fubo", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
178 | NewSampleWithAlphabet("sure", "CHFwKx", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
179 | NewSampleWithAlphabet("sure.", "ItR04jE", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
180 | NewSampleWithAlphabet("asure.", "eaZZKklI", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
181 | NewSampleWithAlphabet("easure.", "CGrIZv4zcK", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
182 | NewSampleWithAlphabet("leasure.", "JS9VeYSiCpo", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
183 |
184 | NewSampleWithAlphabet("=", "9", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
185 | NewSampleWithAlphabet(">", "BA", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
186 | NewSampleWithAlphabet("?", "BB", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
187 | NewSampleWithAlphabet("11", "DRH", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
188 | NewSampleWithAlphabet("111", "Ngpr", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
189 | NewSampleWithAlphabet("1111", "304KV", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
190 | NewSampleWithAlphabet("11111", "Dsmb4rf", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
191 | NewSampleWithAlphabet("111111", "PWOvQHmx", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
192 |
193 | NewSampleWithAlphabet("Hello, World!", "B6Tp195nl3heYvetep", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
194 | NewSampleWithAlphabet("你好,世界!", "B4qwSMr8WKmMlNbzbYzK3zhnz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
195 | NewSampleWithAlphabet("こんにちは", "Bp8LAzXvmf0ZD3phjBPwL", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
196 | NewSampleWithAlphabet("안녕하십니까", "B8vGnpRZkYJr1yOheJ0PsyPrW", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
197 | }
198 |
199 | var SamplesWithNewLine = []*Sample{
200 | NewSample("111111", "FMEl\nG7cn"),
201 | NewSample("111111", "FMEl\rG7cn"),
202 | NewSample("Hello, World!", "1wJfrzvdb\ntXUOlUjUf"),
203 | NewSample("Hello, World!", "1wJfrzvdb\rtXUOlUjUf"),
204 | NewSample("你好,世界!", "1ugmIChyMAcC\nbDRpROpAtpXdp"),
205 | NewSample("你好,世界!", "1ugmIChyMAcC\rbDRpROpAtpXdp"),
206 | }
207 |
208 | var SamplesErr = []*Sample{
209 | NewSample("", "Hello, World!"),
210 | NewSample("", "哈哈"),
211 | NewSample("", "はは"),
212 | }
213 |
--------------------------------------------------------------------------------
/base91/base91.go:
--------------------------------------------------------------------------------
1 | package base91
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | // A CorruptInputError is returned if invalid base91 data is encountered during decoding.
9 | type CorruptInputError int64
10 |
11 | func (e CorruptInputError) Error() string {
12 | return fmt.Sprintf("go-encoding/base91: illegal base91 data at input byte %d", int64(e))
13 | }
14 |
15 | // encodeStd is the standard base91 encoding alphabet (that is, the one specified
16 | // at http://base91.sourceforge.net). Of the 95 printable ASCII characters, the
17 | // following four are omitted: space (0x20), apostrophe (0x27), hyphen (0x2d),
18 | // and backslash (0x5c).
19 | const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~\""
20 |
21 | // StdEncoding is the standard base91 encoding (that is, the one specified
22 | // at http://base91.sourceforge.net). Of the 95 printable ASCII characters,
23 | // the following four are omitted: space (0x20), apostrophe (0x27),
24 | // hyphen (0x2d), and backslash (0x5c).
25 | var StdEncoding = NewEncoding(encodeStd)
26 |
27 | /*
28 | * Encodings
29 | */
30 |
31 | // An Encoding is a base 91 encoding/decoding scheme defined by a 91-character alphabet.
32 | type Encoding struct {
33 | encode [91]byte
34 | decodeMap [256]byte
35 | }
36 |
37 | // NewEncoding returns a new Encoding defined by the given alphabet, which must
38 | // be a 91-byte string that does not contain CR or LF ('\r', '\n').
39 | func NewEncoding(encoder string) *Encoding {
40 | if len(encoder) != 91 {
41 | panic("go-encoding/base91: encoding alphabet is not 91 bytes long")
42 | }
43 |
44 | for i := 0; i < len(encoder); i++ {
45 | if encoder[i] == '\n' || encoder[i] == '\r' {
46 | panic("go-encoding/base91: encoding alphabet contains newline character")
47 | }
48 | }
49 |
50 | e := new(Encoding)
51 | copy(e.encode[:], encoder)
52 |
53 | for i := 0; i < len(e.decodeMap); i++ {
54 | // 0xff indicates that this entry in the decode map is not in the encoding alphabet.
55 | e.decodeMap[i] = 0xff
56 | }
57 |
58 | for i := 0; i < len(encoder); i++ {
59 | e.decodeMap[encoder[i]] = byte(i)
60 | }
61 |
62 | return e
63 | }
64 |
65 | /*
66 | * Encoder
67 | */
68 |
69 | // Encode encodes src using the encoding enc, writing bytes to dst.
70 | // It returns the number of bytes written, because the exact output size cannot
71 | // be known before encoding takes place. EncodedLen(len(src)) may be used to
72 | // determine an upper bound on the output size when allocating a dst slice.
73 | func (enc *Encoding) Encode(dst, src []byte) int {
74 | var queue, numBits uint
75 |
76 | n := 0
77 | for i := 0; i < len(src); i++ {
78 | queue |= uint(src[i]) << numBits
79 | numBits += 8
80 | if numBits > 13 {
81 | var v uint = queue & 8191
82 |
83 | if v > 88 {
84 | queue >>= 13
85 | numBits -= 13
86 | } else {
87 | // We can take 14 bits.
88 | v = queue & 16383
89 | queue >>= 14
90 | numBits -= 14
91 | }
92 | dst[n] = enc.encode[v%91]
93 | n++
94 | dst[n] = enc.encode[v/91]
95 | n++
96 | }
97 | }
98 |
99 | if numBits > 0 {
100 | dst[n] = enc.encode[queue%91]
101 | n++
102 |
103 | if numBits > 7 || queue > 90 {
104 | dst[n] = enc.encode[queue/91]
105 | n++
106 | }
107 | }
108 |
109 | return n
110 | }
111 |
112 | // EncodeToString returns the base91 encoding of src.
113 | func (enc *Encoding) EncodeToString(src []byte) string {
114 | buf := make([]byte, enc.EncodedLen(len(src)))
115 | n := enc.Encode(buf, src)
116 | return string(buf[:n])
117 | }
118 |
119 | // EncodedLen returns an upper bound on the length in bytes of the base91 encoding
120 | // of an input buffer of length n. The true encoded length may be shorter.
121 | func (enc *Encoding) EncodedLen(n int) int {
122 | // At worst, base91 encodes 13 bits into 16 bits. Even though 14 bits can
123 | // sometimes be encoded into 16 bits, assume the worst case to get the upper
124 | // bound on encoded length.
125 | return int(math.Ceil(float64(n) * 16.0 / 13.0))
126 | }
127 |
128 | /*
129 | * Decoder
130 | */
131 |
132 | // Decode decodes src using the encoding enc. It writes at most DecodedLen(len(src))
133 | // bytes to dst and returns the number of bytes written. If src contains invalid base91
134 | // data, it will return the number of bytes successfully written and CorruptInputError.
135 | func (enc *Encoding) Decode(dst, src []byte) (int, error) {
136 | var queue, numBits uint
137 | var v int = -1
138 |
139 | n := 0
140 | for i := 0; i < len(src); i++ {
141 | if enc.decodeMap[src[i]] == 0xff {
142 | // The character is not in the encoding alphabet.
143 | return n, CorruptInputError(i)
144 | }
145 |
146 | if v == -1 {
147 | // Start the next value.
148 | v = int(enc.decodeMap[src[i]])
149 | } else {
150 | v += int(enc.decodeMap[src[i]]) * 91
151 | queue |= uint(v) << numBits
152 |
153 | if (v & 8191) > 88 {
154 | numBits += 13
155 | } else {
156 | numBits += 14
157 | }
158 |
159 | for ok := true; ok; ok = (numBits > 7) {
160 | dst[n] = byte(queue)
161 | n++
162 |
163 | queue >>= 8
164 | numBits -= 8
165 | }
166 |
167 | // Mark this value complete.
168 | v = -1
169 | }
170 | }
171 |
172 | if v != -1 {
173 | dst[n] = byte(queue | uint(v)<", "!A"),
112 | NewSample("?", "#A"),
113 | NewSample("11", "hwB"),
114 | NewSample("111", "hwdE"),
115 | NewSample("1111", "hw;aM"),
116 | NewSample("11111", "hw;a2iA"),
117 | NewSample("111111", "hw;a2iHB"),
118 |
119 | NewSample("Hello, World!", ">OwJh>}AQ;r@@Y?F"),
120 | NewSample("你好,世界!", "I_5k7az}Thlz6;n[kjFVUBB"),
121 | NewSample("こんにちは", "cFs@CCLU=(Py|QE@4rF"),
122 | NewSample("안녕하십니까", "99v?OEn?@[]^_`{|}~\""),
127 | NewSampleWithAlphabet("f", "LB", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
128 | NewSampleWithAlphabet("fo", "3hD", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
129 | NewSampleWithAlphabet("foo", "3h.J", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
130 | NewSampleWithAlphabet("foob", "3h/sY", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
131 | NewSampleWithAlphabet("fooba", "3h/si)A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
132 | NewSampleWithAlphabet("foobar", "3h/si)kC", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
133 |
134 | NewSampleWithAlphabet("su", "5yD", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
135 | NewSampleWithAlphabet("sur", "5yFK", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
136 | NewSampleWithAlphabet("sure", "5yp6Z", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
137 | NewSampleWithAlphabet("sure.", "5yp6v6A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
138 | NewSampleWithAlphabet("asure.", "ls4t5,BB", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
139 | NewSampleWithAlphabet("easure.", "_Dx6j@\"@C", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
140 | NewSampleWithAlphabet("leasure.", "XPH?@[]^_`{|}~\""),
141 |
142 | NewSampleWithAlphabet("=", "zA", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
143 | NewSampleWithAlphabet(">", "!A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
144 | NewSampleWithAlphabet("?", "#A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
145 | NewSampleWithAlphabet("11", "7mB", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
146 | NewSampleWithAlphabet("111", "7m3E", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
147 | NewSampleWithAlphabet("1111", "7m;0M", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
148 | NewSampleWithAlphabet("11111", "7m;0s8A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
149 | NewSampleWithAlphabet("111111", "7m;0s8HB", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
150 |
151 | NewSampleWithAlphabet("Hello, World!", ">OmJ7>}AQ;h@@Y?F", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
152 | NewSampleWithAlphabet("你好,世界!", "I_vax0p}T7bpw;d[a9FVUBB", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
153 | NewSampleWithAlphabet("こんにちは", "2Fi@CCLU=(Po|QE@uhF", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
154 | NewSampleWithAlphabet("안녕하십니까", "zzl?OEd<60&!b!?]DYLh{IB", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!#$%&()*+,./:;<=>?@[]^_`{|}~\""),
155 | }
156 |
157 | var SamplesErr = []*Sample{
158 | NewSample("", "Hello, World!"),
159 | NewSample("", "哈哈"),
160 | NewSample("", "はは"),
161 | }
162 |
--------------------------------------------------------------------------------
/base92/base92.go:
--------------------------------------------------------------------------------
1 | package base92
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | const (
8 | // approximation of ceil(log(256)/log(base)).
9 | // power of two -> speed up DecodeString()
10 | numerator = 16
11 | denominator = 13
12 | )
13 |
14 | // encodeStd is the standard base92 encoding alphabet
15 | const encodeStd = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#|;,_~`\""
16 |
17 | // StdEncoding is the default encoding enc.
18 | var StdEncoding = NewEncoding(encodeStd)
19 |
20 | /*
21 | * Encodings
22 | */
23 |
24 | // An Encoding is a base 92 encoding/decoding scheme defined by a 92-character alphabet.
25 | type Encoding struct {
26 | encode [92]byte
27 | decodeMap [128]byte
28 | }
29 |
30 | // NewEncoding returns a new Encoding defined by the given alphabet, which must
31 | // be a 92-byte string that does not contain CR or LF ('\r', '\n').
32 | func NewEncoding(encoder string) *Encoding {
33 | if len(encoder) != 92 {
34 | panic("go-encoding/base92: encoding alphabet is not 92 bytes long")
35 | }
36 |
37 | for i := 0; i < len(encoder); i++ {
38 | if encoder[i] == '\n' || encoder[i] == '\r' {
39 | panic("go-encoding/base92: encoding alphabet contains newline character")
40 | }
41 | }
42 |
43 | e := new(Encoding)
44 | copy(e.encode[:], encoder)
45 |
46 | for i := 0; i < len(e.decodeMap); i++ {
47 | // 0xff indicates that this entry in the decode map is not in the encoding alphabet.
48 | e.decodeMap[i] = 0xff
49 | }
50 |
51 | for i := 0; i < len(encoder); i++ {
52 | e.decodeMap[encoder[i]] = byte(i)
53 | }
54 |
55 | return e
56 | }
57 |
58 | /*
59 | * Encoder
60 | */
61 |
62 | // Encode encodes binary bytes.
63 | func (enc *Encoding) Encode(bin []byte) []byte {
64 | size := len(bin)
65 |
66 | zcount := 0
67 | for zcount < size && bin[zcount] == 0 {
68 | zcount++
69 | }
70 |
71 | // It is crucial to make this as short as possible, especially for
72 | // the usual case of bitcoin addrs
73 | // This is an integer simplification of
74 | // ceil(log(256)/log(base))
75 | size = zcount + (size-zcount)*numerator/denominator + 1
76 |
77 | out := make([]byte, size)
78 |
79 | var i, high int
80 | var carry uint32
81 |
82 | high = size - 1
83 | for _, b := range bin {
84 | i = size - 1
85 | for carry = uint32(b); i > high || carry != 0; i-- {
86 | carry += 256 * uint32(out[i])
87 | out[i] = byte(carry % 92)
88 | carry /= 92
89 | }
90 |
91 | high = i
92 | }
93 |
94 | // Determine the additional "zero-gap" in the buffer (aside from zcount)
95 | for i = zcount; i < size && out[i] == 0; i++ {
96 | }
97 |
98 | // Now encode the values with actual alphabet in-place
99 | val := out[i-zcount:]
100 | size = len(val)
101 | for i = 0; i < size; i++ {
102 | out[i] = enc.encode[val[i]]
103 | }
104 |
105 | return out[:size]
106 | }
107 |
108 | // EncodeToString encodes binary bytes into Base92 bytes.
109 | func (enc *Encoding) EncodeToString(bin []byte) string {
110 | return string(enc.Encode(bin))
111 | }
112 |
113 | /*
114 | * Decoder
115 | */
116 |
117 | // Decode decodes src using the encoding enc.
118 | func (enc *Encoding) Decode(src []byte) ([]byte, error) {
119 | return enc.DecodeString(string(src))
120 | }
121 |
122 | // DecodeString decodes a Base92 string into binary bytes.
123 | func (enc *Encoding) DecodeString(str string) ([]byte, error) {
124 | if len(str) == 0 {
125 | return nil, nil
126 | }
127 |
128 | zero := enc.encode[0]
129 | strLen := len(str)
130 |
131 | var zcount int
132 | for i := 0; i < strLen && str[i] == zero; i++ {
133 | zcount++
134 | }
135 |
136 | var t, c uint64
137 |
138 | // the 32bit algo stretches the result up to 2 times
139 | binu := make([]byte, 2*((strLen*denominator/numerator)+1))
140 | outi := make([]uint32, (strLen+3)/4)
141 |
142 | for _, r := range str {
143 | if r > 127 {
144 | return nil, fmt.Errorf("go-encoding/base92: high-bit set on invalid digit")
145 | }
146 |
147 | if enc.decodeMap[r] == 0xff {
148 | return nil, fmt.Errorf("go-encoding/base92: invalid digit %q", r)
149 | }
150 |
151 | c = uint64(enc.decodeMap[r])
152 |
153 | for j := len(outi) - 1; j >= 0; j-- {
154 | t = uint64(outi[j])*92 + c
155 | c = t >> 32
156 | outi[j] = uint32(t & 0xffffffff)
157 | }
158 | }
159 |
160 | // initial mask depends on b92sz,
161 | // on further loops it always starts at 24 bits
162 | mask := (uint(strLen%4) * 8)
163 | if mask == 0 {
164 | mask = 32
165 | }
166 | mask -= 8
167 |
168 | outLen := 0
169 | for j := 0; j < len(outi); j++ {
170 | // loop relies on uint overflow
171 | for mask < 32 {
172 | binu[outLen] = byte(outi[j] >> mask)
173 | mask -= 8
174 | outLen++
175 | }
176 |
177 | mask = 24
178 | }
179 |
180 | // find the most significant byte post-decode, if any
181 | for msb := zcount; msb < len(binu); msb++ {
182 | if binu[msb] > 0 {
183 | return binu[msb-zcount : outLen], nil
184 | }
185 | }
186 |
187 | return binu[:outLen], nil
188 | }
189 |
--------------------------------------------------------------------------------
/base92/base92_test.go:
--------------------------------------------------------------------------------
1 | package base92
2 |
3 | import (
4 | "bytes"
5 | "reflect"
6 | "testing"
7 | )
8 |
9 | var cases = []struct {
10 | name string
11 | bin []byte
12 | }{
13 | {"nil", nil},
14 | {"empty", []byte{}},
15 | {"zero", []byte{0}},
16 | {"one", []byte{1}},
17 | {"two", []byte{2}},
18 | {"ten", []byte{10}},
19 | {"2zeros", []byte{0, 0}},
20 | {"2ones", []byte{1, 1}},
21 | {"64zeros", []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
22 | {"65zeros", []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
23 | {"ascii", []byte("c'est une longue chanson")},
24 | {"utf8", []byte("Garçon, un café très fort !")},
25 | }
26 |
27 | func Test_Encode(t *testing.T) {
28 | for _, c := range cases {
29 | t.Run(c.name, func(t *testing.T) {
30 | str := StdEncoding.EncodeToString(c.bin)
31 |
32 | ni := len(c.bin)
33 | if ni > 70 {
34 | ni = 70 // print max the first 70 bytes
35 | }
36 | na := len(str)
37 | if na > 70 {
38 | na = 70 // print max the first 70 characters
39 | }
40 | t.Logf("bin len=%d [:%d]=%v", len(c.bin), ni, c.bin[:ni])
41 | t.Logf("str len=%d [:%d]=%q", len(str), na, str[:na])
42 |
43 | got, err := StdEncoding.DecodeString(str)
44 | if err != nil {
45 | t.Errorf("Decode() error = %v", err)
46 | return
47 | }
48 |
49 | ng := len(got)
50 | if ng > 70 {
51 | ng = 70 // print max the first 70 bytes
52 | }
53 | t.Logf("got len=%d [:%d]=%v", len(got), ng, got[:ng])
54 |
55 | if (len(got) == 0) && (len(c.bin) == 0) {
56 | return
57 | }
58 |
59 | if !reflect.DeepEqual(got, c.bin) {
60 | t.Errorf("Decode() = %v, want %v", got, c.bin)
61 | }
62 | })
63 | }
64 | }
65 |
66 | func Test_Encode2(t *testing.T) {
67 | for _, s := range SamplesStd {
68 | encoded := string(StdEncoding.Encode(s.sourceBytes))
69 | if len(encoded) == len(s.target) && encoded == s.target {
70 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
71 | } else {
72 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), encoded, len(encoded))
73 | }
74 | }
75 | }
76 |
77 | func Test_Decode2(t *testing.T) {
78 | for _, s := range SamplesStd {
79 | decoded, err := StdEncoding.Decode(s.targetBytes)
80 | if err != nil {
81 | t.Error(err)
82 | continue
83 | }
84 |
85 | if bytes.Equal(decoded, s.sourceBytes) {
86 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
87 | } else {
88 | str := string(decoded)
89 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
90 | }
91 | }
92 | }
93 |
94 | func Test_EncodeToString(t *testing.T) {
95 | for _, s := range SamplesStd {
96 | encoded := StdEncoding.EncodeToString([]byte(s.source))
97 | if len(encoded) == len(s.target) && encoded == s.target {
98 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
99 | } else {
100 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), encoded, len(encoded))
101 | }
102 | }
103 | }
104 |
105 | func Test_DecodeString(t *testing.T) {
106 | for _, s := range SamplesStd {
107 | decoded, err := StdEncoding.DecodeString(s.target)
108 | if err != nil {
109 | t.Error(err)
110 | continue
111 | }
112 |
113 | if bytes.Equal(decoded, s.sourceBytes) {
114 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
115 | } else {
116 | str := string(decoded)
117 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
118 | }
119 | }
120 | }
121 |
122 | func Test_EncodeWithCustomAlphabet(t *testing.T) {
123 | for _, s := range SamplesWithAlphabet {
124 | encoded := NewEncoding(s.alphabet).EncodeToString(s.sourceBytes)
125 | if encoded == s.target {
126 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
127 | } else {
128 | str := string(encoded)
129 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), str, len(str))
130 | }
131 | }
132 | }
133 |
134 | func Test_DecodeWithCustomAlphabet(t *testing.T) {
135 | for _, s := range SamplesWithAlphabet {
136 | decoded, err := NewEncoding(s.alphabet).DecodeString(s.target)
137 | if err != nil {
138 | t.Error(err)
139 | continue
140 | }
141 | if bytes.Equal(decoded, s.sourceBytes) {
142 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
143 | } else {
144 | str := string(decoded)
145 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
146 | }
147 | }
148 | }
149 |
150 | func Test_DecodeError(t *testing.T) {
151 | for _, s := range SamplesErr {
152 | decoded, err := StdEncoding.DecodeString(s.target)
153 | if err != nil {
154 | t.Logf("%s: \"%c\"", err.Error(), err)
155 | continue
156 | }
157 |
158 | str := string(decoded)
159 | t.Errorf("An error should have occurred, instead of returning \"%s\"", str)
160 | }
161 | }
162 |
163 | func NewSample(source, target string) *Sample {
164 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target)}
165 | }
166 |
167 | func NewSampleWithAlphabet(source, target, alphabet string) *Sample {
168 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target), alphabet: alphabet}
169 | }
170 |
171 | // encodeStdTest use encodeStd to replace `;"` to ` '`
172 | const encodeStdTest = " !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"
173 | const encodeStdTest2 = "!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~"
174 |
175 | type Sample struct {
176 | source string
177 | target string
178 | sourceBytes []byte
179 | targetBytes []byte
180 | alphabet string
181 | }
182 |
183 | var SamplesStd = []*Sample{
184 | NewSample("", ""),
185 | NewSample("f", "1a"),
186 | NewSample("fo", "393"),
187 | NewSample("foo", "8VdP"),
188 | NewSample("foob", "n\"1=`"),
189 | NewSample("fooba", "=/o>zJ"),
190 | NewSample("foobar", "21!/2`*G"),
191 |
192 | NewSample("su", "3Jp"),
193 | NewSample("sur", "9+`>"),
194 | NewSample("sure", "r3U-1"),
195 | NewSample("sure.", "(m5^vq"),
196 | NewSample("asure.", "1#+m[Bem"),
197 | NewSample("easure.", "5PN!3(DX>"),
198 | NewSample("leasure.", "gN#iXt$=}e"),
199 |
200 | NewSample("=", "Z"),
201 | NewSample(">", "."),
202 | NewSample("?", "-"),
203 | NewSample("11", "1I@"),
204 | NewSample("111", "4c@|"),
205 | NewSample("1111", "bL{~5"),
206 | NewSample("11111", "w5iL>F"),
207 | NewSample("111111", "~iHN3eV"),
208 |
209 | NewSample("Hello, World!", "k3f/B6!rQL=RhJ?d"),
210 | NewSample("你好,世界!", "1m&5KqaKycjNt]Y8I0FkS:x"),
211 | NewSample("こんにちは", "5rIFEY^zgV@2jOj{s|z"),
212 | NewSample("안녕하십니까", "1q=eNur3aBy#78Cu:Zjn[`A"),
213 |
214 | NewSample(string([]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}), "01hQh.Jm{XcF^"),
215 | }
216 |
217 | var SamplesWithAlphabet = []*Sample{
218 | NewSampleWithAlphabet("", "", encodeStdTest),
219 | NewSampleWithAlphabet("f", "!+", encodeStdTest),
220 | NewSampleWithAlphabet("fo", "$*$", encodeStdTest),
221 | NewSampleWithAlphabet("foo", ")[.U", encodeStdTest),
222 | NewSampleWithAlphabet("foob", "8~!e}", encodeStdTest),
223 | NewSampleWithAlphabet("fooba", "eh9mEO", encodeStdTest),
224 | NewSampleWithAlphabet("foobar", "#!gh#}iL", encodeStdTest),
225 |
226 | NewSampleWithAlphabet("su", "$O:", encodeStdTest),
227 | NewSampleWithAlphabet("sur", "*d}m", encodeStdTest),
228 | NewSampleWithAlphabet("sure", "=$Zb!", encodeStdTest),
229 | NewSampleWithAlphabet("sure.", "n7&fA<", encodeStdTest),
230 | NewSampleWithAlphabet("asure.", "!wd7pG/7", encodeStdTest),
231 | NewSampleWithAlphabet("easure.", "&USg$nI^m", encodeStdTest),
232 | NewSampleWithAlphabet("leasure.", "1Sw3^?ves/", encodeStdTest),
233 |
234 | NewSampleWithAlphabet("=", "`", encodeStdTest),
235 | NewSampleWithAlphabet(">", "a", encodeStdTest),
236 | NewSampleWithAlphabet("?", "b", encodeStdTest),
237 | NewSampleWithAlphabet("11", "!Nt", encodeStdTest),
238 | NewSampleWithAlphabet("111", "%-tx", encodeStdTest),
239 | NewSampleWithAlphabet("1111", ",Qr|&", encodeStdTest),
240 | NewSampleWithAlphabet("11111", "B&3QmK", encodeStdTest),
241 | NewSampleWithAlphabet("111111", "|3MS$/[", encodeStdTest),
242 |
243 | NewSampleWithAlphabet("Hello, World!", "5$0hG'g=VQeW2Oj.", encodeStdTest),
244 | NewSampleWithAlphabet("你好,世界!", "!7k&P<+PD-4S?q_)N K5XcC", encodeStdTest),
245 | NewSampleWithAlphabet("こんにちは", "&=NKJ_fE1[t#4T4r>xE", encodeStdTest),
246 | NewSampleWithAlphabet("안녕하십니까", "! 0 {
69 | mod := new(big.Int)
70 | num.DivMod(num, big.NewInt(enc.radix), mod)
71 | output = alphabet[mod.Int64()] + output
72 | }
73 |
74 | for _, i := range input {
75 | if i != 0 {
76 | break
77 | }
78 |
79 | output = alphabet[0] + output
80 | }
81 |
82 | return
83 | }
84 |
85 | /*
86 | * Decoder
87 | */
88 |
89 | // Decode decodes src using the encoding enc.
90 | func (enc *Encoding) Decode(src []byte) ([]byte, error) {
91 | return enc.DecodeString(string(src))
92 | }
93 |
94 | // DecodeString decodes src using the encoding enc.
95 | func (enc *Encoding) DecodeString(input string) (output []byte, err error) {
96 | result := big.NewInt(0)
97 | multi := big.NewInt(1)
98 |
99 | currBig := new(big.Int)
100 | for i := len(input) - 1; i >= 0; i-- {
101 | curr := enc.decodeMap[input[i]]
102 | if curr == 0xff {
103 | err = fmt.Errorf("go-encoding/%s: Invalid input string at character \"%s\", position %d", enc.name, string(input[i]), i)
104 | return
105 | }
106 |
107 | currBig.SetInt64(int64(curr))
108 | currBig.Mul(multi, currBig)
109 | result.Add(result, currBig)
110 | multi.Mul(multi, big.NewInt(enc.radix))
111 | }
112 |
113 | resultBytes := result.Bytes()
114 | var numZeros int
115 | for numZeros = 0; numZeros < len(input); numZeros++ {
116 | if(input[numZeros] != enc.encode[0]) {
117 | break
118 | }
119 | }
120 |
121 | length := numZeros + len(resultBytes)
122 | output = make([]byte, length)
123 | copy(output[numZeros:], resultBytes)
124 |
125 | return
126 | }
127 |
--------------------------------------------------------------------------------
/baseenc/baseenc_test.go:
--------------------------------------------------------------------------------
1 | package baseenc
2 |
3 | import (
4 | "reflect"
5 | "testing"
6 | )
7 |
8 | const encodeBase36 = "0123456789abcdefghijklmnopqrstuvwxyz"
9 |
10 | var cases = []struct {
11 | name string
12 | bin []byte
13 | }{
14 | {"nil", nil},
15 | {"empty", []byte{}},
16 | {"zero", []byte{0}},
17 | {"one", []byte{1}},
18 | {"two", []byte{2}},
19 | {"ten", []byte{10}},
20 | {"2zeros", []byte{0, 0}},
21 | {"2ones", []byte{1, 1}},
22 | {"64zeros", []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
23 | {"65zeros", []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
24 | {"ascii", []byte("c'est une longue chanson")},
25 | {"utf8", []byte("Garçon, un café très fort !")},
26 | }
27 |
28 | func Test_Encode(t *testing.T) {
29 | base36 := NewEncoding("base36", 36, encodeBase36)
30 |
31 | for _, c := range cases {
32 | t.Run(c.name, func(t *testing.T) {
33 | str := base36.EncodeToString(c.bin)
34 |
35 | ni := len(c.bin)
36 | if ni > 70 {
37 | ni = 70 // print max the first 70 bytes
38 | }
39 | na := len(str)
40 | if na > 70 {
41 | na = 70 // print max the first 70 characters
42 | }
43 | t.Logf("bin len=%d [:%d]=%v", len(c.bin), ni, c.bin[:ni])
44 | t.Logf("str len=%d [:%d]=%q", len(str), na, str[:na])
45 |
46 | got, err := base36.DecodeString(str)
47 | if err != nil {
48 | t.Errorf("Decode() error = %v", err)
49 | return
50 | }
51 |
52 | ng := len(got)
53 | if ng > 70 {
54 | ng = 70 // print max the first 70 bytes
55 | }
56 | t.Logf("got len=%d [:%d]=%v", len(got), ng, got[:ng])
57 |
58 | if (len(got) == 0) && (len(c.bin) == 0) {
59 | return
60 | }
61 |
62 | if !reflect.DeepEqual(got, c.bin) {
63 | t.Errorf("Decode() = %v, want %v", got, c.bin)
64 | }
65 | })
66 | }
67 | }
68 |
69 | func Test_Encode_Check(t *testing.T) {
70 | base36 := NewEncoding("base36", 36, encodeBase36)
71 |
72 | var cases = []struct {
73 | name string
74 | src []byte
75 | enc string
76 | }{
77 | {
78 | "index-1",
79 | []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255},
80 | "0rwg9z1idsugqv3",
81 | },
82 | }
83 |
84 | for _, c := range cases {
85 | t.Run(c.name, func(t *testing.T) {
86 | str := base36.EncodeToString(c.src)
87 | if !reflect.DeepEqual(str, c.enc) {
88 | t.Errorf("EncodeToString() = %v, want %v", str, c.enc)
89 | }
90 |
91 | got, err := base36.DecodeString(c.enc)
92 | if err != nil {
93 | t.Fatal(err)
94 | }
95 |
96 | if !reflect.DeepEqual(got, c.src) {
97 | t.Errorf("DecodeString() = %v, want %v", got, c.src)
98 | }
99 | })
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/basex/basex.go:
--------------------------------------------------------------------------------
1 | package basex
2 |
3 | import (
4 | "fmt"
5 | "bytes"
6 | "errors"
7 | "unsafe"
8 | "reflect"
9 | "strconv"
10 | "math/big"
11 | )
12 |
13 | const (
14 | encodeBase2 = "01"
15 | encodeBase16 = "0123456789ABCDEF"
16 | encodeBase16Invalid = "0123456789abcdef"
17 | encodeBase32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
18 | encodeBase36 = "0123456789abcdefghijklmnopqrstuvwxyz"
19 | encodeBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
20 | encodeBase62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
21 | encodeBase62Random = "vPh7zZwA2LyU4bGq5tcVfIMxJi6XaSoK9CNp0OWljYTHQ8REnmu31BrdgeDkFs"
22 | encodeBase62Invalid = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
23 | )
24 |
25 | var (
26 | Base2Encoding = NewEncoding(encodeBase2)
27 | Base16Encoding = NewEncoding(encodeBase16)
28 | Base16InvalidEncoding = NewEncoding(encodeBase16Invalid)
29 | Base32Encoding = NewEncoding(encodeBase32)
30 | Base36Encoding = NewEncoding(encodeBase36)
31 | Base58Encoding = NewEncoding(encodeBase58)
32 | Base62Encoding = NewEncoding(encodeBase62)
33 | Base62RandomEncoding = NewEncoding(encodeBase62Random)
34 | Base62InvalidEncoding = NewEncoding(encodeBase62Invalid)
35 | )
36 |
37 | /*
38 | * Encodings
39 | */
40 |
41 | // An Encoding is a base radix encoding/decoding scheme defined by a radix-character alphabet.
42 | type Encoding struct {
43 | encode []rune
44 | decodeMap map[rune]int
45 | radix *big.Int
46 | }
47 |
48 | // NewEncoding returns a new Encoding defined by the given alphabet, which must
49 | // be a radix-byte string that does not contain CR or LF ('\r', '\n').
50 | // Example alphabets:
51 | // - base2: 01
52 | // - base16: 0123456789abcdef
53 | // - base32: 0123456789ABCDEFGHJKMNPQRSTVWXYZ
54 | // - base58: 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
55 | // - base62: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
56 | func NewEncoding(encoder string) *Encoding {
57 | for i := 0; i < len(encoder); i++ {
58 | if encoder[i] == '\n' || encoder[i] == '\r' {
59 | panic("go-encoding/basex: encoding alphabet contains newline character")
60 | }
61 | }
62 |
63 | runes := []rune(encoder)
64 | decodeMap := make(map[rune]int)
65 |
66 | enc := &Encoding{}
67 |
68 | for i := 0; i < len(runes); i++ {
69 | if _, ok := decodeMap[runes[i]]; ok {
70 | panic("go-encoding/basex: Ambiguous alphabet.")
71 | }
72 |
73 | decodeMap[runes[i]] = i
74 | }
75 |
76 | enc.encode = runes
77 | enc.decodeMap = decodeMap
78 | enc.radix = big.NewInt(int64(len(runes)))
79 |
80 | return enc
81 | }
82 |
83 | /*
84 | * Encoder
85 | */
86 |
87 | // Encode encodes binary bytes into bytes.
88 | func (enc *Encoding) Encode(source []byte) []byte {
89 | if len(source) == 0 {
90 | return nil
91 | }
92 |
93 | var (
94 | res bytes.Buffer
95 | k = 0
96 | )
97 |
98 | for ; source[k] == 0 && k < len(source)-1; k++ {
99 | res.WriteRune(enc.encode[0])
100 | }
101 |
102 | var (
103 | mod big.Int
104 | sourceInt = new(big.Int).SetBytes(source)
105 | )
106 |
107 | for sourceInt.Uint64() > 0 {
108 | sourceInt.DivMod(sourceInt, enc.radix, &mod)
109 | res.WriteRune(enc.encode[mod.Uint64()])
110 | }
111 |
112 | var (
113 | buf = res.Bytes()
114 | j = len(buf) - 1
115 | )
116 |
117 | for k < j {
118 | buf[k], buf[j] = buf[j], buf[k]
119 | k++
120 | j--
121 | }
122 |
123 | return buf
124 | }
125 |
126 | // EncodeToString returns the basex encoding of src.
127 | func (enc *Encoding) EncodeToString(src []byte) string {
128 | buf := enc.Encode(src)
129 | return string(buf)
130 | }
131 |
132 | // Decode decodes src using the encoding enc.
133 | func (enc *Encoding) Decode(source []byte) ([]byte, error) {
134 | if len(source) == 0 {
135 | return nil, nil
136 | }
137 |
138 | var (
139 | data = []rune(string(source))
140 | dest = big.NewInt(0)
141 | )
142 |
143 | for i := 0; i < len(data); i++ {
144 | value, ok := enc.decodeMap[data[i]]
145 | if !ok {
146 | return nil, errors.New("go-encoding/basex: non Base Character")
147 | }
148 |
149 | dest.Mul(dest, enc.radix)
150 | if value > 0 {
151 | dest.Add(dest, big.NewInt(int64(value)))
152 | }
153 | }
154 |
155 | k := 0
156 | for ; data[k] == enc.encode[0] && k < len(data)-1; k++ {
157 | }
158 |
159 | buf := dest.Bytes()
160 | res := make([]byte, k, k+len(buf))
161 |
162 | return append(res, buf...), nil
163 | }
164 |
165 | // DecodeString returns the bytes represented by the basex string s.
166 | func (enc *Encoding) DecodeString(s string) ([]byte, error) {
167 | sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
168 | bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
169 | return enc.Decode(*(*[]byte)(unsafe.Pointer(&bh)))
170 | }
171 |
172 | // 补码
173 | func (enc *Encoding) padding(s string, minlen int) string {
174 | if len(s) >= minlen {
175 | return s
176 | }
177 |
178 | format := fmt.Sprint(`%0`, strconv.Itoa(minlen), "s")
179 | return fmt.Sprintf(format, s)
180 | }
181 |
--------------------------------------------------------------------------------
/basex/basex_test.go:
--------------------------------------------------------------------------------
1 | package basex
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 | "reflect"
7 | )
8 |
9 | func Test_Encode(t *testing.T) {
10 | for _, s := range SamplesStd {
11 | encoded := Base62Encoding.EncodeToString([]byte(s.source))
12 | if len(encoded) == len(s.target) && encoded == s.target {
13 | t.Logf("source: %-15s\ttarget: %s", s.source, s.target)
14 | } else {
15 | t.Errorf("source: %-15s\texpected target: %s(%d)\tactual target: %s(%d)", s.source, s.target, len(s.target), encoded, len(encoded))
16 | }
17 | }
18 | }
19 |
20 | func Test_Decode(t *testing.T) {
21 | for _, s := range SamplesStd {
22 | decoded, err := Base62Encoding.DecodeString(s.target)
23 | if err != nil {
24 | t.Error(err)
25 | continue
26 | }
27 |
28 | if bytes.Equal(decoded, s.sourceBytes) {
29 | t.Logf("target: %-15s\tsource: %s", s.target, s.source)
30 | } else {
31 | str := string(decoded)
32 | t.Errorf("target: %-15s\texpected source: %s(%d)\tactual source: %s(%d)", s.target, s.source, len(s.source), str, len(str))
33 | }
34 | }
35 | }
36 |
37 | func Test_DecodeError(t *testing.T) {
38 | for _, s := range SamplesErr {
39 | decoded, err := Base62Encoding.DecodeString(s.target)
40 | if err != nil {
41 | t.Logf("%s: \"%c\"", err.Error(), err)
42 | continue
43 | }
44 |
45 | str := string(decoded)
46 | t.Errorf("An error should have occurred, instead of returning \"%s\"", str)
47 | }
48 | }
49 |
50 | func NewSample(source, target string) *Sample {
51 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target)}
52 | }
53 |
54 | func NewSampleWithAlphabet(source, target, alphabet string) *Sample {
55 | return &Sample{source: source, target: target, sourceBytes: []byte(source), targetBytes: []byte(target), alphabet: alphabet}
56 | }
57 |
58 | type Sample struct {
59 | source string
60 | target string
61 | sourceBytes []byte
62 | targetBytes []byte
63 | alphabet string
64 | }
65 |
66 | var SamplesStd = []*Sample{
67 | NewSample("", ""),
68 | NewSample("f", "1e"),
69 | NewSample("fo", "6ox"),
70 | NewSample("foo", "SAPP"),
71 | NewSample("foob", "1sIyuo"),
72 | NewSample("fooba", "7kENWa1"),
73 | NewSample("foobar", "VytN8Wjy"),
74 |
75 | NewSample("su", "7gj"),
76 | NewSample("sur", "VkRe"),
77 | NewSample("sure", "275mAn"),
78 | NewSample("sure.", "8jHquZ4"),
79 | NewSample("asure.", "UQPPAab8"),
80 | NewSample("easure.", "26h8PlupSA"),
81 | NewSample("leasure.", "9IzLUOIY2fe"),
82 |
83 | NewSample("=", "z"),
84 | NewSample(">", "10"),
85 | NewSample("?", "11"),
86 | NewSample("11", "3H7"),
87 | NewSample("111", "DWfh"),
88 | NewSample("1111", "tquAL"),
89 | NewSample("11111", "3icRuhV"),
90 | NewSample("111111", "FMElG7cn"),
91 |
92 | NewSample("Hello, World!", "1wJfrzvdbtXUOlUjUf"),
93 | NewSample("你好,世界!", "1ugmIChyMAcCbDRpROpAtpXdp"),
94 | NewSample("こんにちは", "1fyB0pNlcVqP3tfXZ1FmB"),
95 | NewSample("안녕하십니까", "1yl6dfHPaO9hroEXU9qFioFhM"),
96 | }
97 |
98 | var SamplesErr = []*Sample{
99 | NewSample("", "Hello, World!"),
100 | NewSample("", "哈哈"),
101 | NewSample("", "はは"),
102 | }
103 |
104 | func Test_Encode_Check(t *testing.T) {
105 | var cases = []struct {
106 | name string
107 | src []byte
108 | enc string
109 | }{
110 | {
111 | "index-1",
112 | []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255},
113 | "0rwg9z1idsugqv3",
114 | },
115 | }
116 |
117 | for _, c := range cases {
118 | t.Run(c.name, func(t *testing.T) {
119 | str := Base36Encoding.EncodeToString(c.src)
120 | if !reflect.DeepEqual(str, c.enc) {
121 | t.Errorf("EncodeToString() = %v, want %v", str, c.enc)
122 | }
123 |
124 | got, err := Base36Encoding.DecodeString(c.enc)
125 | if err != nil {
126 | t.Fatal(err)
127 | }
128 |
129 | if !reflect.DeepEqual(got, c.src) {
130 | t.Errorf("DecodeString() = %v, want %v", got, c.src)
131 | }
132 | })
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/bcd/bcd.go:
--------------------------------------------------------------------------------
1 | package bcd
2 |
3 | import (
4 | "errors"
5 | )
6 |
7 | func Encode(dataIn []byte) (out []byte) {
8 | dataInLen := len(dataIn)
9 |
10 | var posIn int = 0
11 | var posOut int = 0
12 | var nibbleFlag byte = 0
13 | var c byte = 0
14 |
15 | out = make([]byte, (dataInLen/2))
16 |
17 | for ; posIn < dataInLen; posIn++ {
18 | c = dataIn[posIn]
19 |
20 | if c >= '0' && c <= '9' {
21 | c -= '0'
22 | } else {
23 | switch {
24 | case c == 'A' || c == 'a':
25 | c = 0x0a
26 | case c == 'B' || c == 'b':
27 | c = 0x0b
28 | case c == 'C' || c == 'c':
29 | c = 0x0c
30 | case c == 'D' || c == 'd':
31 | c = 0x0d
32 | case c == 'E' || c == 'e':
33 | c = 0x0e
34 | case c == 'F' || c == 'f':
35 | c = 0x0f
36 | default:
37 | return nil
38 | }
39 | }
40 |
41 | if nibbleFlag == 0 {
42 | c <<= 4
43 | out[posOut] |= c
44 | nibbleFlag = 1
45 | } else {
46 | out[posOut] |= c
47 | posOut++
48 | nibbleFlag = 0
49 | }
50 | }
51 |
52 | return
53 | }
54 |
55 | func Decode(dataIn []byte) (out []byte) {
56 | dataInLen := len(dataIn)
57 |
58 | var posIn int = 0
59 | var posOut int = 0
60 |
61 | out = make([]byte, (dataInLen*2))
62 |
63 | for ; posIn < dataInLen; posIn++ {
64 | out[posOut] = nibbleToHexChar(dataIn[posIn] >> 4)
65 | posOut++
66 |
67 | out[posOut] = nibbleToHexChar(dataIn[posIn] & 0x0f)
68 | posOut++
69 | }
70 |
71 | return
72 | }
73 |
74 | func nibbleToHexChar(nibble byte) byte {
75 | if (nibble >= 0) && (nibble <= 9) {
76 | return nibble + '0'
77 | } else {
78 | switch {
79 | case nibble == 0x0a:
80 | return 'a'
81 | case nibble == 0x0b:
82 | return 'b'
83 | case nibble == 0x0c:
84 | return 'c'
85 | case nibble == 0x0d:
86 | return 'd'
87 | case nibble == 0x0e:
88 | return 'e'
89 | case nibble == 0x0f:
90 | return 'f'
91 | default:
92 | return ' '
93 | }
94 | }
95 | }
96 |
97 | // =======
98 |
99 | func CheckBCD(BCDvalue uint32) bool {
100 | for i := 0; i < 8; i++ {
101 | if (BCDvalue & 0x0F) > 0x09 {
102 | return false
103 | }
104 |
105 | BCDvalue >>= 4
106 | }
107 |
108 | return true
109 | }
110 |
111 | func Uint32ToBCD(BinaryValue uint32) (uint32, error) {
112 | if BinaryValue <= 99999999 {
113 | var ValueToReturn uint32 = 0
114 | var factor uint32 = 10000000
115 |
116 | for i := 0; i < 8; i++ {
117 | ValueToReturn <<= 4
118 |
119 | var temp uint32 = BinaryValue
120 |
121 | temp /= factor
122 | ValueToReturn |= temp
123 |
124 | temp *= factor
125 | BinaryValue -= temp
126 | factor /= 10;
127 | }
128 |
129 | return ValueToReturn, nil
130 | } else {
131 | return BinaryValue, errors.New("go-encoding/bcd: bad")
132 | }
133 | }
134 |
135 | func BCDtoUint32(CurrentBCDvalue uint32) (uint32, error) {
136 | if !CheckBCD(CurrentBCDvalue) {
137 | return CurrentBCDvalue, errors.New("go-encoding/bcd: bad")
138 | }
139 |
140 | var ValueToReturn uint32 = 0
141 | var factor uint32 = 1
142 |
143 | for i := 0; i < 8; i++ {
144 | var temp uint32 = CurrentBCDvalue
145 | temp &= 0x0F
146 | temp *= factor
147 | ValueToReturn += temp
148 | CurrentBCDvalue >>= 4
149 | factor *= 10
150 | }
151 |
152 | return ValueToReturn, nil
153 | }
154 |
--------------------------------------------------------------------------------
/bcd/bcd8421/bcd.go:
--------------------------------------------------------------------------------
1 | package bcd8421
2 |
3 | import "errors"
4 |
5 | var ErrNotBCD = errors.New("go-encoding/bcd8421: Byte is Not BCD Encoded")
6 |
7 | // uint8 to Packed BCD 8-4-2-1 One digit per nibble
8 | func Uint8toBCD(u uint8) byte {
9 | lsn := u % 10
10 | u /= 10
11 | msn := u % 10
12 | return ((msn & 0xf) << 4) | (lsn & 0xf)
13 | }
14 |
15 | // Packed BCD 8-4-2-1 One digit per nibble to uint8
16 | // Error if not a BCD digits
17 | func BCDtoUint8(bcd byte) (uint8, error) {
18 | digits := uint8((bcd>>4&0xf)*10 + (bcd & 0xf))
19 |
20 | // Confirm input is BCD encoded as expected
21 | check := Uint8toBCD(digits)
22 |
23 | if bcd != check|bcd {
24 | return digits, ErrNotBCD
25 | }
26 |
27 | return digits, nil
28 | }
29 |
--------------------------------------------------------------------------------
/bcd/bcd8421/bcd8421.go:
--------------------------------------------------------------------------------
1 | package bcd8421
2 |
3 | import (
4 | "fmt"
5 | "bytes"
6 | "strconv"
7 | )
8 |
9 | func EncodeFromString(number string, bytesLength int) ([]byte, error) {
10 | var numberBytes []byte
11 | var numberLength = len(number)
12 |
13 | if bytesLength*2 < numberLength {
14 | return numberBytes, fmt.Errorf("go-encoding/bcd8421: invalid bytesLength")
15 | }
16 |
17 | nb, err := stringNumberToBytes(number)
18 | if err != nil {
19 | return numberBytes, err
20 | }
21 | if numberLength%2 == 1 {
22 | nb = append([]byte{0x00}, nb...)
23 | }
24 | if fill := bytesLength*2 - len(nb); fill != 0 {
25 | nb = append(bytes.Repeat([]byte{0x00}, fill), nb...)
26 | }
27 |
28 | for i := 0; i < len(nb); i += 2 {
29 | n1 := nb[i]
30 | n2 := nb[i+1]
31 | n3 := n1 << 4
32 | numberBytes = append(numberBytes, n3|n2)
33 | }
34 |
35 | return numberBytes, nil
36 | }
37 |
38 | func DecodeToString(src []byte, skipzero bool) (string, error) {
39 | var s string
40 | var foundFirst bool
41 |
42 | for _, b := range src {
43 | if b == 0x00 && !foundFirst && skipzero {
44 | continue
45 | }
46 |
47 | n1 := b >> 4
48 |
49 | mask := b << 4
50 | n2 := mask<<4 | mask>>4
51 |
52 | if n1 > 9 || n2 > 9 {
53 | return s, fmt.Errorf("go-encoding/bcd8421: invalid BCD 8421 bytes")
54 | }
55 |
56 | if !skipzero {
57 | s += strconv.Itoa(int(n1))
58 | s += strconv.Itoa(int(n2))
59 | continue
60 | }
61 | if n1 != 0x00 && !foundFirst {
62 | foundFirst = true
63 | }
64 | if n1 != 0x00 || foundFirst {
65 | s += strconv.Itoa(int(n1))
66 | }
67 | if n2 != 0x00 && !foundFirst {
68 | foundFirst = true
69 | }
70 | if n2 != 0x00 || foundFirst {
71 | s += strconv.Itoa(int(n2))
72 | }
73 | }
74 |
75 | return s, nil
76 | }
77 |
78 | func stringNumberToBytes(number string) ([]byte, error) {
79 | const fnAtoi = "stringNumberToBytes"
80 |
81 | var b []byte
82 | for _, ch := range []byte(number) {
83 | ch -= '0'
84 | if ch > 9 {
85 | return b, &strconv.NumError{
86 | Func: fnAtoi,
87 | Num: number,
88 | Err: strconv.ErrSyntax,
89 | }
90 | }
91 |
92 | b = append(b, ch)
93 | }
94 |
95 | return b, nil
96 | }
97 |
--------------------------------------------------------------------------------
/bcd/bcd8421/bcd8421_test.go:
--------------------------------------------------------------------------------
1 | package bcd8421
2 |
3 | import (
4 | "reflect"
5 | "testing"
6 | )
7 |
8 | func TestStringNumberToBytes(t *testing.T) {
9 | should := []byte{0x00, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}
10 | b, err := stringNumberToBytes("0123456789")
11 | if err != nil {
12 | panic(err)
13 | }
14 |
15 | if !reflect.DeepEqual(b, should) {
16 | t.Errorf("should be %#v", should)
17 | }
18 | }
19 |
20 | var encodeTestcases = []struct {
21 | number string
22 | bytes []byte
23 | bytesLength int
24 | }{
25 | {
26 | number: "907865438",
27 | bytes: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x07, 0x86, 0x54, 0x38},
28 | bytesLength: 10,
29 | },
30 | {
31 | number: "9007865438",
32 | bytes: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x07, 0x86, 0x54, 0x38},
33 | bytesLength: 10,
34 | },
35 | {
36 | number: "90007865438",
37 | bytes: []byte{0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x07, 0x86, 0x54, 0x38},
38 | bytesLength: 10,
39 | },
40 | {
41 | number: "900007865438",
42 | bytes: []byte{0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x07, 0x86, 0x54, 0x38},
43 | bytesLength: 10,
44 | },
45 | {
46 | number: "9000007865438",
47 | bytes: []byte{0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07, 0x86, 0x54, 0x38},
48 | bytesLength: 10,
49 | },
50 | {
51 | number: "3830",
52 | bytes: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x30},
53 | bytesLength: 10,
54 | },
55 | {
56 | number: "38300",
57 | bytes: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x83, 0x00},
58 | bytesLength: 10,
59 | },
60 | {
61 | number: "383000",
62 | bytes: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x30, 0x00},
63 | bytesLength: 10,
64 | },
65 | {
66 | number: "3830000",
67 | bytes: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x83, 0x00, 0x00},
68 | bytesLength: 10,
69 | },
70 | }
71 |
72 | var decodeTestcases = []struct {
73 | number string
74 | bytes []byte
75 | skipzero bool
76 | }{
77 | {
78 | number: "060101150304",
79 | bytes: []byte{0x06, 0x01, 0x01, 0x15, 0x03, 0x04},
80 | },
81 | {
82 | number: "00060101150304",
83 | bytes: []byte{0x00, 0x06, 0x01, 0x01, 0x15, 0x03, 0x04},
84 | },
85 | {
86 | number: "60101150304",
87 | bytes: []byte{0x06, 0x01, 0x01, 0x15, 0x03, 0x04},
88 | skipzero: true,
89 | },
90 | {
91 | number: "60101150304",
92 | bytes: []byte{0x00, 0x06, 0x01, 0x01, 0x15, 0x03, 0x04},
93 | skipzero: true,
94 | },
95 | }
96 |
97 | func TestEncodeFromString(t *testing.T) {
98 | for _, tt := range encodeTestcases {
99 | ret, err := EncodeFromString(tt.number, tt.bytesLength)
100 | if err != nil {
101 | panic(err)
102 | }
103 | if !reflect.DeepEqual(ret, tt.bytes) {
104 | t.Errorf("EncodeFromString(%#v) = %#v; should be %#v", tt.number, ret, tt.bytes)
105 | }
106 | }
107 | }
108 |
109 | func TestDecodeToString(t *testing.T) {
110 | for _, tt := range decodeTestcases {
111 | n, err := DecodeToString(tt.bytes, tt.skipzero)
112 | if err != nil {
113 | panic(err)
114 | }
115 | if n != tt.number {
116 | t.Errorf("DecodeToString(%#v) = %s; should be %s", tt.bytes, n, tt.number)
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/bcd/bcd8421/bcd_test.go:
--------------------------------------------------------------------------------
1 | package bcd8421
2 |
3 | import "testing"
4 |
5 | func Test_Uint8toBCD(t *testing.T) {
6 | var tests = []struct {
7 | number uint8
8 | want byte
9 | }{
10 | {0, 0x00},
11 | {1, 0x01},
12 | {2, 0x02},
13 | {3, 0x03},
14 | {4, 0x04},
15 | {5, 0x05},
16 | {6, 0x06},
17 | {7, 0x07},
18 | {8, 0x08},
19 | {9, 0x09},
20 | {10, 0x10},
21 | {11, 0x11},
22 | {12, 0x12},
23 | {13, 0x13},
24 | {14, 0x14},
25 | {15, 0x15},
26 | {16, 0x16},
27 | {17, 0x17},
28 | {18, 0x18},
29 | {19, 0x19},
30 | {20, 0x20},
31 | }
32 | for _, tt := range tests {
33 | res := Uint8toBCD(tt.number)
34 | if res != tt.want {
35 | t.Errorf("number %d; , want %2.2x, got %2.2x\n", tt.number, tt.want, res)
36 | }
37 | }
38 | }
39 |
40 | func Test_BCDtoUint8(t *testing.T) {
41 | var tests = []struct {
42 | input byte
43 | want uint8
44 | err error
45 | }{
46 | {0x00, 0, nil},
47 | {0x01, 1, nil},
48 | {0x02, 2, nil},
49 | {0x03, 3, nil},
50 | {0x04, 4, nil},
51 | {0x05, 5, nil},
52 | {0x06, 6, nil},
53 | {0x07, 7, nil},
54 | {0x08, 8, nil},
55 | {0x09, 9, nil},
56 | {0x10, 10, nil},
57 | {0x11, 11, nil},
58 | {0x12, 12, nil},
59 | {0x13, 13, nil},
60 | {0x14, 14, nil},
61 | {0x15, 15, nil},
62 | {0x16, 16, nil},
63 | {0x17, 17, nil},
64 | {0x18, 18, nil},
65 | {0x19, 19, nil},
66 | {0x20, 20, nil},
67 | {0x1a, 20, ErrNotBCD},
68 | }
69 | for _, tt := range tests {
70 | res, err := BCDtoUint8(tt.input)
71 |
72 | if res != tt.want || err != tt.err {
73 | t.Errorf("number %2x; , want %d, error %s got %d\n, err %v", tt.input, tt.want, tt.err, res, err)
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/bcd/bcd_test.go:
--------------------------------------------------------------------------------
1 | package bcd
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 | "encoding/hex"
7 | )
8 |
9 | func fromHex(s string) []byte {
10 | h, _ := hex.DecodeString(s)
11 | return h
12 | }
13 |
14 | func toHex(str string) []byte {
15 | s := hex.EncodeToString([]byte(str))
16 | return []byte(s)
17 | }
18 |
19 | func fromString(s string) []byte {
20 | return []byte(s)
21 | }
22 |
23 | func Test_nibbleToHexChar(t *testing.T) {
24 | var tests = []struct {
25 | bin byte
26 | want byte
27 | }{
28 | {0x05, '5'},
29 | {0x0c, 'c'},
30 | }
31 |
32 | for i, tt := range tests {
33 | got := nibbleToHexChar(tt.bin)
34 | if got != tt.want {
35 | t.Errorf("[%d] bin %d, got %x, want %x", i, tt.bin, got, tt.want)
36 | }
37 | }
38 | }
39 |
40 | func Test_Encode(t *testing.T) {
41 | var tests = []struct {
42 | in []byte
43 | want []byte
44 | }{
45 | {
46 | fromString("1231"),
47 | fromHex("1231"),
48 | },
49 | {
50 | fromString("123ac1"),
51 | fromHex("123ac1"),
52 | },
53 | {
54 | toHex("ftgyhj"),
55 | fromHex("66746779686a"),
56 | },
57 | {
58 | toHex("ftgyhj;,klioyuiyt90-[[';lkl"),
59 | fromHex("66746779686a3b2c6b6c696f797569797439302d5b5b273b6c6b6c"),
60 | },
61 | }
62 |
63 | for i, tt := range tests {
64 | got := Encode(tt.in)
65 | if !bytes.Equal(got, tt.want) {
66 | t.Errorf("[%d] Encode, got %x, want %x", i, got, tt.want)
67 | }
68 | }
69 |
70 | // ========
71 |
72 | for i, tt := range tests {
73 | got := Decode(tt.want)
74 | if !bytes.Equal(got, tt.in) {
75 | t.Errorf("[%d] Decode, got %s, want %s", i, got, tt.in)
76 | }
77 | }
78 | }
79 |
80 | func Test_Uint32ToBCD(t *testing.T) {
81 | var tests = []struct {
82 | in uint32
83 | want uint32
84 | }{
85 | {0x05, 5},
86 | {0x0c, 18},
87 | }
88 |
89 | for i, tt := range tests {
90 | got, _ := Uint32ToBCD(tt.in)
91 | if got != tt.want {
92 | t.Errorf("[%d] Uint32ToBCD, got %d, want %d", i, got, tt.want)
93 | }
94 | }
95 |
96 | // =======
97 |
98 | for i, tt := range tests {
99 | got, _ := BCDtoUint32(tt.want)
100 | if got != tt.in {
101 | t.Errorf("[%d] BCDtoUint32, got %d, want %d", i, got, tt.in)
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/chaocipher/chaocipher.go:
--------------------------------------------------------------------------------
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 | }
169 |
--------------------------------------------------------------------------------
/chaocipher/chaocipher_test.go:
--------------------------------------------------------------------------------
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 | }
27 |
--------------------------------------------------------------------------------
/encoding/asn1.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "encoding/asn1"
5 | )
6 |
7 | // Asn1 Encode
8 | func (this Encoding) Asn1Encode(data any) Encoding {
9 | this.data, this.Error = asn1.Marshal(data)
10 |
11 | return this
12 | }
13 |
14 | // Asn1 Decode
15 | func (this Encoding) Asn1Decode(val any) Encoding {
16 | this.data, this.Error = asn1.Unmarshal(this.data, val)
17 |
18 | return this
19 | }
20 |
21 | // =============
22 |
23 | // Asn1 Encode
24 | func (this Encoding) Asn1EncodeWithParams(data any, params string) Encoding {
25 | this.data, this.Error = asn1.MarshalWithParams(data, params)
26 |
27 | return this
28 | }
29 |
30 | // Asn1 Decode
31 | func (this Encoding) Asn1DecodeWithParams(val any, params string) Encoding {
32 | this.data, this.Error = asn1.UnmarshalWithParams(this.data, val, params)
33 |
34 | return this
35 | }
36 |
--------------------------------------------------------------------------------
/encoding/asn1_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Asn1(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Asn1"
12 | data := "test-pass"
13 |
14 | en := FromString("").Asn1Encode(data)
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | var deStr string
20 | de := FromString(enStr).Asn1Decode(&deStr)
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
27 | func Test_Asn1Params(t *testing.T) {
28 | assert := assertT(t)
29 | assertError := assertErrorT(t)
30 |
31 | name := "Asn1Params"
32 | data := "test-pass"
33 | params := "testparams"
34 |
35 | en := FromString("").Asn1EncodeWithParams(data, params)
36 | enStr := en.ToString()
37 |
38 | assertError(en.Error, name + " Encode error")
39 |
40 | var deStr string
41 | de := FromString(enStr).Asn1DecodeWithParams(&deStr, params)
42 |
43 | assertError(de.Error, name + " Decode error")
44 |
45 | assert(data, deStr, name)
46 | }
47 |
--------------------------------------------------------------------------------
/encoding/base100.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/base100"
5 | )
6 |
7 | // Base100 Decode
8 | func (this Encoding) Base100Decode() Encoding {
9 | data := string(this.data)
10 | this.data, this.Error = base100.Decode(data)
11 |
12 | return this
13 | }
14 |
15 | // Base100 Encode
16 | func (this Encoding) Base100Encode() Encoding {
17 | data := base100.Encode(this.data)
18 | this.data = []byte(data)
19 |
20 | return this
21 | }
22 |
--------------------------------------------------------------------------------
/encoding/base100_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base100(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Base100"
12 | data := "test-pass"
13 |
14 | en := FromString(data).Base100Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Base100Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/base32.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "encoding/base32"
5 | )
6 |
7 | var (
8 | // newStr := NewBase32Encoding(encoder string).WithPadding(NoPadding).EncodeToString(src []byte)
9 | // newStr, err := NewBase32Encoding(encoder string).WithPadding(NoPadding).DecodeString(src string)
10 | NewBase32Encoding = base32.NewEncoding
11 | )
12 |
13 | // Decode Base32
14 | func (this Encoding) Base32Decode() Encoding {
15 | data := string(this.data)
16 | this.data, this.Error = base32.StdEncoding.DecodeString(data)
17 |
18 | return this
19 | }
20 |
21 | // Encode Base32
22 | func (this Encoding) Base32Encode() Encoding {
23 | data := base32.StdEncoding.EncodeToString(this.data)
24 | this.data = []byte(data)
25 |
26 | return this
27 | }
28 |
29 | // ===========
30 |
31 | // Decode Base32 raw
32 | func (this Encoding) Base32RawDecode() Encoding {
33 | data := string(this.data)
34 | this.data, this.Error = base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(data)
35 |
36 | return this
37 | }
38 |
39 | // Encode Base32 raw
40 | func (this Encoding) Base32RawEncode() Encoding {
41 | data := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(this.data)
42 | this.data = []byte(data)
43 |
44 | return this
45 | }
46 |
47 | // ===========
48 |
49 | // Decode Base32 Hex
50 | func (this Encoding) Base32HexDecode() Encoding {
51 | data := string(this.data)
52 | this.data, this.Error = base32.HexEncoding.DecodeString(data)
53 |
54 | return this
55 | }
56 |
57 | // Encode Base32 Hex
58 | func (this Encoding) Base32HexEncode() Encoding {
59 | data := base32.HexEncoding.EncodeToString(this.data)
60 | this.data = []byte(data)
61 |
62 | return this
63 | }
64 |
65 | // ===========
66 |
67 | // Decode Base32Hex raw
68 | func (this Encoding) Base32RawHexDecode() Encoding {
69 | data := string(this.data)
70 | this.data, this.Error = base32.HexEncoding.WithPadding(base32.NoPadding).DecodeString(data)
71 |
72 | return this
73 | }
74 |
75 | // Encode Base32Hex raw
76 | func (this Encoding) Base32RawHexEncode() Encoding {
77 | data := base32.HexEncoding.WithPadding(base32.NoPadding).EncodeToString(this.data)
78 | this.data = []byte(data)
79 |
80 | return this
81 | }
82 |
83 | // ===========
84 |
85 | // Decode Base32Encoder
86 | func (this Encoding) Base32DecodeWithEncoder(encoder string) Encoding {
87 | data := string(this.data)
88 | this.data, this.Error = base32.NewEncoding(encoder).DecodeString(data)
89 |
90 | return this
91 | }
92 |
93 | // Encode Base32Encoder
94 | func (this Encoding) Base32EncodeWithEncoder(encoder string) Encoding {
95 | data := base32.NewEncoding(encoder).EncodeToString(this.data)
96 | this.data = []byte(data)
97 |
98 | return this
99 | }
100 |
101 | // ===========
102 |
103 | // Decode Base32Encoder raw
104 | func (this Encoding) Base32RawDecodeWithEncoder(encoder string) Encoding {
105 | data := string(this.data)
106 | this.data, this.Error = base32.NewEncoding(encoder).WithPadding(base32.NoPadding).DecodeString(data)
107 |
108 | return this
109 | }
110 |
111 | // Encode Base32Encoder raw
112 | func (this Encoding) Base32RawEncodeWithEncoder(encoder string) Encoding {
113 | data := base32.NewEncoding(encoder).WithPadding(base32.NoPadding).EncodeToString(this.data)
114 | this.data = []byte(data)
115 |
116 | return this
117 | }
118 |
--------------------------------------------------------------------------------
/encoding/base32_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base32(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Base32"
12 | data := "test-pass"
13 |
14 | en := FromString(data).Base32Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Base32Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
27 | func Test_Base32Raw(t *testing.T) {
28 | assert := assertT(t)
29 | assertError := assertErrorT(t)
30 |
31 | name := "Base32"
32 | data := "test-pass"
33 |
34 | en := FromString(data).Base32RawEncode()
35 | enStr := en.ToString()
36 |
37 | assertError(en.Error, name + "Base32Raw- Encode error")
38 |
39 | de := FromString(enStr).Base32RawDecode()
40 | deStr := de.ToString()
41 |
42 | assertError(de.Error, name + "Base32Raw- Decode error")
43 |
44 | assert(data, deStr, name)
45 | }
46 |
47 | func Test_Base32Hex(t *testing.T) {
48 | assert := assertT(t)
49 | assertError := assertErrorT(t)
50 |
51 | name := "Base32Hex"
52 | data := "test-pass"
53 |
54 | en := FromString(data).Base32HexEncode()
55 | enStr := en.ToString()
56 |
57 | assertError(en.Error, name + " Encode error")
58 |
59 | de := FromString(enStr).Base32HexDecode()
60 | deStr := de.ToString()
61 |
62 | assertError(de.Error, name + " Decode error")
63 |
64 | assert(data, deStr, name)
65 | }
66 |
67 | func Test_Base32RawHex(t *testing.T) {
68 | assert := assertT(t)
69 | assertError := assertErrorT(t)
70 |
71 | name := "Base32Hex"
72 | data := "test-pass"
73 |
74 | en := FromString(data).Base32RawHexEncode()
75 | enStr := en.ToString()
76 |
77 | assertError(en.Error, name + "Base32RawHex- Encode error")
78 |
79 | de := FromString(enStr).Base32RawHexDecode()
80 | deStr := de.ToString()
81 |
82 | assertError(de.Error, name + "Base32RawHex- Decode error")
83 |
84 | assert(data, deStr, name)
85 | }
86 |
87 | func Test_Base32Encoder(t *testing.T) {
88 | assert := assertT(t)
89 | assertError := assertErrorT(t)
90 |
91 | name := "Base32Encoder"
92 | data := "test-pass"
93 |
94 | const encodeTest = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234569"
95 |
96 | en := FromString(data).Base32EncodeWithEncoder(encodeTest)
97 | enStr := en.ToString()
98 |
99 | assertError(en.Error, name + " Encode error")
100 |
101 | de := FromString(enStr).Base32DecodeWithEncoder(encodeTest)
102 | deStr := de.ToString()
103 |
104 | assertError(de.Error, name + " Decode error")
105 |
106 | assert(data, deStr, name)
107 | }
108 |
109 | func Test_Base32RawEncoder(t *testing.T) {
110 | assert := assertT(t)
111 | assertError := assertErrorT(t)
112 |
113 | name := "Base32Encoder"
114 | data := "test-pass"
115 |
116 | const encodeTest = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234569"
117 |
118 | en := FromString(data).Base32RawEncodeWithEncoder(encodeTest)
119 | enStr := en.ToString()
120 |
121 | assertError(en.Error, name + "Base32RawEncoder- Encode error")
122 |
123 | de := FromString(enStr).Base32RawDecodeWithEncoder(encodeTest)
124 | deStr := de.ToString()
125 |
126 | assertError(de.Error, name + "Base32RawEncoder- Decode error")
127 |
128 | assert(data, deStr, name)
129 | }
130 |
--------------------------------------------------------------------------------
/encoding/base36.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/base36"
5 | )
6 |
7 | // Decode Base36
8 | func (this Encoding) Base36Decode() Encoding {
9 | data := string(this.data)
10 | this.data, this.Error = base36.StdEncoding.DecodeString(data)
11 |
12 | return this
13 | }
14 |
15 | // Encode Base36
16 | func (this Encoding) Base36Encode() Encoding {
17 | data := base36.StdEncoding.EncodeToString(this.data)
18 | this.data = []byte(data)
19 |
20 | return this
21 | }
22 |
--------------------------------------------------------------------------------
/encoding/base36_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base36(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Base36"
12 | data := "test-pass"
13 |
14 | en := FromString(data).Base36Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Base36Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/base45.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/base45"
5 | )
6 |
7 | // Base45 Decode
8 | func (this Encoding) Base45Decode() Encoding {
9 | decoded, err := base45.StdEncoding.DecodeString(string(this.data))
10 |
11 | this.data = decoded
12 | this.Error = err
13 |
14 | return this
15 | }
16 |
17 | // Base45 Encode
18 | func (this Encoding) Base45Encode() Encoding {
19 | data := base45.StdEncoding.EncodeToString(this.data)
20 | this.data = []byte(data)
21 |
22 | return this
23 | }
24 |
--------------------------------------------------------------------------------
/encoding/base45_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base45(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Base45"
12 | data := "test-pass"
13 |
14 | en := FromString(data).Base45Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Base45Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/base58.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/base58"
5 | )
6 |
7 | // Base58 Decode
8 | func (this Encoding) Base58Decode() Encoding {
9 | data := string(this.data)
10 | this.data, this.Error = base58.StdEncoding.DecodeString(data)
11 |
12 | return this
13 | }
14 |
15 | // Base58 Encode
16 | func (this Encoding) Base58Encode() Encoding {
17 | data := base58.StdEncoding.EncodeToString(this.data)
18 | this.data = []byte(data)
19 |
20 | return this
21 | }
22 |
--------------------------------------------------------------------------------
/encoding/base58_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base58(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Base58"
12 | data := "test-pass"
13 |
14 | en := FromString(data).Base58Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Base58Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/base62.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/base62"
5 | )
6 |
7 | // Base62 Decode
8 | func (this Encoding) Base62Decode() Encoding {
9 | data := string(this.data)
10 | this.data, this.Error = base62.StdEncoding.DecodeString(data)
11 |
12 | return this
13 | }
14 |
15 | // Base62 Encode
16 | func (this Encoding) Base62Encode() Encoding {
17 | data := base62.StdEncoding.EncodeToString(this.data)
18 | this.data = []byte(data)
19 |
20 | return this
21 | }
22 |
--------------------------------------------------------------------------------
/encoding/base62_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base62(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | data := "test-pass"
12 | name := "Base62"
13 |
14 | en := FromString(data).Base62Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Base62Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/base64.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "strings"
5 | "encoding/base64"
6 | )
7 |
8 | var (
9 | // newStr := NewBase64Encoding(encoder string).WithPadding(NoPadding).EncodeToString(src []byte)
10 | // newStr, err := NewBase64Encoding(encoder string).WithPadding(NoPadding).DecodeString(src string)
11 | NewBase64Encoding = base64.NewEncoding
12 | )
13 |
14 | // Base64 Decode
15 | func (this Encoding) Base64Decode() Encoding {
16 | data := string(this.data)
17 | this.data, this.Error = base64.StdEncoding.DecodeString(data)
18 |
19 | return this
20 | }
21 |
22 | // Base64 Encode
23 | func (this Encoding) Base64Encode() Encoding {
24 | data := base64.StdEncoding.EncodeToString(this.data)
25 | this.data = []byte(data)
26 |
27 | return this
28 | }
29 |
30 | // ====================
31 |
32 | // Base64 URL Decode
33 | func (this Encoding) Base64URLDecode() Encoding {
34 | data := string(this.data)
35 | this.data, this.Error = base64.URLEncoding.DecodeString(data)
36 |
37 | return this
38 | }
39 |
40 | // Base64 URL Encode
41 | func (this Encoding) Base64URLEncode() Encoding {
42 | data := base64.URLEncoding.EncodeToString(this.data)
43 | this.data = []byte(data)
44 |
45 | return this
46 | }
47 |
48 | // ====================
49 |
50 | // Base64 Raw Decode
51 | func (this Encoding) Base64RawDecode() Encoding {
52 | data := string(this.data)
53 | this.data, this.Error = base64.RawStdEncoding.DecodeString(data)
54 |
55 | return this
56 | }
57 |
58 | // Base64 Raw Encode
59 | func (this Encoding) Base64RawEncode() Encoding {
60 | data := base64.RawStdEncoding.EncodeToString(this.data)
61 | this.data = []byte(data)
62 |
63 | return this
64 | }
65 |
66 | // ====================
67 |
68 | // Base64RawURL Decode
69 | func (this Encoding) Base64RawURLDecode() Encoding {
70 | data := string(this.data)
71 | this.data, this.Error = base64.RawURLEncoding.DecodeString(data)
72 |
73 | return this
74 | }
75 |
76 | // Base64RawURL Encode
77 | func (this Encoding) Base64RawURLEncode() Encoding {
78 | data := base64.RawURLEncoding.EncodeToString(this.data)
79 | this.data = []byte(data)
80 |
81 | return this
82 | }
83 |
84 | // ====================
85 |
86 | // Base64Segment Decode
87 | func (this Encoding) Base64SegmentDecode(paddingAllowed ...bool) Encoding {
88 | data := string(this.data)
89 |
90 | if len(paddingAllowed) > 0 && paddingAllowed[0] {
91 | if l := len(data) % 4; l > 0 {
92 | data += strings.Repeat("=", 4-l)
93 | }
94 |
95 | this.data, this.Error = base64.URLEncoding.DecodeString(data)
96 |
97 | return this
98 | }
99 |
100 | this.data, this.Error = base64.RawURLEncoding.DecodeString(data)
101 |
102 | return this
103 | }
104 |
105 | // Base64Segment Encode
106 | func (this Encoding) Base64SegmentEncode() Encoding {
107 | data := base64.RawURLEncoding.EncodeToString(this.data)
108 | this.data = []byte(data)
109 |
110 | return this
111 | }
112 |
113 | // ====================
114 |
115 | // Base64 Decode With Encoder
116 | func (this Encoding) Base64DecodeWithEncoder(encoder string) Encoding {
117 | data := string(this.data)
118 | this.data, this.Error = base64.NewEncoding(encoder).DecodeString(data)
119 |
120 | return this
121 | }
122 |
123 | // Base64 Encode With Encoder
124 | func (this Encoding) Base64EncodeWithEncoder(encoder string) Encoding {
125 | data := base64.NewEncoding(encoder).EncodeToString(this.data)
126 | this.data = []byte(data)
127 |
128 | return this
129 | }
130 |
--------------------------------------------------------------------------------
/encoding/base64_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base64(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | data := "test-pass"
12 |
13 | en := FromString(data).Base64Encode()
14 | enStr := en.ToString()
15 |
16 | assertError(en.Error, "Base64 Encode error")
17 |
18 | de := FromString(enStr).Base64Decode()
19 | deStr := de.ToString()
20 |
21 | assertError(de.Error, "Base64 Decode error")
22 |
23 | assert(data, deStr, "Base64")
24 | }
25 |
26 | func Test_Base64URL(t *testing.T) {
27 | assert := assertT(t)
28 | assertError := assertErrorT(t)
29 |
30 | data := "test-pass"
31 |
32 | en := FromString(data).Base64URLEncode()
33 | enStr := en.ToString()
34 |
35 | assertError(en.Error, "Base64URL Encode error")
36 |
37 | de := FromString(enStr).Base64URLDecode()
38 | deStr := de.ToString()
39 |
40 | assertError(de.Error, "Base64URL Decode error")
41 |
42 | assert(data, deStr, "Base64URL")
43 | }
44 |
45 | func Test_Base64Raw(t *testing.T) {
46 | assert := assertT(t)
47 | assertError := assertErrorT(t)
48 |
49 | data := "test-pass"
50 |
51 | en := FromString(data).Base64RawEncode()
52 | enStr := en.ToString()
53 |
54 | assertError(en.Error, "Base64Raw Encode error")
55 |
56 | de := FromString(enStr).Base64RawDecode()
57 | deStr := de.ToString()
58 |
59 | assertError(de.Error, "Base64Raw Decode error")
60 |
61 | assert(data, deStr, "Base64Raw")
62 | }
63 |
64 | func Test_Base64RawURL(t *testing.T) {
65 | assert := assertT(t)
66 | assertError := assertErrorT(t)
67 |
68 | data := "test-pass"
69 |
70 | en := FromString(data).Base64RawURLEncode()
71 | enStr := en.ToString()
72 |
73 | assertError(en.Error, "Base64RawURL Encode error")
74 |
75 | de := FromString(enStr).Base64RawURLDecode()
76 | deStr := de.ToString()
77 |
78 | assertError(de.Error, "Base64RawURL Decode error")
79 |
80 | assert(data, deStr, "Base64RawURL")
81 | }
82 |
83 | func Test_Base64Segment(t *testing.T) {
84 | assert := assertT(t)
85 | assertError := assertErrorT(t)
86 |
87 | data := "test-pass"
88 |
89 | en := FromString(data).Base64SegmentEncode()
90 | enStr := en.ToString()
91 |
92 | assertError(en.Error, "Base64Segment Encode error")
93 |
94 | de := FromString(enStr).Base64SegmentDecode()
95 | deStr := de.ToString()
96 |
97 | assertError(de.Error, "Base64Segment Decode error")
98 |
99 | assert(data, deStr, "Base64Segment")
100 | }
101 |
102 | func Test_Base64Encoder(t *testing.T) {
103 | assert := assertT(t)
104 | assertError := assertErrorT(t)
105 |
106 | data := "test-pass"
107 | const encodeTest = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789;/"
108 |
109 | en := FromString(data).Base64EncodeWithEncoder(encodeTest)
110 | enStr := en.ToString()
111 |
112 | assertError(en.Error, "Base64Encoder Encode error")
113 |
114 | de := FromString(enStr).Base64DecodeWithEncoder(encodeTest)
115 | deStr := de.ToString()
116 |
117 | assertError(de.Error, "Base64Encoder Decode error")
118 |
119 | assert(data, deStr, "Base64Encoder")
120 | }
121 |
122 |
--------------------------------------------------------------------------------
/encoding/base85.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "bytes"
5 | "encoding/ascii85"
6 | )
7 |
8 | // Base85 Decode
9 | func (this Encoding) Base85Decode() Encoding {
10 | src := this.data
11 |
12 | decodedText := make([]byte, len(src))
13 | decoded, _, err := ascii85.Decode(decodedText, src, true)
14 | if err != nil {
15 | this.Error = err
16 | return this
17 | }
18 |
19 | decodedText = decodedText[:decoded]
20 |
21 | this.data = bytes.Trim(decodedText, "\x00")
22 |
23 | return this
24 | }
25 |
26 | // Base85 Encode
27 | func (this Encoding) Base85Encode() Encoding {
28 | text := this.data
29 |
30 | dest := make([]byte, ascii85.MaxEncodedLen(len(text)))
31 | ascii85.Encode(dest, text)
32 |
33 | this.data = dest
34 |
35 | return this
36 | }
37 |
--------------------------------------------------------------------------------
/encoding/base85_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base85(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | data := "test-pass"
12 | name := "Base85"
13 |
14 | en := FromString(data).Base85Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Base85Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/base91.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/base91"
5 | )
6 |
7 | // Base91 Decode
8 | func (this Encoding) Base91Decode() Encoding {
9 | data := string(this.data)
10 | this.data, this.Error = base91.StdEncoding.DecodeString(data)
11 |
12 | return this
13 | }
14 |
15 | // Base91 Encode
16 | func (this Encoding) Base91Encode() Encoding {
17 | data := base91.StdEncoding.EncodeToString(this.data)
18 | this.data = []byte(data)
19 |
20 | return this
21 | }
22 |
--------------------------------------------------------------------------------
/encoding/base91_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base91(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Base91"
12 | data := "test-pass"
13 |
14 | en := FromString(data).Base91Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Base91Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/base92.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/base92"
5 | )
6 |
7 | // Base92 Decode
8 | func (this Encoding) Base92Decode() Encoding {
9 | data := string(this.data)
10 | this.data, this.Error = base92.StdEncoding.DecodeString(data)
11 |
12 | return this
13 | }
14 |
15 | // Base92 Encode
16 | func (this Encoding) Base92Encode() Encoding {
17 | data := base92.StdEncoding.EncodeToString(this.data)
18 | this.data = []byte(data)
19 |
20 | return this
21 | }
22 |
--------------------------------------------------------------------------------
/encoding/base92_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Base92(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Base92"
12 | data := "test-pass"
13 |
14 | en := FromString(data).Base92Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Base92Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/basex.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/basex"
5 | )
6 |
7 | // Basex2 Decode
8 | func (this Encoding) Basex2Decode() Encoding {
9 | data := string(this.data)
10 | this.data, this.Error = basex.Base2Encoding.DecodeString(data)
11 |
12 | return this
13 | }
14 |
15 | // Base2 Encode
16 | func (this Encoding) Basex2Encode() Encoding {
17 | data := basex.Base2Encoding.EncodeToString(this.data)
18 | this.data = []byte(data)
19 |
20 | return this
21 | }
22 |
23 | // ====================
24 |
25 | // Basex16 Decode
26 | func (this Encoding) Basex16Decode() Encoding {
27 | data := string(this.data)
28 | this.data, this.Error = basex.Base16Encoding.DecodeString(data)
29 |
30 | return this
31 | }
32 |
33 | // Base16 Encode
34 | func (this Encoding) Basex16Encode() Encoding {
35 | data := basex.Base16Encoding.EncodeToString(this.data)
36 | this.data = []byte(data)
37 |
38 | return this
39 | }
40 |
41 | // ====================
42 |
43 | // Basex62 Decode
44 | func (this Encoding) Basex62Decode() Encoding {
45 | data := string(this.data)
46 | this.data, this.Error = basex.Base62Encoding.DecodeString(data)
47 |
48 | return this
49 | }
50 |
51 | // Basex62 Encode
52 | func (this Encoding) Basex62Encode() Encoding {
53 | data := basex.Base62Encoding.EncodeToString(this.data)
54 | this.data = []byte(data)
55 |
56 | return this
57 | }
58 |
59 | // ====================
60 |
61 | // Basex Decode With Encoder
62 | func (this Encoding) BasexDecodeWithEncoder(encoder string) Encoding {
63 | data := string(this.data)
64 | this.data, this.Error = basex.NewEncoding(encoder).DecodeString(data)
65 |
66 | return this
67 | }
68 |
69 | // Basex Encode With Encoder
70 | func (this Encoding) BasexEncodeWithEncoder(encoder string) Encoding {
71 | data := basex.NewEncoding(encoder).EncodeToString(this.data)
72 | this.data = []byte(data)
73 |
74 | return this
75 | }
76 |
--------------------------------------------------------------------------------
/encoding/basex_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Basex2(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Basex2"
12 | data := "test-pass"
13 |
14 | en := FromString(data).Basex2Encode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).Basex2Decode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
27 | func Test_Basex16(t *testing.T) {
28 | assert := assertT(t)
29 | assertError := assertErrorT(t)
30 |
31 | name := "Basex16"
32 | data := "test-pass"
33 |
34 | en := FromString(data).Basex16Encode()
35 | enStr := en.ToString()
36 |
37 | assertError(en.Error, name + " Encode error")
38 |
39 | de := FromString(enStr).Basex16Decode()
40 | deStr := de.ToString()
41 |
42 | assertError(de.Error, name + " Decode error")
43 |
44 | assert(data, deStr, name)
45 | }
46 |
47 | func Test_Basex62(t *testing.T) {
48 | assert := assertT(t)
49 | assertError := assertErrorT(t)
50 |
51 | name := "Basex62"
52 | data := "test-pass"
53 |
54 | en := FromString(data).Basex62Encode()
55 | enStr := en.ToString()
56 |
57 | assertError(en.Error, name + " Encode error")
58 |
59 | de := FromString(enStr).Basex62Decode()
60 | deStr := de.ToString()
61 |
62 | assertError(de.Error, name + " Decode error")
63 |
64 | assert(data, deStr, name)
65 | }
66 |
67 | func Test_BasexEncoder(t *testing.T) {
68 | assert := assertT(t)
69 | assertError := assertErrorT(t)
70 |
71 | name := "Base32Encoder"
72 | data := "test-pass"
73 |
74 | const encodeTest = "ACDEFGHIJKLMNOPQRSTUVWXYZ234569"
75 |
76 | en := FromString(data).BasexEncodeWithEncoder(encodeTest)
77 | enStr := en.ToString()
78 |
79 | assertError(en.Error, name + " Encode error")
80 |
81 | de := FromString(enStr).BasexDecodeWithEncoder(encodeTest)
82 | deStr := de.ToString()
83 |
84 | assertError(de.Error, name + " Decode error")
85 |
86 | assert(data, deStr, name)
87 | }
88 |
--------------------------------------------------------------------------------
/encoding/binary.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "bytes"
5 | "encoding/binary"
6 | )
7 |
8 | // Binary Little Endian Encode
9 | func (this Encoding) BinaryLittleEndianEncode(data any) Encoding {
10 | buf := bytes.NewBuffer(nil)
11 |
12 | err := binary.Write(buf, binary.LittleEndian, data)
13 | if err != nil {
14 | this.Error = err
15 | return this
16 | }
17 |
18 | this.data = buf.Bytes()
19 |
20 | return this
21 | }
22 |
23 | // Binary Little Endian Decode
24 | func (this Encoding) BinaryLittleEndianDecode(dst any) Encoding {
25 | buf := bytes.NewBuffer(this.data)
26 |
27 | this.Error = binary.Read(buf, binary.LittleEndian, dst)
28 |
29 | return this
30 | }
31 |
32 | // ====================
33 |
34 | // Binary Big Endian Encode
35 | func (this Encoding) BinaryBigEndianEncode(data any) Encoding {
36 | buf := bytes.NewBuffer(nil)
37 |
38 | err := binary.Write(buf, binary.BigEndian, data)
39 | if err != nil {
40 | this.Error = err
41 | return this
42 | }
43 |
44 | this.data = buf.Bytes()
45 |
46 | return this
47 | }
48 |
49 | // Binary Big Endian Decode
50 | func (this Encoding) BinaryBigEndianDecode(dst any) Encoding {
51 | buf := bytes.NewBuffer(this.data)
52 |
53 | this.Error = binary.Read(buf, binary.BigEndian, dst)
54 |
55 | return this
56 | }
57 |
--------------------------------------------------------------------------------
/encoding/binary_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_BinaryLittleEndian(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | data := uint16(61375)
12 | name := "BinaryLittleEndian"
13 |
14 | en := FromString("").BinaryLittleEndianEncode(data)
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | var deStr uint16
20 | de := FromString(enStr).BinaryLittleEndianDecode(&deStr)
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
27 | func Test_BinaryBigEndian(t *testing.T) {
28 | assert := assertT(t)
29 | assertError := assertErrorT(t)
30 |
31 | data := uint16(61375)
32 | name := "BinaryBigEndian"
33 |
34 | en := FromString("").BinaryBigEndianEncode(data)
35 | enStr := en.ToString()
36 |
37 | assertError(en.Error, name + " Encode error")
38 |
39 | var deStr uint16
40 | de := FromString(enStr).BinaryBigEndianDecode(&deStr)
41 |
42 | assertError(de.Error, name + " Decode error")
43 |
44 | assert(data, deStr, name)
45 | }
46 |
47 | func Test_BinaryBigEndianBase64(t *testing.T) {
48 | assert := assertT(t)
49 | assertError := assertErrorT(t)
50 |
51 | data := uint16(61375)
52 | name := "BinaryBigEndianBase64"
53 |
54 | en := FromString("").BinaryBigEndianEncode(data).Base64Encode()
55 | enStr := en.ToString()
56 |
57 | assertError(en.Error, name + " Encode error")
58 |
59 | var deStr uint16
60 | de := FromString(enStr).Base64Decode().BinaryBigEndianDecode(&deStr)
61 |
62 | assertError(de.Error, name + " Decode error")
63 |
64 | assert(data, deStr, name)
65 | }
66 |
--------------------------------------------------------------------------------
/encoding/convert.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "errors"
5 | "strconv"
6 | )
7 |
8 | // 十进制转二进制
9 | // dec to bin
10 | func Decbin(number int64) string {
11 | return strconv.FormatInt(number, 2)
12 | }
13 |
14 | // 二进制转十进制
15 | // bin to dec
16 | func Bindec(str string) int64 {
17 | data, _ := strconv.ParseInt(str, 2, 0)
18 |
19 | return data
20 | }
21 |
22 | // 十进制转八进制
23 | // dec to oct
24 | func Decoct(number int64) string {
25 | return strconv.FormatInt(number, 8)
26 | }
27 |
28 | // 八进制转十进制
29 | // oct to dec
30 | func Octdec(str string) int64 {
31 | data, _ := strconv.ParseInt(str, 8, 0)
32 |
33 | return data
34 | }
35 |
36 | // 十进制转十六进制
37 | // dec to hex
38 | func Dechex(number int64) string {
39 | return strconv.FormatInt(number, 16)
40 | }
41 |
42 | // 十六进制转十进制
43 | // hex to dec
44 | func Hexdec(str string) int64 {
45 | data, _ := strconv.ParseInt(str, 16, 0)
46 |
47 | return data
48 | }
49 |
50 | // 各种进制互转
51 | // 十进制转十六进制
52 | // Base Convert
53 | // BaseConvert("12312", 10, 16)
54 | // [2- 36] 进制
55 | func BaseConvert(number string, frombase, tobase int) string {
56 | i, err := strconv.ParseInt(number, frombase, 0)
57 | if err != nil {
58 | return ""
59 | }
60 |
61 | return strconv.FormatInt(i, tobase)
62 | }
63 |
64 | // ====================
65 |
66 | // ConvertDecode
67 | // 给定类型数据格式化为string类型数据
68 | // bitSize 限制长度
69 | // ParseBool()、ParseFloat()、ParseInt()、ParseUint()。
70 | // FormatBool()、FormatInt()、FormatUint()、FormatFloat()、
71 | func (this Encoding) ConvertDecode(input any, base int, bitSize ...int) Encoding {
72 | newBitSize := 0
73 | if len(bitSize) > 0 {
74 | newBitSize = bitSize[0]
75 | }
76 |
77 | var number int64
78 | var err error
79 |
80 | switch input.(type) {
81 | case int:
82 | number = int64(input.(int))
83 | case int8:
84 | number = int64(input.(int8))
85 | case int16:
86 | number = int64(input.(int16))
87 | case int32:
88 | number = int64(input.(int32))
89 | case int64:
90 | number = input.(int64)
91 | case string:
92 | number, err = strconv.ParseInt(input.(string), base, newBitSize)
93 | if err != nil {
94 | this.Error = err
95 | return this
96 | }
97 | default:
98 | this.Error = errors.New("data error.")
99 | return this
100 | }
101 |
102 | // 转为10进制字符
103 | data := strconv.FormatInt(number, 10)
104 |
105 | this.data = []byte(data)
106 |
107 | return this
108 | }
109 |
110 | // 二进制
111 | // ConvertBinDecode
112 | func (this Encoding) ConvertBinDecode(data string) Encoding {
113 | return this.ConvertDecode(data, 2)
114 | }
115 |
116 | // 八进制
117 | // ConvertOctDecode
118 | func (this Encoding) ConvertOctDecode(data string) Encoding {
119 | return this.ConvertDecode(data, 8)
120 | }
121 |
122 | // 十进制
123 | // ConvertDecDecode
124 | func (this Encoding) ConvertDecDecode(data int64) Encoding {
125 | return this.ConvertDecode(data, 10)
126 | }
127 |
128 | // 十进制字符
129 | // ConvertDecStringDecode
130 | func (this Encoding) ConvertDecStringDecode(data string) Encoding {
131 | return this.ConvertDecode(data, 10)
132 | }
133 |
134 | // 十六进制
135 | // ConvertHexDecode
136 | func (this Encoding) ConvertHexDecode(data string) Encoding {
137 | return this.ConvertDecode(data, 16)
138 | }
139 |
140 | // ====================
141 |
142 | // 输出进制Encode
143 | // ConvertEncode
144 | func (this Encoding) ConvertEncode(base int) string {
145 | number, err := strconv.ParseInt(string(this.data), 10, 0)
146 | if err != nil {
147 | return ""
148 | }
149 |
150 | return strconv.FormatInt(number, base)
151 | }
152 |
153 | // 输出 二进制
154 | // ConvertBinEncode
155 | func (this Encoding) ConvertBinEncode() string {
156 | return this.ConvertEncode(2)
157 | }
158 |
159 | // 输出 八进制
160 | // ConvertOctEncode
161 | func (this Encoding) ConvertOctEncode() string {
162 | return this.ConvertEncode(8)
163 | }
164 |
165 | // 输出 十进制
166 | // ConvertDecEncode
167 | func (this Encoding) ConvertDecEncode() int64 {
168 | number, err := strconv.ParseInt(string(this.data), 10, 0)
169 | if err != nil {
170 | return 0
171 | }
172 |
173 | return number
174 | }
175 |
176 | // 输出 十进制
177 | // ConvertDecStringEncode
178 | func (this Encoding) ConvertDecStringEncode() string {
179 | return this.ConvertEncode(10)
180 | }
181 |
182 | // 输出 十六进制
183 | // ConvertHexEncode
184 | func (this Encoding) ConvertHexEncode() string {
185 | return this.ConvertEncode(16)
186 | }
187 |
--------------------------------------------------------------------------------
/encoding/csv.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "bytes"
5 | "errors"
6 | "strings"
7 | "reflect"
8 | "encoding/csv"
9 | )
10 |
11 | // Csv Encode
12 | func (this Encoding) CsvEncode(data [][]string) Encoding {
13 | buf := bytes.NewBuffer(nil)
14 |
15 | w := csv.NewWriter(buf)
16 | w.WriteAll(data)
17 |
18 | if err := w.Error(); err != nil {
19 | this.Error = err
20 | return this
21 | }
22 |
23 | this.data = buf.Bytes()
24 |
25 | return this
26 | }
27 |
28 | // Csv Decode
29 | func (this Encoding) CsvDecode(dst any, opts ...rune) Encoding {
30 | buf := strings.NewReader(string(this.data))
31 | r := csv.NewReader(buf)
32 |
33 | if len(opts) > 0 {
34 | // ';'
35 | r.Comma = opts[0]
36 | }
37 |
38 | if len(opts) > 1 {
39 | // '#'
40 | r.Comment = opts[1]
41 | }
42 |
43 | csvs, err := r.ReadAll()
44 | if err != nil {
45 | this.Error = err
46 | return this
47 | }
48 |
49 | // 获取最后指针
50 | dstValue := reflect.ValueOf(dst)
51 | for dstValue.Kind() == reflect.Pointer {
52 | dstValue = dstValue.Elem()
53 | }
54 |
55 | if !dstValue.IsValid() || dstValue.Kind() != reflect.Slice {
56 | this.Error = errors.New("Decode to data type is not slice")
57 | return this
58 | }
59 |
60 | if !dstValue.CanSet() {
61 | this.Error = errors.New("Decode to data not set")
62 | return this
63 | }
64 |
65 | dstData := make([]reflect.Value, 0)
66 | for _, csv := range csvs {
67 | dstData = append(dstData, reflect.ValueOf(csv))
68 | }
69 |
70 | dstDataArr := reflect.Append(dstValue, dstData...)
71 |
72 | dstValue.Set(dstDataArr)
73 |
74 | return this
75 | }
76 |
--------------------------------------------------------------------------------
/encoding/csv_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Csv(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Csv"
12 |
13 | records := [][]string{
14 | {"first_name", "last_name", "username"},
15 | {"Rob", "Pike", "rob"},
16 | {"Ken", "Thompson", "ken"},
17 | {"Robert", "Griesemer", "gri"},
18 | }
19 | in := `first_name,last_name,username
20 | Rob,Pike,rob
21 | Ken,Thompson,ken
22 | Robert,Griesemer,gri
23 | `
24 |
25 | en := FromString("").CsvEncode(records)
26 | enStr := en.ToString()
27 |
28 | assertError(en.Error, name + " Encode error")
29 | assert(in, enStr, name + " Encode")
30 |
31 | var deStr [][]string
32 | de := FromString(in).CsvDecode(&deStr)
33 |
34 | assertError(de.Error, name + " Decode error")
35 | assert(records, deStr, name + " Decode")
36 | }
37 |
--------------------------------------------------------------------------------
/encoding/data_set.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "sync"
5 | )
6 |
7 | type DataName interface {
8 | ~uint | ~int | ~string
9 | }
10 |
11 | /**
12 | * Data Set
13 | *
14 | * @create 2023-3-31
15 | * @author deatil
16 | */
17 | type DataSet[N DataName, M any] struct {
18 | // 锁定
19 | mu sync.RWMutex
20 |
21 | // 数据
22 | data map[N]func() M
23 | }
24 |
25 | // NewDataSet
26 | func NewDataSet[N DataName, M any]() *DataSet[N, M] {
27 | return &DataSet[N, M]{
28 | data: make(map[N]func() M),
29 | }
30 | }
31 |
32 | // Add
33 | func (this *DataSet[N, M]) Add(name N, data func() M) *DataSet[N, M] {
34 | this.mu.Lock()
35 | defer this.mu.Unlock()
36 |
37 | this.data[name] = data
38 |
39 | return this
40 | }
41 |
42 | // Has
43 | func (this *DataSet[N, M]) Has(name N) bool {
44 | this.mu.RLock()
45 | defer this.mu.RUnlock()
46 |
47 | if _, ok := this.data[name]; ok {
48 | return true
49 | }
50 |
51 | return false
52 | }
53 |
54 | // Get
55 | func (this *DataSet[N, M]) Get(name N) func() M {
56 | this.mu.RLock()
57 | defer this.mu.RUnlock()
58 |
59 | if data, ok := this.data[name]; ok {
60 | return data
61 | }
62 |
63 | return nil
64 | }
65 |
66 | // Remove
67 | func (this *DataSet[N, M]) Remove(name N) *DataSet[N, M] {
68 | this.mu.Lock()
69 | defer this.mu.Unlock()
70 |
71 | delete(this.data, name)
72 |
73 | return this
74 | }
75 |
76 | // Names
77 | func (this *DataSet[N, M]) Names() []N {
78 | names := make([]N, 0)
79 | for name, _ := range this.data {
80 | names = append(names, name)
81 | }
82 |
83 | return names
84 | }
85 |
86 | // All
87 | func (this *DataSet[N, M]) All() map[N]func() M {
88 | return this.data
89 | }
90 |
91 | // Clean
92 | func (this *DataSet[N, M]) Clean() {
93 | this.mu.Lock()
94 | defer this.mu.Unlock()
95 |
96 | for name, _ := range this.data {
97 | delete(this.data, name)
98 | }
99 | }
100 |
101 | // Len
102 | func (this *DataSet[N, M]) Len() int {
103 | return len(this.data)
104 | }
105 |
--------------------------------------------------------------------------------
/encoding/encoding.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | /**
4 | * Encode
5 | *
6 | * @create 2022-4-3
7 | * @author deatil
8 | */
9 | type Encoding struct {
10 | // data bytes
11 | data []byte
12 |
13 | // Error
14 | Error error
15 | }
16 |
17 | // NewEncoding
18 | func NewEncoding() Encoding {
19 | return Encoding{}
20 | }
21 |
22 | // New
23 | func New() Encoding {
24 | return NewEncoding()
25 | }
26 |
27 | // default Encoding
28 | var defaultEncoding = NewEncoding()
29 |
--------------------------------------------------------------------------------
/encoding/encoding_from.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "io"
5 | "bytes"
6 | )
7 |
8 | // From Bytes
9 | func (this Encoding) FromBytes(data []byte) Encoding {
10 | this.data = data
11 |
12 | return this
13 | }
14 |
15 | // FromBytes
16 | func FromBytes(data []byte) Encoding {
17 | return defaultEncoding.FromBytes(data)
18 | }
19 |
20 | // FromString
21 | func (this Encoding) FromString(data string) Encoding {
22 | this.data = []byte(data)
23 |
24 | return this
25 | }
26 |
27 | // FromString
28 | func FromString(data string) Encoding {
29 | return defaultEncoding.FromString(data)
30 | }
31 |
32 | // FromReader
33 | func (this Encoding) FromReader(reader io.Reader) Encoding {
34 | buf := bytes.NewBuffer(nil)
35 |
36 | if _, err := io.Copy(buf, reader); err != nil {
37 | this.Error = err
38 |
39 | return this
40 | }
41 |
42 | this.data = buf.Bytes()
43 |
44 | return this
45 | }
46 |
47 | // FromReader
48 | func FromReader(reader io.Reader) Encoding {
49 | return defaultEncoding.FromReader(reader)
50 | }
51 |
--------------------------------------------------------------------------------
/encoding/encoding_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | "reflect"
6 | )
7 |
8 | func assertT(t *testing.T) func(any, any, string) {
9 | return func(actual any, expected any, msg string) {
10 | if !reflect.DeepEqual(actual, expected) {
11 | t.Errorf("Failed %s: actual: %v, expected: %v", msg, actual, expected)
12 | }
13 | }
14 | }
15 |
16 | func assertErrorT(t *testing.T) func(error, string) {
17 | return func(err error, msg string) {
18 | if err != nil {
19 | t.Errorf("Failed %s: error: %+v", msg, err)
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/encoding/encoding_to.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "io"
5 | "bytes"
6 | )
7 |
8 | // output String
9 | func (this Encoding) String() string {
10 | return this.ToString()
11 | }
12 |
13 | // output Bytes
14 | func (this Encoding) ToBytes() []byte {
15 | return this.data
16 | }
17 |
18 | // output String
19 | func (this Encoding) ToString() string {
20 | return string(this.data)
21 | }
22 |
23 | // output io.Reader
24 | func (this Encoding) ToReader() io.Reader {
25 | return bytes.NewBuffer(this.data)
26 | }
27 |
--------------------------------------------------------------------------------
/encoding/encoding_use.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | // EncodeDecode接口
8 | type IEncoding interface {
9 | // Encode
10 | Encode([]byte, ...map[string]any) ([]byte, error)
11 |
12 | // Decode
13 | Decode([]byte, ...map[string]any) ([]byte, error)
14 | }
15 |
16 | // EncodeDecode
17 | var UseEncoding = NewDataSet[string, IEncoding]()
18 |
19 | // get Encoding
20 | func getEncoding(name string) (IEncoding, error) {
21 | if !UseEncoding.Has(name) {
22 | err := fmt.Errorf("Encoding: Encoding type [%s] is error.", name)
23 | return nil, err
24 | }
25 |
26 | // EncodeDecode
27 | newEncoding := UseEncoding.Get(name)
28 |
29 | return newEncoding(), nil
30 | }
31 |
32 | // Encode
33 | func (this Encoding) EncodeBy(name string, cfg ...map[string]any) Encoding {
34 | newEncoding, err := getEncoding(name)
35 | if err != nil {
36 | this.Error = err
37 | return this
38 | }
39 |
40 | this.data, this.Error = newEncoding.Encode(this.data, cfg...)
41 |
42 | return this
43 | }
44 |
45 | // Decode
46 | func (this Encoding) DecodeBy(name string, cfg ...map[string]any) Encoding {
47 | newEncoding, err := getEncoding(name)
48 | if err != nil {
49 | this.Error = err
50 | return this
51 | }
52 |
53 | this.data, this.Error = newEncoding.Decode(this.data, cfg...)
54 |
55 | return this
56 | }
57 |
--------------------------------------------------------------------------------
/encoding/encoding_use_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | "encoding/base64"
6 | )
7 |
8 | type testEncoding struct {}
9 |
10 | // Encode
11 | func (this testEncoding) Encode(data []byte, cfg ...map[string]any) ([]byte, error) {
12 | newData := base64.StdEncoding.EncodeToString(data)
13 |
14 | return []byte(newData), nil
15 | }
16 |
17 | // Decode
18 | func (this testEncoding) Decode(data []byte, cfg ...map[string]any) ([]byte, error) {
19 | return base64.StdEncoding.DecodeString(string(data))
20 | }
21 |
22 | func init() {
23 | UseEncoding.Add("TestEncoding", func() IEncoding {
24 | return testEncoding{}
25 | })
26 | }
27 |
28 | func Test_UseEncoding(t *testing.T) {
29 | assert := assertT(t)
30 | assertError := assertErrorT(t)
31 |
32 | data := "test-pass123"
33 |
34 | en := FromString(data).EncodeBy("TestEncoding")
35 | enStr := en.ToString()
36 |
37 | assertError(en.Error, "UseEncoding Encode error")
38 |
39 | de := FromString(enStr).DecodeBy("TestEncoding")
40 | deStr := de.ToString()
41 |
42 | assertError(de.Error, "UseEncoding Decode error")
43 |
44 | assert(data, deStr, "UseEncoding")
45 | }
46 |
--------------------------------------------------------------------------------
/encoding/gob.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "bytes"
5 | "encoding/gob"
6 | )
7 |
8 | // Gob Encode
9 | func (this Encoding) GobEncode(data any) Encoding {
10 | buf := bytes.NewBuffer(nil)
11 |
12 | enc := gob.NewEncoder(buf)
13 | err := enc.Encode(data)
14 | if err != nil {
15 | this.Error = err
16 | return this
17 | }
18 |
19 | this.data = buf.Bytes()
20 |
21 | return this
22 | }
23 |
24 | // Gob Decode
25 | func (this Encoding) GobDecode(dst any) Encoding {
26 | buf := bytes.NewBuffer(this.data)
27 | dec := gob.NewDecoder(buf)
28 |
29 | this.Error = dec.Decode(dst)
30 |
31 | return this
32 | }
33 |
--------------------------------------------------------------------------------
/encoding/gob_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Gob(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Gob"
12 | data := map[string]string{
13 | "key": "test-pass",
14 | "key2": "test-pass-Gob",
15 | }
16 |
17 | en := FromString("").GobEncode(data)
18 | enStr := en.ToString()
19 |
20 | assertError(en.Error, name + " Encode error")
21 |
22 | var deData map[string]string
23 | de := FromString(enStr).GobDecode(&deData)
24 |
25 | assertError(de.Error, name + " Decode error")
26 |
27 | assert(data["key"], deData["key"], name)
28 | assert(data["key2"], deData["key2"], name)
29 | }
30 |
--------------------------------------------------------------------------------
/encoding/hex.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "encoding/hex"
5 | )
6 |
7 | // Hex Decode
8 | func (this Encoding) HexDecode() Encoding {
9 | data := string(this.data)
10 | this.data, this.Error = hex.DecodeString(data)
11 |
12 | return this
13 | }
14 |
15 | // Hex Encode
16 | func (this Encoding) HexEncode() Encoding {
17 | data := hex.EncodeToString(this.data)
18 | this.data = []byte(data)
19 |
20 | return this
21 | }
22 |
--------------------------------------------------------------------------------
/encoding/hex_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Hex(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Hex"
12 | data := "test-pass"
13 |
14 | en := FromString(data).HexEncode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).HexDecode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/json.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "encoding/json"
5 |
6 | jsoniter "github.com/json-iterator/go"
7 | )
8 |
9 | // JSON Encode
10 | func (this Encoding) JSONEncode(data any) Encoding {
11 | this.data, this.Error = json.Marshal(data)
12 |
13 | return this
14 | }
15 |
16 | // JSON Decode
17 | func (this Encoding) JSONDecode(dst any) Encoding {
18 | this.Error = json.Unmarshal(this.data, dst)
19 |
20 | return this
21 | }
22 |
23 | // ====================
24 |
25 | // JSONIterator Encode
26 | func (this Encoding) JSONIteratorEncode(data any) Encoding {
27 | this.data, this.Error = jsoniter.Marshal(data)
28 |
29 | return this
30 | }
31 |
32 | // JSONIterator Indent Encode
33 | func (this Encoding) JSONIteratorIndentEncode(v any, prefix, indent string) Encoding {
34 | this.data, this.Error = jsoniter.MarshalIndent(v, prefix, indent)
35 |
36 | return this
37 | }
38 |
39 | // JSONIterator Decode
40 | func (this Encoding) JSONIteratorDecode(dst any) Encoding {
41 | this.Error = jsoniter.Unmarshal(this.data, dst)
42 |
43 | return this
44 | }
45 |
--------------------------------------------------------------------------------
/encoding/json_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_JSON(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "JSON"
12 | data := map[string]string{
13 | "key": "test-pass",
14 | "key2": "test-pass-JSON",
15 | }
16 |
17 | en := FromString("").JSONEncode(data)
18 | enStr := en.ToString()
19 |
20 | assertError(en.Error, name + " Encode error")
21 |
22 | var deData map[string]string
23 | de := FromString(enStr).JSONDecode(&deData)
24 |
25 | assertError(de.Error, name + " Decode error")
26 |
27 | assert(data["key"], deData["key"], name)
28 | assert(data["key2"], deData["key2"], name)
29 | }
30 |
31 | func Test_JSONIterator(t *testing.T) {
32 | assert := assertT(t)
33 | assertError := assertErrorT(t)
34 |
35 | name := "JSONIterator"
36 | data := map[string]string{
37 | "key": "test-pass",
38 | "key2": "test-pass-JSONIterator",
39 | }
40 |
41 | en := FromString("").JSONIteratorEncode(data)
42 | enStr := en.ToString()
43 |
44 | assertError(en.Error, name + " Encode error")
45 |
46 | var deData map[string]string
47 | de := FromString(enStr).JSONIteratorDecode(&deData)
48 |
49 | assertError(de.Error, name + " Decode error")
50 |
51 | assert(data["key"], deData["key"], name)
52 | assert(data["key2"], deData["key2"], name)
53 | }
54 |
--------------------------------------------------------------------------------
/encoding/morse.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/morse"
5 | )
6 |
7 | // MorseITU Decode
8 | func (this Encoding) MorseITUDecode() Encoding {
9 | data, err := morse.ITUEncoding.DecodeString(string(this.data))
10 |
11 | this.data = data
12 | this.Error = err
13 |
14 | return this
15 | }
16 |
17 | // MorseITU Encode
18 | func (this Encoding) MorseITUEncode() Encoding {
19 | data := morse.ITUEncoding.EncodeToString(this.data)
20 | this.data = []byte(data)
21 |
22 | return this
23 | }
24 |
--------------------------------------------------------------------------------
/encoding/morse_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_MorseITU(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "MorseITU"
12 | data := "testpass"
13 |
14 | en := FromString(data).MorseITUEncode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).MorseITUDecode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/puny.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/puny"
5 | )
6 |
7 | // PunyDecode Decode
8 | func (this Encoding) PunyDecode() Encoding {
9 | this.data, this.Error = puny.StdEncoding.Decode(this.data)
10 |
11 | return this
12 | }
13 |
14 | // Puny Encode
15 | func (this Encoding) PunyEncode() Encoding {
16 | this.data, this.Error = puny.StdEncoding.Encode(this.data)
17 |
18 | return this
19 | }
20 |
--------------------------------------------------------------------------------
/encoding/puny_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Puny(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Puny"
12 | data := "ó チツチノハフヘキキξεζοреё┢┣┮┐┑ 《《"
13 |
14 | en := FromString(data).PunyEncode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).PunyDecode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/quotedprintable.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "github.com/deatil/go-encoding/quotedprintable"
5 | )
6 |
7 | // quotedprintable Decode
8 | func (this Encoding) QuotedprintableDecode() Encoding {
9 | this.data, this.Error = quotedprintable.StdEncoding.Decode(this.data)
10 |
11 | return this
12 | }
13 |
14 | // quotedprintable Encode
15 | func (this Encoding) QuotedprintableEncode() Encoding {
16 | this.data, this.Error = quotedprintable.StdEncoding.Encode(this.data)
17 |
18 | return this
19 | }
20 |
--------------------------------------------------------------------------------
/encoding/quotedprintable_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Quotedprintable(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Quotedprintable"
12 | data := `quoted\nprin\rtabl e gt\tdf`
13 |
14 | en := FromString(data).QuotedprintableEncode()
15 | enStr := en.ToString()
16 |
17 | assertError(en.Error, name + " Encode error")
18 |
19 | de := FromString(enStr).QuotedprintableDecode()
20 | deStr := de.ToString()
21 |
22 | assertError(de.Error, name + " Decode error")
23 |
24 | assert(data, deStr, name)
25 | }
26 |
--------------------------------------------------------------------------------
/encoding/safe_url.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "net/url"
5 | )
6 |
7 | // SafeURL Decode
8 | func (this Encoding) SafeURLDecode() Encoding {
9 | data := string(this.data)
10 | dst, err := url.QueryUnescape(data)
11 |
12 | this.data = []byte(dst)
13 | this.Error = err
14 |
15 | return this
16 | }
17 |
18 | // SafeURL Encode
19 | func (this Encoding) SafeURLEncode() Encoding {
20 | data := url.QueryEscape(string(this.data))
21 | this.data = []byte(data)
22 |
23 | return this
24 | }
25 |
--------------------------------------------------------------------------------
/encoding/safe_url_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | )
7 |
8 | var safeUrlTests = []struct {
9 | input string
10 | output string
11 | }{
12 | {"", ""},
13 | {"www.github.com?tab=star&open=lt", "www.github.com%3Ftab%3Dstar%26open%3Dlt"},
14 | }
15 |
16 | func TestSafeURL_From(t *testing.T) {
17 | assert := assertT(t)
18 | assertError := assertErrorT(t)
19 |
20 | for index, test := range safeUrlTests {
21 | e := FromString(test.output).SafeURLDecode()
22 |
23 | t.Run(fmt.Sprintf("test_%d", index), func(t *testing.T) {
24 | assertError(e.Error, "SafeURL_From")
25 | assert(test.input, e.ToString(), "SafeURL_From")
26 | })
27 | }
28 | }
29 |
30 | func TestSafeURL_To(t *testing.T) {
31 | assert := assertT(t)
32 | assertError := assertErrorT(t)
33 |
34 | for index, test := range safeUrlTests {
35 | e := FromString(test.input).SafeURLEncode()
36 |
37 | t.Run(fmt.Sprintf("test_%d", index), func(t *testing.T) {
38 | assertError(e.Error, "SafeURL_To")
39 | assert(test.output, e.ToString(), "SafeURL_To")
40 | })
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/encoding/serialize.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "bytes"
5 | "reflect"
6 | "strconv"
7 | "encoding/gob"
8 | )
9 |
10 | // Serialize Encode
11 | func (this Encoding) SerializeEncode(data any) Encoding {
12 | this.data, this.Error = serialize(data)
13 |
14 | return this
15 | }
16 |
17 | // Serialize Decode
18 | func (this Encoding) SerializeDecode(val any) Encoding {
19 | this.Error = unserialize(this.data, val)
20 |
21 | return this
22 | }
23 |
24 | // serialize
25 | func serialize(value any) ([]byte, error) {
26 | if bytes, ok := value.([]byte); ok {
27 | return bytes, nil
28 | }
29 |
30 | switch v := reflect.ValueOf(value); v.Kind() {
31 | case reflect.Int,
32 | reflect.Int8,
33 | reflect.Int16,
34 | reflect.Int32,
35 | reflect.Int64:
36 | return []byte(strconv.FormatInt(v.Int(), 10)), nil
37 | case reflect.Uint,
38 | reflect.Uint8,
39 | reflect.Uint16,
40 | reflect.Uint32,
41 | reflect.Uint64:
42 | return []byte(strconv.FormatUint(v.Uint(), 10)), nil
43 | }
44 |
45 | var b bytes.Buffer
46 | encoder := gob.NewEncoder(&b)
47 |
48 | if err := encoder.Encode(value); err != nil {
49 | return nil, err
50 | }
51 |
52 | return b.Bytes(), nil
53 | }
54 |
55 | // unserialize
56 | func unserialize(data []byte, ptr any) (err error) {
57 | if bytes, ok := ptr.(*[]byte); ok {
58 | *bytes = data
59 | return nil
60 | }
61 |
62 | if v := reflect.ValueOf(ptr); v.Kind() == reflect.Ptr {
63 | switch p := v.Elem(); p.Kind() {
64 | case reflect.Int,
65 | reflect.Int8,
66 | reflect.Int16,
67 | reflect.Int32,
68 | reflect.Int64:
69 | var i int64
70 | i, err = strconv.ParseInt(string(data), 10, 64)
71 | if err != nil {
72 | return err
73 | }
74 |
75 | p.SetInt(i)
76 | return nil
77 |
78 | case reflect.Uint,
79 | reflect.Uint8,
80 | reflect.Uint16,
81 | reflect.Uint32,
82 | reflect.Uint64:
83 | var i uint64
84 | i, err = strconv.ParseUint(string(data), 10, 64)
85 | if err != nil {
86 | return err
87 | }
88 |
89 | p.SetUint(i)
90 | return nil
91 | }
92 | }
93 |
94 | b := bytes.NewBuffer(data)
95 | decoder := gob.NewDecoder(b)
96 |
97 | if err = decoder.Decode(ptr); err != nil {
98 | return err
99 | }
100 |
101 | return nil
102 | }
103 |
--------------------------------------------------------------------------------
/encoding/serialize_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Serialize(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | name := "Serialize"
12 | data := map[string]string{
13 | "key": "test-pass",
14 | "key2": "test-pass-key2",
15 | }
16 |
17 | en := FromString("").SerializeEncode(data)
18 | enStr := en.ToString()
19 |
20 | assertError(en.Error, name + " Encode error")
21 |
22 | var deData map[string]string
23 | de := FromString(enStr).SerializeDecode(&deData)
24 |
25 | assertError(de.Error, name + " Decode error")
26 |
27 | assert(data["key"], deData["key"], name)
28 | assert(data["key2"], deData["key2"], name)
29 | }
30 |
--------------------------------------------------------------------------------
/encoding/xml.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "bytes"
5 | "encoding/xml"
6 | )
7 |
8 | // Xml Decode
9 | func (this Encoding) XmlDecode(dst any) Encoding {
10 | buf := bytes.NewBuffer(this.data)
11 | dec := xml.NewDecoder(buf)
12 |
13 | this.Error = dec.Decode(dst)
14 |
15 | return this
16 | }
17 |
18 | // Xml Encode
19 | func (this Encoding) XmlEncode(data any) Encoding {
20 | buf := bytes.NewBuffer(nil)
21 |
22 | enc := xml.NewEncoder(buf)
23 | err := enc.Encode(data)
24 | if err != nil {
25 | this.Error = err
26 | return this
27 | }
28 |
29 | this.data = buf.Bytes()
30 |
31 | return this
32 | }
33 |
--------------------------------------------------------------------------------
/encoding/xml_test.go:
--------------------------------------------------------------------------------
1 | package encoding
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func Test_Xml(t *testing.T) {
8 | assert := assertT(t)
9 | assertError := assertErrorT(t)
10 |
11 | type Per struct {
12 | Name string
13 | Age int
14 | }
15 |
16 | name := "Xml"
17 | data := Per{
18 | Name: "kkk",
19 | Age: 12,
20 | }
21 |
22 | en := FromString("").XmlEncode(data)
23 | enStr := en.ToString()
24 |
25 | assertError(en.Error, name + " Encode error")
26 |
27 | var deData Per
28 | de := FromString(enStr).XmlDecode(&deData)
29 |
30 | assertError(de.Error, name + " Decode error")
31 |
32 | assert(data.Name, deData.Name, name)
33 | assert(data.Age, data.Age, name)
34 | }
35 |
--------------------------------------------------------------------------------
/example.md:
--------------------------------------------------------------------------------
1 | ### 使用
2 |
3 | ~~~go
4 | package main
5 |
6 | import (
7 | "fmt"
8 | "github.com/deatil/go-encoding/encoding"
9 | )
10 |
11 | type Per struct {
12 | Name string
13 | Age int
14 | }
15 |
16 | func main() {
17 | // Base64 编码后结果
18 | base64Data := encoding.
19 | FromString("use-data"). // 数据来源
20 | Base64Encode(). // 编码或者解码方式
21 | ToString() // 输出结果
22 | fmt.Println("Base64 编码后结果:", base64Data)
23 |
24 | // =====
25 |
26 | // Asn1 编码
27 | var p string
28 | encodeStr := encoding.Asn1Encode("test-data").Base64Encode().ToString()
29 | encoding.FromString("Ewl0ZXN0LWRhdGE=").Base64Decode().Asn1Decode(&p)
30 | encodeStr2 := p
31 |
32 | // XML 编码
33 | p := Per{
34 | Name: "kkk",
35 | Age: 12,
36 | }
37 |
38 | var p2 Per
39 |
40 | // 编码
41 | encodeStr := encoding.XmlEncode(p).Base64Encode().ToString()
42 | encoding.FromString("PFBlcj48TmFtZT5ra2s8L05hbWU+PEFnZT4xMjwvQWdlPjwvUGVyPg==").Base64Decode().XmlDecode(&p2)
43 |
44 | encodeStr2 := p2.Name
45 |
46 | // Binary 编码
47 | var p uint16
48 | encodeStr := encoding.BinaryLittleEndianEncode(uint16(61374)).Base64Encode().ToString()
49 | encoding.FromString("vu8=").Base64Decode().XmlDecode(&p)
50 |
51 | // Csv 编码
52 | records := [][]string{
53 | {"first_name", "last_name", "username"},
54 | {"Rob", "Pike", "rob"},
55 | {"Ken", "Thompson", "ken"},
56 | {"Robert", "Griesemer", "gri"},
57 | }
58 | in := `first_name,last_name,username
59 | "Rob","Pike",rob
60 | Ken,Thompson,ken
61 | "Robert","Griesemer","gri"
62 | `
63 | encodeStr := encoding.CsvEncode(records).ToString()
64 |
65 | var encodeStr2 [][]string
66 | encoding.FromString(in).CsvDecode(&encodeStr2)
67 |
68 |
69 | // Csv 编码2
70 | records := [][]string{
71 | {"first_name", "last_name", "username"},
72 | {"Rob", "Pike", "rob"},
73 | {"Ken", "Thompson", "ken"},
74 | {"Robert", "Griesemer", "gri"},
75 | }
76 | in := `first_name;last_name;username
77 | "Rob";"Pike";rob
78 | # lines beginning with a # character are ignored
79 | Ken;Thompson;ken
80 | "Robert";"Griesemer";"gri"
81 | `
82 | encodeStr := encoding.CsvEncode(records).ToString()
83 |
84 | var encodeStr2 [][]string
85 | encoding.FromString(in).CsvDecode(&encodeStr2, ';', '#')
86 | }
87 |
88 | ~~~
89 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/deatil/go-encoding
2 |
3 | go 1.20
4 |
5 | require github.com/json-iterator/go v1.1.12
6 |
7 | require (
8 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
9 | github.com/modern-go/reflect2 v1.0.2 // indirect
10 | )
11 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
5 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
6 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
7 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
8 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
9 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
10 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
11 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
12 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
13 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
14 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
15 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
16 |
--------------------------------------------------------------------------------
/leb128/leb128.go:
--------------------------------------------------------------------------------
1 | package leb128
2 |
3 | // EncodeInt32 encodes the `value` as leb128 encoded byte array
4 | func EncodeInt32(value int32) []byte {
5 | result := make([]byte, 0)
6 | val := value
7 | i := 0
8 |
9 | for {
10 | b := byte(val & 0x7f)
11 | val >>= 7
12 | if (val == 0 && b & 0x40 == 0) || (val == -1 && b & 0x40 != 0) {
13 | result = append(result, b)
14 | break
15 | }
16 |
17 | result = append(result, b | 0x80)
18 | i++
19 | }
20 |
21 | return result
22 | }
23 |
24 | // DecodeInt32 decodes an int32 and returns the number of bytes used from the given leb128 encoded array `value`
25 | func DecodeInt32(value []byte) (int32, int) {
26 | result := uint32(0)
27 | shift := 0
28 |
29 | for _, b := range value {
30 | result |= uint32(b & 0x7f) << shift
31 | shift += 7
32 | if b & 0x80 == 0 {
33 | if shift < 32 && b & 0x40 != 0 {
34 | result |= ^uint32(0) << shift
35 | }
36 |
37 | break
38 | }
39 | }
40 |
41 | return int32(result), shift / 7
42 | }
43 |
44 | // EncodeInt64 encodes the `value` as leb128 encoded byte array
45 | func EncodeInt64(value int64) []byte {
46 | result := make([]byte, 0)
47 | val := value
48 |
49 | for {
50 | b := byte(val & 0x7f)
51 | val >>= 7
52 | if (val == 0 && b & 0x40 == 0) || (val == -1 && b & 0x40 != 0) {
53 | result = append(result, b)
54 | break
55 | }
56 |
57 | result = append(result, b | 0x80)
58 | }
59 |
60 | return result
61 | }
62 |
63 | // DecodeInt64 decodes an int64 and returns the number of bytes used from the given leb128 encoded array `value`
64 | func DecodeInt64(value []byte) (int64, int) {
65 | result := uint64(0)
66 | shift := 0
67 |
68 | for _, b := range value {
69 | result |= uint64(b & 0x7f) << shift
70 | shift += 7
71 |
72 | if b & 0x80 == 0 {
73 | if shift < 64 && b & 0x40 != 0 {
74 | result |= ^uint64(0) << shift
75 | }
76 |
77 | break
78 | }
79 | }
80 |
81 | return int64(result), shift / 7
82 | }
83 |
84 | // EncodeUint32 encodes the `value` as leb128 encoded byte array
85 | func EncodeUint32(value uint32) []byte {
86 | result := make([]byte, 0)
87 | val := value
88 |
89 | for {
90 | b := byte(val & 0x7f)
91 | val >>= 7
92 | if val == 0 {
93 | result = append(result, b)
94 | break
95 | }
96 |
97 | result = append(result, b | 0x80)
98 | }
99 |
100 | return result
101 | }
102 |
103 | // DecodeUint32 decodes an uint32 and returns the number of bytes used from the given leb128 encoded array `value`
104 | func DecodeUint32(value []byte) (uint32, int) {
105 | result := uint32(0)
106 | shift := 0
107 |
108 | for _, b := range value {
109 | result |= uint32(b & 0x7f) << shift
110 | if b & 0x80 == 0 {
111 | break
112 | }
113 |
114 | shift += 7
115 | }
116 |
117 | return result, shift / 7 + 1
118 | }
119 |
120 | // EncodeUint64 encodes the `value` as leb128 encoded byte array
121 | func EncodeUint64(value uint64) []byte {
122 | result := make([]byte, 0)
123 | val := value
124 |
125 | for {
126 | b := byte(val & 0x7f)
127 | val >>= 7
128 | if val == 0 {
129 | result = append(result, b)
130 | break
131 | }
132 |
133 | result = append(result, b | 0x80)
134 | }
135 |
136 | return result
137 | }
138 |
139 | // DecodeUint64 decodes an uint64 and returns the number of bytes used from the given leb128 encoded array `value`
140 | func DecodeUint64(value []byte) (uint64, int) {
141 | result := uint64(0)
142 | shift := 0
143 |
144 | for _, b := range value {
145 | result |= uint64(b & 0x7f) << shift
146 | if b & 0x80 == 0 {
147 | break
148 | }
149 |
150 | shift += 7
151 | }
152 |
153 | return result, shift / 7 + 1
154 | }
155 |
--------------------------------------------------------------------------------
/leb128/leb128_test.go:
--------------------------------------------------------------------------------
1 | package leb128
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 | "encoding/hex"
7 | )
8 |
9 | type PairU struct {
10 | value uint64
11 | encoded string
12 | }
13 |
14 | type PairI struct {
15 | value int64
16 | encoded string
17 | }
18 |
19 | func fromHex(s string) []byte {
20 | h, _ := hex.DecodeString(s)
21 | return h
22 | }
23 |
24 | func Test_Basic(t *testing.T) {
25 | {
26 | if !bytes.Equal(EncodeUint64(624485), []byte{0xe5, 0x8e, 0x26}) {
27 | t.Error("EncodeUint64 fail")
28 | }
29 |
30 | uval, ulen := DecodeUint64([]byte{0xe5, 0x8e, 0x26})
31 | if uval != 624485 {
32 | t.Error("DecodeUint64 uval error")
33 | }
34 | if ulen != 3 {
35 | t.Error("DecodeUint64 ulen error")
36 | }
37 | }
38 |
39 | {
40 | if !bytes.Equal(EncodeUint32(624485), []byte{0xe5, 0x8e, 0x26}) {
41 | t.Error("EncodeUint32 fail")
42 | }
43 |
44 | uval, ulen := DecodeUint32([]byte{0xe5, 0x8e, 0x26})
45 | if uval != 624485 {
46 | t.Error("DecodeUint32 uval error")
47 | }
48 | if ulen != 3 {
49 | t.Error("DecodeUint32 ulen error")
50 | }
51 | }
52 |
53 | // =====
54 |
55 | {
56 | if !bytes.Equal(EncodeInt64(-123456), []byte{0xc0, 0xbb, 0x78}) {
57 | t.Error("EncodeInt64 fail")
58 | }
59 |
60 | uval, ulen := DecodeInt64([]byte{0xc0, 0xbb, 0x78})
61 | if uval != -123456 {
62 | t.Error("DecodeInt64 uval error")
63 | }
64 | if ulen != 3 {
65 | t.Error("DecodeInt64 ulen error")
66 | }
67 | }
68 |
69 | {
70 | if !bytes.Equal(EncodeInt32(-123456), []byte{0xc0, 0xbb, 0x78}) {
71 | t.Error("EncodeInt32 fail")
72 | }
73 |
74 | uval, ulen := DecodeInt32([]byte{0xc0, 0xbb, 0x78})
75 | if uval != -123456 {
76 | t.Error("DecodeInt32 uval error")
77 | }
78 | if ulen != 3 {
79 | t.Error("DecodeInt32 ulen error")
80 | }
81 | }
82 | }
83 |
84 | func Test_Unsigned_Data(t *testing.T) {
85 | for _, tt := range unsigned_data {
86 | got := EncodeUint64(tt.value)
87 | if !bytes.Equal(got, fromHex(tt.encoded)) {
88 | t.Error("EncodeUint64 fail")
89 | }
90 |
91 | bytes := fromHex(tt.encoded)
92 | uval, ulen := DecodeUint64(bytes)
93 | if uval != tt.value {
94 | t.Error("DecodeUint64 uval error")
95 | }
96 | if ulen != len(bytes) {
97 | t.Error("DecodeUint64 ulen error")
98 | }
99 |
100 | }
101 | }
102 |
103 | func Test_Signed_Data(t *testing.T) {
104 | for _, tt := range signed_data {
105 | got := EncodeInt64(tt.value)
106 | if !bytes.Equal(got, fromHex(tt.encoded)) {
107 | t.Error("EncodeInt64 fail")
108 | }
109 |
110 | bytes := fromHex(tt.encoded)
111 | uval, ulen := DecodeInt64(bytes)
112 | if uval != tt.value {
113 | t.Error("DecodeInt64 uval error")
114 | }
115 | if ulen != len(bytes) {
116 | t.Error("DecodeInt64 ulen error")
117 | }
118 |
119 | }
120 | }
121 |
122 | var unsigned_data = []PairU{
123 | {217, "d901"},
124 | {34, "22"},
125 | {233, "e901"},
126 | {2049800081, "91efb5d107"},
127 | {3884507512, "f8c2a3bc0e"},
128 | }
129 |
130 | var signed_data = []PairI{
131 | {71, "c700"},
132 | {-57, "47"},
133 | {58, "3a"},
134 | {1961805726, "9e8fbba707"},
135 | {-1567520880, "908fc6947a"},
136 | }
137 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deatil/go-encoding/6b5727ddf8219384079c6e8eb9ea36a73a86c8de/logo.png
--------------------------------------------------------------------------------
/morse/morse.go:
--------------------------------------------------------------------------------
1 | package morse
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | "reflect"
7 | "strings"
8 | )
9 |
10 | var morseITU = map[string]string{
11 | "a": ".-",
12 | "b": "-...",
13 | "c": "-.-.",
14 | "d": "-..",
15 | "e": ".",
16 | "f": "..-.",
17 | "g": "--.",
18 | "h": "....",
19 | "i": "..",
20 | "j": ".---",
21 | "k": "-.-",
22 | "l": ".-..",
23 | "m": "--",
24 | "n": "-.",
25 | "o": "---",
26 | "p": ".--.",
27 | "q": "--.-",
28 | "r": ".-.",
29 | "s": "...",
30 | "t": "-",
31 | "u": "..-",
32 | "v": "...-",
33 | "w": ".--",
34 | "x": "-..-",
35 | "y": "-.--",
36 | "z": "--..",
37 | "ä": ".-.-",
38 | "ö": "---.",
39 | "ü": "..--",
40 | "Ch": "----",
41 | "0": "-----",
42 | "1": ".----",
43 | "2": "..---",
44 | "3": "...--",
45 | "4": "....-",
46 | "5": ".....",
47 | "6": "-....",
48 | "7": "--...",
49 | "8": "---..",
50 | "9": "----.",
51 | ".": ".-.-.-",
52 | ",": "--..--",
53 | "?": "..--..",
54 | "!": "..--.",
55 | ":": "---...",
56 | "\"": ".-..-.",
57 | "'": ".----.",
58 | "=": "-...-",
59 | }
60 |
61 | // ITUEncoding is the standard morse ITU encoding.
62 | var ITUEncoding = NewEncoding(morseITU, " ", "/")
63 |
64 | /*
65 | * Encodings
66 | */
67 |
68 | // An Encoding is a radix 62 encoding/decoding scheme, defined by a 62-character alphabet.
69 | type Encoding struct {
70 | alphabet map[string]string
71 | letterSeparator string
72 | wordSeparator string
73 | }
74 |
75 | func NewEncoding(alphabet map[string]string, letterSeparator, wordSeparator string) *Encoding {
76 | e := new(Encoding)
77 | e.alphabet = alphabet
78 | e.letterSeparator = letterSeparator
79 | e.wordSeparator = wordSeparator
80 |
81 | return e
82 | }
83 |
84 | /*
85 | * Encoder
86 | */
87 |
88 | // Encode encodes clear text in `s` using `alphabet` mapping
89 | func (enc *Encoding) Encode(s []byte) []byte {
90 | res := ""
91 | for _, part := range string(s) {
92 | p := string(part)
93 | if p == " " {
94 | if enc.wordSeparator != "" {
95 | res += enc.wordSeparator + enc.letterSeparator
96 | }
97 | } else if enc.alphabet[p] != "" {
98 | res += enc.alphabet[p] + enc.letterSeparator
99 | }
100 | }
101 |
102 | return []byte(strings.TrimSpace(res))
103 | }
104 |
105 | // EncodeToString returns the base62 encoding of src.
106 | func (enc *Encoding) EncodeToString(src []byte) string {
107 | buf := enc.Encode(src)
108 | return string(buf)
109 | }
110 |
111 | /*
112 | * Decoder
113 | */
114 |
115 | // Decode decodes morse code in `s` using `alphabet` mapping
116 | func (enc *Encoding) Decode(s []byte) ([]byte, error) {
117 | res := ""
118 | for _, part := range strings.Split(string(s), enc.letterSeparator) {
119 | found := false
120 | for key, val := range enc.alphabet {
121 | if val == part {
122 | res += key
123 | found = true
124 | break
125 | }
126 | }
127 |
128 | if part == enc.wordSeparator {
129 | res += " "
130 | found = true
131 | }
132 |
133 | if !found {
134 | return []byte(res), fmt.Errorf("go-encoding/morse: unknown character " + part)
135 | }
136 | }
137 |
138 | return []byte(res), nil
139 | }
140 |
141 | // DecodeString returns the bytes represented by the base62 string s.
142 | func (enc *Encoding) DecodeString(s string) ([]byte, error) {
143 | sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
144 | bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
145 | return enc.Decode(*(*[]byte)(unsafe.Pointer(&bh)))
146 | }
147 |
148 | // LooksLikeMorse returns true if string seems to be a morse encoded string
149 | func LooksLikeMorse(s string) bool {
150 | if len(s) < 1 {
151 | return false
152 | }
153 |
154 | for _, b := range s {
155 | if b != '-' && b != '.' && b != ' ' {
156 | return false
157 | }
158 | }
159 |
160 | return true
161 | }
162 |
--------------------------------------------------------------------------------
/morse/morse_test.go:
--------------------------------------------------------------------------------
1 | package morse
2 |
3 | import "testing"
4 |
5 | func Test_LooksLikeMorse(t *testing.T) {
6 | if !LooksLikeMorse("- .... . .-..") {
7 | t.Error("fail 1")
8 | }
9 |
10 | if LooksLikeMorse("one one one...") {
11 | t.Error("fail 2")
12 | }
13 |
14 | if LooksLikeMorse("") {
15 | t.Error("fail 3")
16 | }
17 | }
18 |
19 | func Test_DecodeBrokenITU(t *testing.T) {
20 | _, err := ITUEncoding.DecodeString("-- ?.. ...")
21 | if err == nil {
22 | t.Error("expected error")
23 | }
24 | }
25 |
26 | func Test_EncodeToString(t *testing.T) {
27 | in := []byte("test:date")
28 |
29 | encoded := ITUEncoding.EncodeToString(in)
30 | if len(encoded) == 0 {
31 | t.Error("EncodeToString fail")
32 | }
33 |
34 | decoded, err := ITUEncoding.DecodeString(encoded)
35 | if err != nil {
36 | t.Error("DecodeString fail")
37 | }
38 |
39 | if string(decoded) != string(in) {
40 | t.Errorf("DecodeString, got %s, want %s", string(decoded), string(in))
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/puny/puny.go:
--------------------------------------------------------------------------------
1 | package puny
2 |
3 | import (
4 | "fmt"
5 | "bytes"
6 | "errors"
7 | "unsafe"
8 | "reflect"
9 | )
10 |
11 | const (
12 | // Bootstring parameters specified in RFC 3492
13 | baseC = 36
14 | tMin = 1
15 | tMax = 26
16 | skew = 38
17 | damp = 700
18 | initialBias = 72
19 | initialN = 128 // 0x80
20 | delimiter byte = 0x2D // hyphen
21 | maxRune = '\U0010FFFF'
22 | )
23 |
24 | var (
25 | invalidCharaterErr = errors.New("go-encoding/puny: Non-ASCCI codepoint found in src")
26 | overFlowErr = errors.New("go-encoding/puny: Overflow")
27 | inputError = errors.New("go-encoding/puny: Bad Input")
28 | digit2codepointErr = errors.New("go-encoding/puny: digit2codepoint")
29 | )
30 |
31 | // std Encoding
32 | var StdEncoding = NewEncoding()
33 |
34 | /*
35 | * Encodings
36 | */
37 |
38 | type Encoding struct{}
39 |
40 | func NewEncoding() *Encoding {
41 | return &Encoding{}
42 | }
43 |
44 | /*
45 | * Encoder
46 | */
47 |
48 | // Encode returns the puny encoding of src.
49 | func (p *Encoding) Encode(src []byte) ([]byte, error) {
50 | n := initialN
51 | delta := 0
52 | bias := initialBias
53 | runes := bytes.Runes(src)
54 |
55 | var result bytes.Buffer
56 | var err error
57 |
58 | basicRunes := 0
59 | for i := 0; i < len(runes); i++ {
60 | // Write all basic codepoints to result
61 | if runes[i] < 0x80 {
62 | result.WriteRune(runes[i])
63 |
64 | basicRunes++
65 | }
66 | }
67 |
68 | // Append delimiter
69 | if basicRunes > 0 {
70 | err = result.WriteByte(delimiter)
71 | if err != nil {
72 | return nil, err
73 | }
74 | }
75 |
76 | for h := basicRunes; h < len(runes); {
77 | minRune := maxRune
78 |
79 | // Find the minimum rune >= n in the input
80 | for i := 0; i < len(runes); i++ {
81 | if int(runes[i]) >= n && runes[i] < minRune {
82 | minRune = runes[i]
83 | }
84 | }
85 |
86 | delta = delta + (int(minRune)-n)*(h+1) // ??
87 | n = int(minRune)
88 |
89 | for i := 0; i < len(runes); i++ {
90 | if int(runes[i]) < n {
91 | delta++
92 | }
93 | if int(runes[i]) == n {
94 | q := delta
95 | for k := baseC; true; k += baseC {
96 | var t int
97 |
98 | switch {
99 | case k <= bias:
100 | t = tMin
101 | break
102 | case k >= (bias + tMax):
103 | t = tMax
104 | break
105 | default:
106 | t = k - bias
107 | }
108 |
109 | if q < t {
110 | break
111 | }
112 |
113 | result, err = writeBytesDigitToCodepoint(result, t+(q-t)%(baseC-t))
114 | if err != nil {
115 | return nil, err
116 | }
117 | q = (q - t) / (baseC - t)
118 | }
119 | result, err = writeBytesDigitToCodepoint(result, q)
120 | if err != nil {
121 | return nil, err
122 | }
123 |
124 | bias = adapt(delta, h == basicRunes, h+1)
125 | delta = 0
126 | h++
127 | }
128 | }
129 | delta++
130 | n++
131 | }
132 |
133 | return result.Bytes(), nil
134 | }
135 |
136 | // EncodeToString returns the puny encoding of src.
137 | func (p *Encoding) EncodeToString(src []byte) (string, error) {
138 | buf, err := p.Encode(src)
139 | return string(buf), err
140 | }
141 |
142 | func (p *Encoding) EncodedLen(n int) int {
143 | return n
144 | }
145 |
146 | /*
147 | * Decoder
148 | */
149 |
150 | // Decode returns the bytes represented by the puny string s.
151 | func (p *Encoding) Decode(src []byte) ([]byte, error) {
152 | // Decoding procedure explained in detail in RFC 3492.
153 | n := initialN
154 | i := 0
155 | bias := initialBias
156 |
157 | pos := 0
158 | delimIndex := -1
159 |
160 | result := make([]rune, 0, len(src))
161 |
162 | // Only ASCII allowed in decoding procedure
163 | for j := 0; j < len(src); j++ {
164 | if src[j] >= 0x80 {
165 | return nil, invalidCharaterErr
166 |
167 | }
168 | }
169 |
170 | // Consume all codepoints before the last delimiter
171 | delimIndex = bytes.LastIndex(src, []byte{delimiter})
172 | for pos = 0; pos < delimIndex; pos++ {
173 | result = append(result, rune(src[pos]))
174 | }
175 |
176 | // Consume delimiter
177 | pos = delimIndex + 1
178 |
179 | for pos < len(src) {
180 | oldi := i
181 | w := 1
182 | for k := baseC; true; k += baseC {
183 | var t int
184 |
185 | if pos == len(src) {
186 | return nil, inputError
187 | }
188 |
189 | // consume a code point, or fail if there was none to consume
190 | cp := rune(src[pos])
191 | pos++
192 |
193 | digit := codepoint2digit(cp)
194 |
195 | if digit > ((maxRune - i) / w) {
196 | return nil, inputError
197 | }
198 |
199 | i = i + digit*w
200 |
201 | switch {
202 | case k <= bias:
203 | t = tMin
204 | break
205 | case k >= bias+tMax:
206 | t = tMax
207 | break
208 | default:
209 | t = k - bias
210 | }
211 |
212 | if digit < t {
213 | break
214 | }
215 | w = w * (baseC - t)
216 | }
217 | bias = adapt(i-oldi, oldi == 0, len(result)+1)
218 |
219 | if i/(len(result)+1) > (maxRune - n) {
220 | return nil, overFlowErr
221 | }
222 |
223 | n = n + i/(len(result)+1)
224 | i = i % (len(result) + 1)
225 |
226 | if n < 0x80 {
227 | return nil, fmt.Errorf("%v is a basic code point.", n)
228 | }
229 |
230 | result = insert(result, i, rune(n))
231 | i++
232 | }
233 |
234 | return writeRune(result), nil
235 | }
236 |
237 | // DecodeString returns the bytes represented by the puny string s.
238 | func (p *Encoding) DecodeString(s string) ([]byte, error) {
239 | sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
240 | bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
241 | return p.Decode(*(*[]byte)(unsafe.Pointer(&bh)))
242 | }
243 |
244 | func (p *Encoding) DecodedLen(n int) int {
245 | return n
246 | }
247 |
--------------------------------------------------------------------------------
/puny/puny_test.go:
--------------------------------------------------------------------------------
1 | package puny
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | type testPair struct {
8 | decoded string
9 | encoded string
10 | }
11 |
12 | type malformedTestPair struct {
13 | encoded string
14 | error error
15 | }
16 |
17 | var pairs = []testPair{
18 | {
19 | decoded: "∏∪∩",
20 | encoded: "q9g0cc",
21 | },
22 | {
23 | decoded: "Hello!!",
24 | encoded: "Hello!!-",
25 | },
26 | {
27 | decoded: "puny Encoding,?:+【‘;’",
28 | encoded: "puny Encoding+-yb3hqa1950e6u24cvhaxa3f",
29 | },
30 | {
31 | decoded: "测试!",
32 | encoded: "!-rq9bs28f",
33 | },
34 | {
35 | decoded: "ǐǒó チツチノハフヘキキξεζοреё┢┣┮┐┑ 《《‖∶",
36 | encoded: " -4ja79fka410aha6dl49ipd3io866avhg1plqa10asa3sp25sa586aa29ba1fto2a8opd",
37 | },
38 | }
39 |
40 | func testEqual(t *testing.T, msg string, args ...any) bool {
41 | if args[len(args)-2] != args[len(args)-1] {
42 | t.Errorf(msg, args...)
43 | return false
44 | }
45 |
46 | return true
47 | }
48 |
49 | func TestEncode(t *testing.T) {
50 | for _, p := range pairs {
51 | got, err := StdEncoding.EncodeToString([]byte(p.decoded))
52 | if err != nil {
53 | t.Fatal(err)
54 | }
55 |
56 | testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
57 | }
58 | }
59 |
60 | func TestDecode(t *testing.T) {
61 | for _, p := range pairs {
62 | got, err := StdEncoding.DecodeString(p.encoded)
63 | if err != nil {
64 | t.Fatal(err)
65 | }
66 |
67 | testEqual(t, "Decode(%q) = %q, want %q", p.encoded, string(got), p.decoded)
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/puny/utils.go:
--------------------------------------------------------------------------------
1 | package puny
2 |
3 | import (
4 | "bytes"
5 | )
6 |
7 | func adapt(delta int, first bool, numchars int) (bias int) {
8 | if first {
9 | delta = delta / damp
10 | } else {
11 | delta = delta / 2
12 | }
13 |
14 | delta = delta + (delta / numchars)
15 |
16 | k := 0
17 | for delta > ((baseC-tMin)*tMax)/2 {
18 | delta = delta / (baseC - tMin)
19 | k = k + baseC
20 | }
21 |
22 | bias = k + ((baseC-tMin+1)*delta)/(delta+skew)
23 | return
24 | }
25 |
26 | func codepoint2digit(r rune) int {
27 | switch {
28 | case r-48 < 10:
29 | return int(r - 22)
30 | case r-65 < 26:
31 | return int(r - 65)
32 | case r-97 < 26:
33 | return int(r - 97)
34 | }
35 |
36 | return baseC
37 | }
38 |
39 | func writeBytesDigitToCodepoint(bytes bytes.Buffer, d int) (bytes.Buffer, error) {
40 | var val rune
41 | switch {
42 | case d < 26:
43 | // 0..25 : 'a'..'z'
44 | val = rune(d + 'a')
45 | case d < 36:
46 | // 26..35 : '0'..'9';
47 | val = rune(d - 26 + '0')
48 | default:
49 | return bytes, digit2codepointErr
50 | }
51 |
52 | err := bytes.WriteByte(byte(val))
53 | return bytes, err
54 | }
55 |
56 | func writeRune(r []rune) []byte {
57 | str := string(r)
58 | return []byte(str)
59 | }
60 |
61 | func insert(s []rune, pos int, r rune) []rune {
62 | return append(s[:pos], append([]rune{r}, s[pos:]...)...)
63 | }
64 |
--------------------------------------------------------------------------------
/quotedprintable/quotedprintable.go:
--------------------------------------------------------------------------------
1 | package quotedprintable
2 |
3 | import (
4 | "io"
5 | "fmt"
6 | "bytes"
7 | "unsafe"
8 | "reflect"
9 | )
10 |
11 | // encodeStd is the standard quotedprintable encoding alphabet
12 | const encodeStd = "0123456789ABCDEF"
13 |
14 | // StdEncoding is the standard quotedprintable encoding
15 | var StdEncoding = NewEncoding(encodeStd)
16 |
17 | /*
18 | * Encodings
19 | */
20 |
21 | // An Encoding is a quotedprintable encoding/decoding scheme defined by a 16-character alphabet.
22 | type Encoding struct {
23 | encode string
24 | }
25 |
26 | // NewEncoding returns a new Encoding defined by the given alphabet
27 | func NewEncoding(encoder string) *Encoding {
28 | if len(encoder) != 16 {
29 | panic("go-encoding/quotedprintable: encoding alphabet is not 16 bytes long")
30 | }
31 |
32 | enc := new(Encoding)
33 | enc.encode = encoder
34 |
35 | return enc
36 | }
37 |
38 | /*
39 | * Encoder
40 | */
41 |
42 | func (e *Encoding) Encode(src []byte) ([]byte, error) {
43 | dst := make([]byte, e.EncodedLen(len(src)))
44 |
45 | n := 0
46 | for i, c := range src {
47 | switch {
48 | case c != '=' && (c >= '!' && c <= '~' || c == '\n' || c == '\r'):
49 | dst[n] = c
50 | n++
51 | case c == ' ' || c == '\t':
52 | if isLastChar(i, src) {
53 | e.encodeByte(dst[n:], c)
54 | n += 3
55 | } else {
56 | dst[n] = c
57 | n++
58 | }
59 | default:
60 | e.encodeByte(dst[n:], c)
61 | n += 3
62 | }
63 | }
64 |
65 | return dst[:n], nil
66 | }
67 |
68 | // EncodeToString returns the PunyEncoding encoding of src.
69 | func (e *Encoding) EncodeToString(src []byte) (string, error) {
70 | buf, err := e.Encode(src)
71 | return string(buf), err
72 | }
73 |
74 | func (e *Encoding) EncodedLen(n int) int {
75 | return 3 * n
76 | }
77 |
78 | /*
79 | * Decoder
80 | */
81 |
82 | func (e *Encoding) Decode(src []byte) ([]byte, error) {
83 | dst := make([]byte, e.DecodedLen(len(src)))
84 |
85 | var eol, trimLen, eolLen, n int
86 | var err error
87 |
88 | for i := 0; i < len(src); i++ {
89 | if i == eol {
90 | eol = bytes.IndexByte(src[i:], '\n') + i + 1
91 | if eol == i {
92 | eol = len(src)
93 | eolLen = 0
94 | } else if eol-2 >= i && src[eol-2] == '\r' {
95 | eolLen = 2
96 | } else {
97 | eolLen = 1
98 | }
99 |
100 | // Count the number of bytes to trim
101 | trimLen = 0
102 | for {
103 | if trimLen == eol-eolLen-i {
104 | break
105 | }
106 |
107 | switch src[eol-eolLen-trimLen-1] {
108 | case '\n', '\r', ' ', '\t':
109 | trimLen++
110 | continue
111 | case '=':
112 | if trimLen > 0 {
113 | trimLen += eolLen + 1
114 | eolLen = 0
115 | err = fmt.Errorf("quotedprintable: invalid bytes after =: %q", src[eol-trimLen+1:eol])
116 | } else {
117 | trimLen = eolLen + 1
118 | eolLen = 0
119 | }
120 | }
121 |
122 | break
123 | }
124 | }
125 |
126 | // Skip trimmable bytes
127 | if trimLen > 0 && i == eol-trimLen-eolLen {
128 | if err != nil {
129 | return nil, err
130 | }
131 |
132 | i += trimLen - 1
133 | continue
134 | }
135 |
136 | switch c := src[i]; {
137 | case c == '=':
138 | if i+2 >= len(src) {
139 | return nil, io.ErrUnexpectedEOF
140 | }
141 | b, convErr := readHexByte(src[i+1:])
142 | if convErr != nil {
143 | return nil, convErr
144 | }
145 | dst[n] = b
146 | n++
147 | i += 2
148 | case (c >= ' ' && c <= '~') || c == '\n' || c == '\r' || c == '\t':
149 | dst[n] = c
150 | n++
151 | default:
152 | return nil, fmt.Errorf("quotedprintable: invalid unescaped byte 0x%02x in quoted-printable body", c)
153 | }
154 | }
155 |
156 | return dst[:n], nil
157 | }
158 |
159 | // DecodeString returns the bytes represented by the PunyEncoding string s.
160 | func (e *Encoding) DecodeString(s string) ([]byte, error) {
161 | sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
162 | bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
163 | return e.Decode(*(*[]byte)(unsafe.Pointer(&bh)))
164 | }
165 |
166 | func (e *Encoding) DecodedLen(n int) int {
167 | return n
168 | }
169 |
170 | func (e *Encoding) encodeByte(dst []byte, b byte) {
171 | dst[0] = '='
172 | dst[1] = e.encode[b>>4]
173 | dst[2] = e.encode[b&0x0f]
174 | }
175 |
--------------------------------------------------------------------------------
/quotedprintable/quotedprintable_test.go:
--------------------------------------------------------------------------------
1 | package quotedprintable
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | type testPair struct {
8 | decoded string
9 | encoded string
10 | }
11 |
12 | type malformedTestPair struct {
13 | encoded string
14 | error error
15 | }
16 |
17 | var pairs = []testPair{
18 | {
19 | decoded: `AB== fr gt\tdf`,
20 | encoded: "AB=3D=3D fr gt\\tdf",
21 | },
22 | {
23 | decoded: "Hello!! gt\tdf",
24 | encoded: "Hello!! gt\tdf",
25 | },
26 | {
27 | decoded: `quoted\nprin\rtabl e gt\tdf`,
28 | encoded: "quoted\\nprin\\rtabl e gt\\tdf",
29 | },
30 | {
31 | decoded: `ietf!\rjj`,
32 | encoded: "ietf!\\rjj",
33 | },
34 | {
35 | decoded: `test tyu\nikl dolor sit ametf5.h`,
36 | encoded: "test tyu\\nikl dolor sit ametf5.h",
37 | },
38 | }
39 |
40 | func testEqual(t *testing.T, msg string, args ...any) bool {
41 | if args[len(args)-2] != args[len(args)-1] {
42 | t.Errorf(msg, args...)
43 | return false
44 | }
45 |
46 | return true
47 | }
48 |
49 | func TestEncode(t *testing.T) {
50 | for _, p := range pairs {
51 | got, err := StdEncoding.EncodeToString([]byte(p.decoded))
52 | if err != nil {
53 | t.Fatal(err)
54 | }
55 |
56 | testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
57 | }
58 | }
59 |
60 | func TestDecode(t *testing.T) {
61 | for _, p := range pairs {
62 | got, err := StdEncoding.DecodeString(p.encoded)
63 | if err != nil {
64 | t.Fatal(err)
65 | }
66 |
67 | testEqual(t, "Decode(%q) = %q, want %q", p.encoded, string(got), p.decoded)
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/quotedprintable/utils.go:
--------------------------------------------------------------------------------
1 | package quotedprintable
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func fromHex(b byte) (byte, error) {
8 | switch {
9 | case b >= '0' && b <= '9':
10 | return b - '0', nil
11 | case b >= 'A' && b <= 'F':
12 | return b - 'A' + 10, nil
13 | // Accept badly encoded bytes
14 | case b >= 'a' && b <= 'f':
15 | return b - 'a' + 10, nil
16 | }
17 |
18 | return 0, fmt.Errorf("quotedprintable: invalid quoted-printable hex byte %#02x", b)
19 | }
20 |
21 | func readHexByte(v []byte) (b byte, err error) {
22 | var hb, lb byte
23 | if hb, err = fromHex(v[0]); err != nil {
24 | return 0, err
25 | }
26 |
27 | if lb, err = fromHex(v[1]); err != nil {
28 | return 0, err
29 | }
30 |
31 | return hb<<4 | lb, nil
32 | }
33 |
34 | func isLastChar(i int, src []byte) bool {
35 | return i == len(src)-1 ||
36 | (i < len(src)-1 && src[i+1] == '\n') ||
37 | (i < len(src)-2 && src[i+1] == '\r' && src[i+2] == '\n')
38 | }
39 |
--------------------------------------------------------------------------------