1251 lines
27 KiB
Go
1251 lines
27 KiB
Go
package starcrypto
|
||
|
||
import (
|
||
"bufio"
|
||
"crypto"
|
||
"crypto/aes"
|
||
"crypto/cipher"
|
||
"crypto/md5"
|
||
"crypto/rand"
|
||
"crypto/rsa"
|
||
"crypto/sha1"
|
||
"crypto/sha256"
|
||
"crypto/sha512"
|
||
"crypto/x509"
|
||
"encoding/ascii85"
|
||
"encoding/base64"
|
||
"encoding/binary"
|
||
"encoding/hex"
|
||
"encoding/pem"
|
||
"errors"
|
||
"fmt"
|
||
"hash"
|
||
"hash/crc32"
|
||
"io"
|
||
"io/ioutil"
|
||
rands "math/rand"
|
||
"os"
|
||
"path/filepath"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"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)<<n)&255))
|
||
}
|
||
return o
|
||
}
|
||
|
||
// Base128Encode encodes src into EncodedLen(len(src)) bytes of dst. As a convenience,
|
||
// it returns the number of bytes written to dst, but this value is always
|
||
// EncodedLen(len(src)).
|
||
//
|
||
// Encode implements base128 encoding.
|
||
func Base128Encode(dst, src []byte) int {
|
||
ret := Base128EncodedLen(len(src))
|
||
if len(dst) < ret {
|
||
panic("dst has insufficient length")
|
||
}
|
||
dst = dst[:0]
|
||
whichByte := uint(1)
|
||
bufByte := byte(0)
|
||
for _, v := range src {
|
||
dst = append(dst, bufByte|(v>>whichByte))
|
||
bufByte = (v&(1<<whichByte) - 1) << (7 - whichByte)
|
||
if whichByte == 7 {
|
||
dst = append(dst, bufByte)
|
||
bufByte = 0
|
||
whichByte = 0
|
||
}
|
||
whichByte++
|
||
}
|
||
dst = append(dst, bufByte)
|
||
return ret
|
||
}
|
||
|
||
// Base128Decode decodes src into DecodedLen(len(src)) bytes, returning the actual
|
||
// number of bytes written to dst.
|
||
//
|
||
// If Decode encounters invalid input, it returns an error describing the
|
||
// failure.
|
||
func Base128Decode(dst, src []byte) (int, error) {
|
||
dLen := Base128DecodedLen(len(src))
|
||
if Base128EncodedLen(dLen) != len(src) {
|
||
return 0, ErrLength
|
||
}
|
||
if len(dst) < dLen {
|
||
panic("dst has insufficient length")
|
||
}
|
||
dst = dst[:0]
|
||
whichByte := uint(1)
|
||
bufByte := byte(0)
|
||
for _, v := range src {
|
||
if (v & 0x80) != 0 {
|
||
return len(dst), ErrBit
|
||
}
|
||
if whichByte > 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)
|
||
}
|
||
|
||
// Base64Decode 输出解密前的Base64数据
|
||
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)
|
||
}
|
||
|
||
// MD5 输出MD5校验值
|
||
func Md5(bstr []byte) []byte {
|
||
md5sum := md5.New()
|
||
md5sum.Write(bstr)
|
||
return md5sum.Sum(nil)
|
||
}
|
||
|
||
func Md5Str(bstr []byte) string {
|
||
return String(Md5(bstr))
|
||
}
|
||
|
||
// CRC32 输出CRC32校验值
|
||
func Crc32(bstr []byte) []byte {
|
||
crcsum := crc32.NewIEEE()
|
||
crcsum.Write(bstr)
|
||
return crcsum.Sum(nil)
|
||
}
|
||
|
||
func Crc32Str(bstr []byte) string {
|
||
return String(Crc32(bstr))
|
||
}
|
||
|
||
// SHA512 输出SHA512校验值
|
||
func Sha512(bstr []byte) []byte {
|
||
shasum := sha512.New()
|
||
shasum.Write(bstr)
|
||
return shasum.Sum(nil)
|
||
}
|
||
|
||
func Sha512Str(bstr []byte) string {
|
||
return String(Sha512(bstr))
|
||
}
|
||
|
||
// SHA384 输出SHA384校验值
|
||
func Sha384(bstr []byte) []byte {
|
||
shasum := sha512.New384()
|
||
shasum.Write(bstr)
|
||
return shasum.Sum(nil)
|
||
}
|
||
|
||
func Sha384Str(bstr []byte) string {
|
||
return String(Sha384(bstr))
|
||
}
|
||
|
||
// SHA256 输出SHA256校验值
|
||
func Sha256(bstr []byte) []byte {
|
||
shasum := sha256.New()
|
||
shasum.Write(bstr)
|
||
return shasum.Sum(nil)
|
||
}
|
||
|
||
func Sha256Str(bstr []byte) string {
|
||
return String(Sha256(bstr))
|
||
}
|
||
|
||
// SHA224 输出SHA224校验值
|
||
func Sha224(bstr []byte) []byte {
|
||
shasum := sha256.New224()
|
||
shasum.Write(bstr)
|
||
return shasum.Sum(nil)
|
||
}
|
||
|
||
func Sha224Str(bstr []byte) string {
|
||
return String(Sha224(bstr))
|
||
}
|
||
|
||
// SHA1 输出SHA1校验值
|
||
func Sha1(bstr []byte) []byte {
|
||
shasum := sha1.New()
|
||
shasum.Write(bstr)
|
||
return shasum.Sum(nil)
|
||
}
|
||
|
||
func Sha1Str(bstr []byte) string {
|
||
return String(Sha512(bstr))
|
||
}
|
||
|
||
func GenerateKey(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
|
||
private, err := rsa.GenerateKey(rand.Reader, bits)
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
return private, &private.PublicKey, nil
|
||
|
||
}
|
||
|
||
func EncodePrivateKey(private *rsa.PrivateKey) []byte {
|
||
return pem.EncodeToMemory(&pem.Block{
|
||
Bytes: x509.MarshalPKCS1PrivateKey(private),
|
||
Type: "RSA PRIVATE KEY",
|
||
})
|
||
}
|
||
|
||
func EncodePublicKey(public *rsa.PublicKey) ([]byte, error) {
|
||
publicBytes, err := x509.MarshalPKIXPublicKey(public)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return pem.EncodeToMemory(&pem.Block{
|
||
Bytes: publicBytes,
|
||
Type: "PUBLIC KEY",
|
||
}), nil
|
||
}
|
||
|
||
//EncodeSSHKey
|
||
func EncodeSSHKey(public *rsa.PublicKey) ([]byte, error) {
|
||
publicKey, err := ssh.NewPublicKey(public)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return ssh.MarshalAuthorizedKey(publicKey), nil
|
||
}
|
||
|
||
func MakeSSHKeyPair() (string, string, error) {
|
||
|
||
pkey, pubkey, err := GenerateKey(2048)
|
||
if err != nil {
|
||
return "", "", err
|
||
}
|
||
|
||
pub, err := EncodeSSHKey(pubkey)
|
||
if err != nil {
|
||
return "", "", err
|
||
}
|
||
|
||
//glog.Info("privateKey=[%s]\n pubKey=[%s]",string(EncodePrivateKey(pkey)),string(pub))
|
||
return string(EncodePrivateKey(pkey)), string(pub), nil
|
||
}
|
||
|
||
// SumAll 可以对同一数据进行多种校验
|
||
func SumAll(data []byte, method []string) (map[string][]byte, error) {
|
||
result := make(map[string][]byte)
|
||
methods := make(map[string]hash.Hash)
|
||
var iscrc bool
|
||
if len(method) == 0 {
|
||
method = []string{"sha512", "sha256", "sha384", "sha224", "sha1", "crc32", "md5"}
|
||
}
|
||
sum512 := sha512.New()
|
||
sum384 := sha512.New384()
|
||
sum256 := sha256.New()
|
||
sum224 := sha256.New224()
|
||
sum1 := sha1.New()
|
||
crcsum := crc32.NewIEEE()
|
||
md5sum := md5.New()
|
||
for _, v := range method {
|
||
switch v {
|
||
case "md5":
|
||
methods["md5"] = md5sum
|
||
case "crc32":
|
||
iscrc = true
|
||
case "sha1":
|
||
methods["sha1"] = sum1
|
||
case "sha224":
|
||
methods["sha224"] = sum224
|
||
case "sha256":
|
||
methods["sha256"] = sum256
|
||
case "sha384":
|
||
methods["sha384"] = sum384
|
||
case "sha512":
|
||
methods["sha512"] = sum512
|
||
}
|
||
}
|
||
for _, v := range methods {
|
||
v.Write(data)
|
||
}
|
||
if iscrc {
|
||
crcsum.Write(data)
|
||
}
|
||
|
||
for k, v := range methods {
|
||
result[k] = v.Sum(nil)
|
||
}
|
||
if iscrc {
|
||
result["crc32"] = crcsum.Sum(nil)
|
||
}
|
||
return result, nil
|
||
}
|
||
|
||
// FileSum 输出文件内容校验值,method为单个校验方法,小写
|
||
//例:FileSum("./test.txt","md5",shell(pect float64){fmt.Sprintf("已完成 %f\r",pect)})
|
||
func FileSum(filepath, method string, shell func(float64)) (string, error) {
|
||
var sum hash.Hash
|
||
var sum32 hash.Hash32
|
||
var issum32 bool
|
||
var result string
|
||
fp, err := os.Open(filepath)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
switch method {
|
||
case "sha512":
|
||
sum = sha512.New()
|
||
case "sha384":
|
||
sum = sha512.New384()
|
||
case "sha256":
|
||
sum = sha256.New()
|
||
case "sha224":
|
||
sum = sha256.New224()
|
||
case "sha1":
|
||
sum = sha1.New()
|
||
case "crc32":
|
||
sum32 = crc32.NewIEEE()
|
||
issum32 = true
|
||
case "md5":
|
||
sum = md5.New()
|
||
default:
|
||
return "", errors.New("Cannot Recognize The Method:" + method)
|
||
}
|
||
writer := 0
|
||
stat, _ := os.Stat(filepath)
|
||
filebig := float64(stat.Size())
|
||
if !issum32 {
|
||
// if _, err := io.Copy(sum, fp); err != nil {
|
||
for {
|
||
buf := make([]byte, 1048574)
|
||
n, err := fp.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return result, err
|
||
}
|
||
writer += n
|
||
pect := (float64(writer) / filebig) * 100
|
||
go shell(pect)
|
||
sum.Write(buf[0:n])
|
||
}
|
||
result = hex.EncodeToString(sum.Sum(nil))
|
||
} else {
|
||
for {
|
||
buf := make([]byte, 1048574)
|
||
n, err := fp.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return result, err
|
||
}
|
||
writer += n
|
||
pect := (float64(writer) / filebig) * 100
|
||
go shell(pect)
|
||
sum32.Write(buf[0:n])
|
||
}
|
||
result = hex.EncodeToString(sum32.Sum(nil))
|
||
}
|
||
return result, nil
|
||
}
|
||
|
||
// FileSumAll 可以对同一文件进行多种校验
|
||
func FileSumAll(filepath string, method []string, shell func(float64)) (map[string]string, error) {
|
||
result := make(map[string]string)
|
||
methods := make(map[string]hash.Hash)
|
||
var iscrc bool
|
||
|
||
if len(method) == 0 {
|
||
method = []string{"sha512", "sha256", "sha384", "sha224", "sha1", "crc32", "md5"}
|
||
}
|
||
fp, err := os.Open(filepath)
|
||
defer fp.Close()
|
||
if err != nil {
|
||
return result, err
|
||
}
|
||
stat, _ := os.Stat(filepath)
|
||
filebig := float64(stat.Size())
|
||
sum512 := sha512.New()
|
||
sum384 := sha512.New384()
|
||
sum256 := sha256.New()
|
||
sum224 := sha256.New224()
|
||
sum1 := sha1.New()
|
||
crcsum := crc32.NewIEEE()
|
||
md5sum := md5.New()
|
||
for _, v := range method {
|
||
switch v {
|
||
case "md5":
|
||
methods["md5"] = md5sum
|
||
case "crc32":
|
||
iscrc = true
|
||
case "sha1":
|
||
methods["sha1"] = sum1
|
||
case "sha224":
|
||
methods["sha224"] = sum224
|
||
case "sha256":
|
||
methods["sha256"] = sum256
|
||
case "sha384":
|
||
methods["sha384"] = sum384
|
||
case "sha512":
|
||
methods["sha512"] = sum512
|
||
}
|
||
}
|
||
|
||
writer := 0
|
||
for {
|
||
buf := make([]byte, 1048574)
|
||
n, err := fp.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return result, err
|
||
}
|
||
writer += n
|
||
pect := (float64(writer) / filebig) * 100
|
||
go shell(pect)
|
||
for _, v := range methods {
|
||
v.Write(buf[0:n])
|
||
}
|
||
if iscrc {
|
||
crcsum.Write(buf[0:n])
|
||
}
|
||
}
|
||
for k, v := range methods {
|
||
result[k] = hex.EncodeToString(v.Sum(nil))
|
||
}
|
||
if iscrc {
|
||
result["crc32"] = hex.EncodeToString(crcsum.Sum(nil))
|
||
}
|
||
return result, nil
|
||
}
|
||
|
||
// Attach 合并src与dst文件并输出到output中
|
||
func Attach(src, dst, output string) error {
|
||
fpsrc, err := os.Open(src)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer fpsrc.Close()
|
||
fpdst, err := os.Open(dst)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer fpdst.Close()
|
||
fpout, err := os.Create(output)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer fpout.Close()
|
||
if _, err := io.Copy(fpout, fpsrc); err != nil {
|
||
return err
|
||
}
|
||
for {
|
||
buf := make([]byte, 1048574)
|
||
n, err := fpdst.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return err
|
||
}
|
||
fpout.Write(buf[0:n])
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// Detach 按bytenum字节大小分割src文件到dst1与dst2两个新文件中去
|
||
func Detach(src string, bytenum int, dst1, dst2 string) error {
|
||
fpsrc, err := os.Open(src)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer fpsrc.Close()
|
||
fpdst1, err := os.Create(dst1)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer fpdst1.Close()
|
||
fpdst2, err := os.Create(dst2)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer fpdst2.Close()
|
||
sumall := 0
|
||
var buf []byte
|
||
for {
|
||
if bytenum-sumall < 1048576 {
|
||
buf = make([]byte, bytenum-sumall)
|
||
} else {
|
||
buf = make([]byte, 1048576)
|
||
}
|
||
n, err := fpsrc.Read(buf)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
sumall += n
|
||
fpdst1.Write(buf[0:n])
|
||
if sumall == bytenum {
|
||
break
|
||
}
|
||
}
|
||
for {
|
||
buf = make([]byte, 1048576)
|
||
n, err := fpsrc.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return err
|
||
}
|
||
fpdst2.Write(buf[0:n])
|
||
}
|
||
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)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer fpsrc.Close()
|
||
stat, _ := os.Stat(src)
|
||
filebig := float64(stat.Size())
|
||
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)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return err
|
||
}
|
||
sum += int64(n)
|
||
go shell(float64(sum) / filebig * 100)
|
||
b64.Write(buf[0:n])
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// Base64DecodeFile 用base64方法解码src文件到dst文件中去,shell传入当前进度
|
||
func Base64DecodeFile(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 = 0
|
||
defer fpsrc.Close()
|
||
fpdst, err := os.Create(dst)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer fpdst.Close()
|
||
b64 := base64.NewDecoder(base64.StdEncoding, fpsrc)
|
||
for {
|
||
buf := make([]byte, 1048576)
|
||
n, err := b64.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return err
|
||
}
|
||
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
|
||
}
|
||
|
||
// SplitFile 把src文件按要求分割到dst中去,dst应传入带*号字符串
|
||
// 如果bynum=true 则把文件分割成num份
|
||
// 如果bynum=false 则把文件按num字节分成多份
|
||
func SplitFile(src, dst string, num int, bynum bool, 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())
|
||
if bynum {
|
||
if int(filebig) < num {
|
||
return errors.New("file is too small to split")
|
||
}
|
||
}
|
||
balance := int(filebig/float64(num)) + 1
|
||
if !bynum {
|
||
balance = num
|
||
}
|
||
nownum := 0
|
||
fpdst, err := os.Create(strings.Replace(dst, "*", fmt.Sprint(nownum), -1))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer fpdst.Close()
|
||
var sum, tsum int = 0, 0
|
||
var buf []byte
|
||
for {
|
||
if balance-sum < 1048576 {
|
||
buf = make([]byte, balance-sum)
|
||
} else {
|
||
buf = make([]byte, 1048576)
|
||
}
|
||
n, err := fpsrc.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return err
|
||
}
|
||
sum += n
|
||
tsum += n
|
||
fpdst.Write(buf[0:n])
|
||
go shell(float64(tsum) / filebig * 100)
|
||
if sum == balance {
|
||
fpdst.Close()
|
||
nownum++
|
||
fpdst, err = os.Create(strings.Replace(dst, "*", fmt.Sprint(nownum), -1))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
sum = 0
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// MergeFile 合并src文件到dst文件中去,src文件应传入带*号字符串
|
||
func MergeFile(src, dst string, shell func(float64)) error {
|
||
tmp := strings.Replace(src, "*", "0", -1)
|
||
dir, err := ioutil.ReadDir(filepath.Dir(tmp))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
base := filepath.Base(src)
|
||
tmp = strings.Replace(base, "*", "(\\d+)", -1)
|
||
reg := regexp.MustCompile(tmp)
|
||
count := 0
|
||
var filebig float64
|
||
for _, v := range dir {
|
||
if reg.MatchString(v.Name()) {
|
||
count++
|
||
filebig += float64(v.Size())
|
||
}
|
||
}
|
||
fpdst, err := os.Create(dst)
|
||
defer fpdst.Close()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
var sum int64
|
||
for i := 0; i < count; i++ {
|
||
fpsrc, err := os.Open(strings.Replace(src, "*", strconv.Itoa(i), -1))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
for {
|
||
buf := make([]byte, 1048576)
|
||
n, err := fpsrc.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return err
|
||
}
|
||
sum += int64(n)
|
||
go shell(float64(sum) / filebig * 100)
|
||
fpdst.Write(buf[0:n])
|
||
}
|
||
fpsrc.Close()
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// RSAEncrypt RSA公钥加密
|
||
func RSAEncrypt(data, public []byte) ([]byte, error) {
|
||
blk, _ := pem.Decode(public)
|
||
if blk == nil {
|
||
return []byte{}, errors.New("public key error")
|
||
}
|
||
pubkey, err := x509.ParsePKIXPublicKey(blk.Bytes)
|
||
if err != nil {
|
||
return []byte{}, err
|
||
}
|
||
return rsa.EncryptPKCS1v15(rand.Reader, pubkey.(*rsa.PublicKey), data)
|
||
}
|
||
|
||
// RSADecrypt RSA私钥解密
|
||
func RSADecrypt(data, private []byte, password string) ([]byte, error) {
|
||
var prikey *rsa.PrivateKey
|
||
var err error
|
||
var bytes []byte
|
||
blk, _ := pem.Decode(private)
|
||
if blk == nil {
|
||
return []byte{}, errors.New("private key error!")
|
||
}
|
||
if password != "" {
|
||
tmp, err := x509.DecryptPEMBlock(blk, []byte(password))
|
||
if err != nil {
|
||
return []byte{}, err
|
||
}
|
||
bytes = tmp
|
||
} else {
|
||
bytes = blk.Bytes
|
||
}
|
||
prikey, err = x509.ParsePKCS1PrivateKey(bytes)
|
||
if err != nil {
|
||
tmp, err := x509.ParsePKCS8PrivateKey(bytes)
|
||
if err != nil {
|
||
return []byte{}, err
|
||
}
|
||
prikey = tmp.(*rsa.PrivateKey)
|
||
}
|
||
return rsa.DecryptPKCS1v15(rand.Reader, prikey, data)
|
||
}
|
||
|
||
// RSASign RSA私钥签名加密
|
||
func RSASign(msg, priKey []byte, password string, hashType crypto.Hash) ([]byte, error) {
|
||
var prikey *rsa.PrivateKey
|
||
var err error
|
||
var bytes []byte
|
||
blk, _ := pem.Decode(priKey)
|
||
if blk == nil {
|
||
return []byte{}, errors.New("private key error!")
|
||
}
|
||
if password != "" {
|
||
tmp, err := x509.DecryptPEMBlock(blk, []byte(password))
|
||
if err != nil {
|
||
return []byte{}, err
|
||
}
|
||
bytes = tmp
|
||
} else {
|
||
bytes = blk.Bytes
|
||
}
|
||
prikey, err = x509.ParsePKCS1PrivateKey(bytes)
|
||
if err != nil {
|
||
tmp, err := x509.ParsePKCS8PrivateKey(bytes)
|
||
if err != nil {
|
||
return []byte{}, err
|
||
}
|
||
prikey = tmp.(*rsa.PrivateKey)
|
||
}
|
||
hashMethod := hashType.New()
|
||
_, err = hashMethod.Write(msg)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return rsa.SignPKCS1v15(rand.Reader, prikey, hashType, hashMethod.Sum(nil))
|
||
}
|
||
|
||
// RSAVerify RSA公钥签名验证
|
||
func RSAVerify(data, msg, pubKey []byte, hashType crypto.Hash) error {
|
||
blk, _ := pem.Decode(pubKey)
|
||
if blk == nil {
|
||
return errors.New("public key error!")
|
||
}
|
||
pubkey, err := x509.ParsePKIXPublicKey(blk.Bytes)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
hashMethod := hashType.New()
|
||
_, err = hashMethod.Write(msg)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
return rsa.VerifyPKCS1v15(pubkey.(*rsa.PublicKey), hashType, hashMethod.Sum(nil), data)
|
||
}
|
||
|
||
// VicqueEncodeV1 Best!
|
||
func VicqueEncodeV1(srcdata []byte, key string) []byte {
|
||
var keys []int
|
||
var saku, piku uint8
|
||
data := make([]byte, len(srcdata))
|
||
copy(data, srcdata)
|
||
binary.Read(rand.Reader, binary.LittleEndian, &saku)
|
||
binary.Read(rand.Reader, binary.LittleEndian, &piku)
|
||
keys = append(keys, len(key)+int(saku))
|
||
lens := len(data)
|
||
for _, v := range key {
|
||
keys = append(keys, int(byte(v))+int(saku)-int(piku))
|
||
}
|
||
lenkey := len(keys)
|
||
for k, v := range data {
|
||
if k == lens/2 {
|
||
break
|
||
}
|
||
nv := int(v)
|
||
t := 0
|
||
if k%2 == 0 {
|
||
nv += keys[k%lenkey]
|
||
if nv > 255 {
|
||
nv -= 256
|
||
}
|
||
t = int(data[lens-1-k])
|
||
t += keys[k%lenkey]
|
||
if t > 255 {
|
||
t -= 256
|
||
}
|
||
} else {
|
||
nv -= keys[k%lenkey]
|
||
if nv < 0 {
|
||
nv += 256
|
||
}
|
||
t = int(data[lens-1-k])
|
||
t -= keys[k%lenkey]
|
||
if t > 255 {
|
||
t += 256
|
||
}
|
||
}
|
||
data[k] = byte(t)
|
||
data[lens-1-k] = byte(nv)
|
||
}
|
||
data = append(data, byte(saku), byte(piku))
|
||
return data
|
||
}
|
||
|
||
// VicqueDecodeV1 Best!
|
||
func VicqueDecodeV1(srcdata []byte, key string) []byte {
|
||
var keys []int
|
||
var saku, piku int
|
||
data := make([]byte, len(srcdata))
|
||
copy(data, srcdata)
|
||
lens := len(data)
|
||
saku = int(data[lens-2])
|
||
piku = int(data[lens-1])
|
||
keys = append(keys, len(key)+int(saku))
|
||
for _, v := range key {
|
||
keys = append(keys, int(byte(v))+int(saku)-int(piku))
|
||
}
|
||
lenkey := len(keys)
|
||
lens -= 2
|
||
for k, v := range data {
|
||
if k == lens/2 {
|
||
break
|
||
}
|
||
nv := int(v)
|
||
t := 0
|
||
if k%2 == 0 {
|
||
nv -= keys[k%lenkey]
|
||
if nv < 0 {
|
||
nv += 256
|
||
}
|
||
t = int(data[lens-1-k])
|
||
t -= keys[k%lenkey]
|
||
if t > 255 {
|
||
t += 256
|
||
}
|
||
} else {
|
||
nv += keys[k%lenkey]
|
||
if nv > 255 {
|
||
nv -= 256
|
||
}
|
||
t = int(data[lens-1-k])
|
||
t += keys[k%lenkey]
|
||
if t > 255 {
|
||
t -= 256
|
||
}
|
||
}
|
||
data[k] = byte(t)
|
||
data[lens-1-k] = byte(nv)
|
||
}
|
||
return data[:lens]
|
||
}
|
||
|
||
// VicqueEncodeV1File best
|
||
func VicqueEncodeV1File(src, dst, pwd 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()
|
||
for {
|
||
buf := make([]byte, 1048576)
|
||
n, err := fpsrc.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return err
|
||
}
|
||
sum += int64(n)
|
||
go shell(float64(sum) / filebig * 100)
|
||
data := VicqueEncodeV1(buf[0:n], pwd)
|
||
fpdst.Write(data)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// VicqueDecodeV1File best
|
||
func VicqueDecodeV1File(src, dst, pwd 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()
|
||
for {
|
||
buf := make([]byte, 1048578)
|
||
n, err := fpsrc.Read(buf)
|
||
if err != nil {
|
||
if err == io.EOF {
|
||
break
|
||
}
|
||
return err
|
||
}
|
||
sum += int64(n)
|
||
go shell(float64(sum) / filebig * 100)
|
||
data := VicqueDecodeV1(buf[0:n], pwd)
|
||
fpdst.Write(data)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// FillWithRandom 随机写filesize大小的文件,每次buf大小为bufcap,随机bufnum个字符
|
||
func FillWithRandom(filepath string, filesize int, bufcap int, bufnum int, shell func(float64)) error {
|
||
var buf [][]byte
|
||
var buftmp []byte
|
||
rands.Seed(time.Now().Unix())
|
||
if bufnum <= 0 {
|
||
bufnum = 1
|
||
}
|
||
if bufcap > filesize {
|
||
bufcap = filesize
|
||
}
|
||
myfile, err := os.Create(filepath)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer myfile.Close()
|
||
writer := bufio.NewWriter(myfile)
|
||
for i := 0; i < bufnum; i++ {
|
||
buftmp = []byte{}
|
||
for j := 0; j < bufcap; j++ {
|
||
buftmp = append(buftmp, byte(rands.Intn(256)))
|
||
}
|
||
buf = append(buf, buftmp)
|
||
}
|
||
sum := 0
|
||
for {
|
||
if filesize-sum < bufcap {
|
||
writer.Write(buf[rands.Intn(bufnum)][0 : filesize-sum])
|
||
sum += filesize - sum
|
||
} else {
|
||
writer.Write(buf[rands.Intn(bufnum)])
|
||
sum += bufcap
|
||
}
|
||
go shell(float64(sum) / float64(filesize) * 100)
|
||
if sum >= filesize {
|
||
break
|
||
}
|
||
}
|
||
writer.Flush()
|
||
return nil
|
||
}
|
||
|
||
// =================== CFB ======================
|
||
func AesEncryptCFB(origData []byte, key []byte) (encrypted []byte) {
|
||
block, err := aes.NewCipher(key)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
encrypted = make([]byte, aes.BlockSize+len(origData))
|
||
iv := encrypted[:aes.BlockSize]
|
||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
||
panic(err)
|
||
}
|
||
stream := cipher.NewCFBEncrypter(block, iv)
|
||
stream.XORKeyStream(encrypted[aes.BlockSize:], origData)
|
||
return encrypted
|
||
}
|
||
func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte) {
|
||
block, _ := aes.NewCipher(key)
|
||
if len(encrypted) < aes.BlockSize {
|
||
panic("ciphertext too short")
|
||
}
|
||
iv := encrypted[:aes.BlockSize]
|
||
encrypted = encrypted[aes.BlockSize:]
|
||
|
||
stream := cipher.NewCFBDecrypter(block, iv)
|
||
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
|
||
}
|