diff --git a/crypto.go b/crypto.go index 2d68c0d..a598ce3 100644 --- a/crypto.go +++ b/crypto.go @@ -12,6 +12,7 @@ import ( "crypto/sha256" "crypto/sha512" "crypto/x509" + "encoding/ascii85" "encoding/base64" "encoding/binary" "encoding/hex" @@ -33,6 +34,199 @@ import ( "golang.org/x/crypto/ssh" ) +var ( + // ErrLength is returned from the Decode* methods if the input has an + // impossible length. + ErrLength = errors.New("base128: invalid length base128 string") + // ErrBit is returned from the Decode* methods if the input has a byte with + // the high-bit set (e.g. 0x80). This will never be the case for strings + // produced from the Encode* methods in this package. + ErrBit = errors.New("base128: high bit set in base128 string") +) + +// Encoding table holds all the characters for base91 encoding +var enctab = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~'") + +// Decoding table maps all the characters back to their integer values +var dectab = map[byte]byte{ + 'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, + 'I': 8, 'J': 9, 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, + 'Q': 16, 'R': 17, 'S': 18, 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, + 'Y': 24, 'Z': 25, 'a': 26, 'b': 27, 'c': 28, 'd': 29, 'e': 30, 'f': 31, + 'g': 32, 'h': 33, 'i': 34, 'j': 35, 'k': 36, 'l': 37, 'm': 38, 'n': 39, + 'o': 40, 'p': 41, 'q': 42, 'r': 43, 's': 44, 't': 45, 'u': 46, 'v': 47, + 'w': 48, 'x': 49, 'y': 50, 'z': 51, '0': 52, '1': 53, '2': 54, '3': 55, + '4': 56, '5': 57, '6': 58, '7': 59, '8': 60, '9': 61, '!': 62, '#': 63, + '$': 64, '%': 65, '&': 66, '(': 67, ')': 68, '*': 69, '+': 70, ',': 71, + '.': 72, '/': 73, ':': 74, ';': 75, '<': 76, '=': 77, '>': 78, '?': 79, + '@': 80, '[': 81, ']': 82, '^': 83, '_': 84, '`': 85, '{': 86, '|': 87, + '}': 88, '~': 89, '\'': 90, +} + +// Base91EncodeToString encodes the given byte array and returns a string +func Base91EncodeToString(d []byte) string { + return string(Base91Encode(d)) +} + +// Base91Encode returns the base91 encoded string +func Base91Encode(d []byte) []byte { + var n, b uint + var o []byte + + for i := 0; i < len(d); i++ { + b |= uint(d[i]) << n + n += 8 + if n > 13 { + v := b & 8191 + if v > 88 { + b >>= 13 + n -= 13 + } else { + v = b & 16383 + b >>= 14 + n -= 14 + } + o = append(o, enctab[v%91], enctab[v/91]) + } + } + if n > 0 { + o = append(o, enctab[b%91]) + if n > 7 || b > 90 { + o = append(o, enctab[b/91]) + } + } + return o +} + +// Base91DecodeToString decodes a given byte array are returns a string +func Base91DecodeString(d string) []byte { + return Base91Decode([]byte(d)) +} + +// Base91Decode decodes a base91 encoded string and returns the result +func Base91Decode(d []byte) []byte { + var b, n uint + var o []byte + v := -1 + + for i := 0; i < len(d); i++ { + c, ok := dectab[d[i]] + if !ok { + continue + } + if v < 0 { + v = int(c) + } else { + v += int(c) * 91 + b |= uint(v) << n + if v&8191 > 88 { + n += 13 + } else { + n += 14 + } + o = append(o, byte(b&255)) + b >>= 8 + n -= 8 + for n > 7 { + o = append(o, byte(b&255)) + b >>= 8 + n -= 8 + } + v = -1 + } + } + if v+1 > 0 { + o = append(o, byte((b|uint(v)<>whichByte)) + bufByte = (v&(1< 1 { + dst = append(dst, bufByte|(v>>(8-whichByte))) + } + bufByte = v << whichByte + if whichByte == 8 { + whichByte = 0 + } + whichByte++ + } + return len(dst), nil +} + +// Base128DecodeString returns the bytes represented by the base128 string s. +func Base128DecodeString(s string) ([]byte, error) { + src := []byte(s) + dst := make([]byte, Base128DecodedLen(len(src))) + if _, err := Base128Decode(dst, src); err != nil { + return nil, err + } + return dst, nil +} + +// Base128DecodedLen returns the number of bytes `encLen` encoded bytes decodes to. +func Base128DecodedLen(encLen int) int { + return (encLen * 7 / 8) +} + +// Base128EncodedLen returns the number of bytes that `dataLen` bytes will encode to. +func Base128EncodedLen(dataLen int) int { + return (((dataLen * 8) + 6) / 7) +} + +// Base128EncodeToString returns the base128 encoding of src. +func Base128EncodeToString(src []byte) string { + dst := make([]byte, Base128EncodedLen(len(src))) + Base128Encode(dst, src) + return string(dst) +} + // Base64Encode 输出格式化后的Base64字符串 func Base64Encode(bstr []byte) string { return base64.StdEncoding.EncodeToString(bstr) @@ -43,6 +237,22 @@ func Base64Decode(str string) ([]byte, error) { return base64.StdEncoding.DecodeString(str) } +// Base85Encode 输出格式化后的Base85字符串 +func Base85Encode(bstr []byte) string { + var rtn []byte + rtn = make([]byte, ascii85.MaxEncodedLen(len(bstr))) + ascii85.Encode(rtn, bstr) + return string(rtn) +} + +// Base85Decode 输出解密前的Base85数据 +func Base85Decode(str string) ([]byte, error) { + var rtn []byte + rtn = make([]byte, len(str)) + _, _, err := ascii85.Decode(rtn, []byte(str), true) + return rtn, err +} + func String(bstr []byte) string { return hex.EncodeToString(bstr) } @@ -449,6 +659,76 @@ func Detach(src string, bytenum int, dst1, dst2 string) error { return nil } +// Base85EncodeFile 用base85方法编码src文件到dst文件中去,shell传入当前进度 +func Base85EncodeFile(src, dst string, shell func(float64)) error { + fpsrc, err := os.Open(src) + if err != nil { + return err + } + defer fpsrc.Close() + stat, _ := os.Stat(src) + filebig := float64(stat.Size()) + var sum int64 + fpdst, err := os.Create(dst) + if err != nil { + return err + } + defer fpdst.Close() + b85 := ascii85.NewEncoder(fpdst) + defer b85.Close() + for { + buf := make([]byte, 1024000) + n, err := fpsrc.Read(buf) + if err != nil { + if err == io.EOF { + break + } + return err + } + sum += int64(n) + go shell(float64(sum) / filebig * 100) + b85.Write(buf[0:n]) + } + return nil +} + +// Base85DecodeFile 用base85方法解码src文件到dst文件中去,shell传入当前进度 +func Base85DecodeFile(src, dst string, shell func(float64)) error { + fpsrc, err := os.Open(src) + if err != nil { + return err + } + defer fpsrc.Close() + stat, _ := os.Stat(src) + filebig := float64(stat.Size()) + var sum int64 + defer fpsrc.Close() + fpdst, err := os.Create(dst) + if err != nil { + return err + } + defer fpdst.Close() + b85 := ascii85.NewDecoder(fpsrc) + for { + buf := make([]byte, 1280000) + n, err := b85.Read(buf) + if err != nil { + if err == io.EOF { + break + } + return err + } + sum += int64(n) + per := float64(sum) / filebig * 100 / 4.0 * 5.0 + if per >= 100 { + per = 100 + } + go shell(per) + fpdst.Write(buf[0:n]) + } + return nil +} + // Base64EncodeFile 用base64方法编码src文件到dst文件中去,shell传入当前进度 func Base64EncodeFile(src, dst string, shell func(float64)) error { fpsrc, err := os.Open(src) @@ -458,13 +738,14 @@ func Base64EncodeFile(src, dst string, shell func(float64)) error { defer fpsrc.Close() stat, _ := os.Stat(src) filebig := float64(stat.Size()) - sum := 0 + var sum int64 = 0 fpdst, err := os.Create(dst) if err != nil { return err } defer fpdst.Close() b64 := base64.NewEncoder(base64.StdEncoding, fpdst) + defer b64.Close() for { buf := make([]byte, 1048575) n, err := fpsrc.Read(buf) @@ -474,7 +755,7 @@ func Base64EncodeFile(src, dst string, shell func(float64)) error { } return err } - sum += n + sum += int64(n) go shell(float64(sum) / filebig * 100) b64.Write(buf[0:n]) } @@ -490,7 +771,7 @@ func Base64DecodeFile(src, dst string, shell func(float64)) error { defer fpsrc.Close() stat, _ := os.Stat(src) filebig := float64(stat.Size()) - sum := 0 + var sum int64 = 0 defer fpsrc.Close() fpdst, err := os.Create(dst) if err != nil { @@ -507,8 +788,12 @@ func Base64DecodeFile(src, dst string, shell func(float64)) error { } return err } - sum += n - go shell(float64(sum) / filebig * 100) + sum += int64(n) + per := float64(sum) / filebig * 100 / 3.0 * 4.0 + if per >= 100 { + per = 100 + } + go shell(per) fpdst.Write(buf[0:n]) } return nil @@ -595,7 +880,7 @@ func MergeFile(src, dst string, shell func(float64)) error { if err != nil { return err } - sum := 0 + var sum int64 for i := 0; i < count; i++ { fpsrc, err := os.Open(strings.Replace(src, "*", strconv.Itoa(i), -1)) if err != nil { @@ -610,7 +895,7 @@ func MergeFile(src, dst string, shell func(float64)) error { } return err } - sum += n + sum += int64(n) go shell(float64(sum) / filebig * 100) fpdst.Write(buf[0:n]) } @@ -808,7 +1093,7 @@ func VicqueEncodeV1File(src, dst, pwd string, shell func(float64)) error { defer fpsrc.Close() stat, _ := os.Stat(src) filebig := float64(stat.Size()) - sum := 0 + var sum int64 defer fpsrc.Close() fpdst, err := os.Create(dst) if err != nil { @@ -824,7 +1109,7 @@ func VicqueEncodeV1File(src, dst, pwd string, shell func(float64)) error { } return err } - sum += n + sum += int64(n) go shell(float64(sum) / filebig * 100) data := VicqueEncodeV1(buf[0:n], pwd) fpdst.Write(data) @@ -841,7 +1126,7 @@ func VicqueDecodeV1File(src, dst, pwd string, shell func(float64)) error { defer fpsrc.Close() stat, _ := os.Stat(src) filebig := float64(stat.Size()) - sum := 0 + var sum int64 defer fpsrc.Close() fpdst, err := os.Create(dst) if err != nil { @@ -857,7 +1142,7 @@ func VicqueDecodeV1File(src, dst, pwd string, shell func(float64)) error { } return err } - sum += n + sum += int64(n) go shell(float64(sum) / filebig * 100) data := VicqueDecodeV1(buf[0:n], pwd) fpdst.Write(data) @@ -934,3 +1219,22 @@ func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte) { stream.XORKeyStream(encrypted, encrypted) return encrypted } + +func AesEncryptCFBNoBlock(origData []byte, key []byte) (encrypted []byte) { + block, err := aes.NewCipher(key) + if err != nil { + panic(err) + } + encrypted = make([]byte, len(origData)) + iv := Sha1(key)[:16] + stream := cipher.NewCFBEncrypter(block, iv) + stream.XORKeyStream(encrypted, origData) + return encrypted +} +func AesDecryptCFBNoBlock(encrypted []byte, key []byte) (decrypted []byte) { + block, _ := aes.NewCipher(key) + iv := Sha1(key)[:16] + stream := cipher.NewCFBDecrypter(block, iv) + stream.XORKeyStream(encrypted, encrypted) + return encrypted +}