You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
starainrt/crypto.go

830 lines
16 KiB
Go

5 years ago
package starainrt
import (
"bufio"
"crypto"
5 years ago
"crypto/md5"
"crypto/rand"
"crypto/rsa"
5 years ago
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/x509"
5 years ago
"encoding/base64"
"encoding/binary"
5 years ago
"encoding/hex"
"encoding/pem"
"errors"
5 years ago
"fmt"
"hash"
5 years ago
"hash/crc32"
"io"
"io/ioutil"
rands "math/rand"
5 years ago
"os"
"path/filepath"
5 years ago
"regexp"
"strconv"
"strings"
"time"
5 years ago
)
type StarCrypto struct {
5 years ago
}
/*
Base64
*/
func (this StarCrypto) Base64Encode(bstr []byte) string {
return base64.StdEncoding.EncodeToString(bstr)
5 years ago
}
/*
Base64
*/
func (this StarCrypto) Base64Decode(str string) ([]byte, error) {
return base64.StdEncoding.DecodeString(str)
}
/*
MD5
*/
func (this StarCrypto) MD5(bstr []byte) string {
md5sum := md5.New()
return hex.EncodeToString(md5sum.Sum(bstr))
}
/*
CRC32
*/
func (this StarCrypto) CRC32(bstr []byte) string {
crcsum := crc32.NewIEEE()
return hex.EncodeToString(crcsum.Sum(bstr))
}
/*
SHA512
*/
func (this StarCrypto) Sha512(bstr []byte) string {
shasum := sha512.New()
return hex.EncodeToString(shasum.Sum(bstr))
}
/*
SHA256
*/
func (this StarCrypto) SHA256(bstr []byte) string {
shasum := sha256.New()
return hex.EncodeToString(shasum.Sum(bstr))
}
/*
SHA1
*/
func (this StarCrypto) SHA1(bstr []byte) string {
shasum := sha1.New()
return hex.EncodeToString(shasum.Sum(bstr))
}
/*
*/
func (this StarCrypto) SumAll(data []byte, method []string) (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"}
}
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
}
5 years ago
}
for _, v := range methods {
v.Write(data)
5 years ago
}
if iscrc {
crcsum.Write(data)
5 years ago
}
for k, v := range methods {
result[k] = hex.EncodeToString(v.Sum(nil))
5 years ago
}
if iscrc {
result["crc32"] = hex.EncodeToString(crcsum.Sum(nil))
}
return result, nil
5 years ago
}
/*
method,
FileSum("./test.txt","md5",shell(pect float64){fmt.Sprintf("已完成 %f\r",pect)})
*/
func (this StarCrypto) FileSum(filepath, method string, shell func(float64)) (string, error) {
var sum hash.Hash
var sum32 hash.Hash32
var issum32 bool
var result string
if !Exists(filepath) {
return "", errors.New("File Not Exists!")
}
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
5 years ago
}
writer += n
pect := (float64(writer) / filebig) * 100
go shell(pect)
sum.Write(buf[0:n])
5 years ago
}
result = hex.EncodeToString(sum.Sum(nil))
5 years ago
} else {
for {
buf := make([]byte, 1048574)
n, err := fp.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return result, err
5 years ago
}
writer += n
pect := (float64(writer) / filebig) * 100
go shell(pect)
sum32.Write(buf[0:n])
5 years ago
}
result = hex.EncodeToString(sum32.Sum(nil))
5 years ago
}
return result, nil
5 years ago
}
/*
*/
func (this StarCrypto) 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"}
}
if !Exists(filepath) {
return result, errors.New("File Not Exists!")
}
fp, err := os.Open(filepath)
5 years ago
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
}
}
5 years ago
writer := 0
for {
buf := make([]byte, 1048574)
n, err := fp.Read(buf)
5 years ago
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])
5 years ago
}
if iscrc {
crcsum.Write(buf[0:n])
5 years ago
}
}
for k, v := range methods {
result[k] = hex.EncodeToString(v.Sum(nil))
}
if iscrc {
result["crc32"] = hex.EncodeToString(crcsum.Sum(nil))
}
return result, nil
5 years ago
}
func (this StarCrypto) Attach(src, dst, output string) error {
if !Exists(src) {
return errors.New("Source File Not Exists!")
}
if !Exists(dst) {
return errors.New("Dest File Not Exists!")
}
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 {
5 years ago
break
}
return err
5 years ago
}
fpout.Write(buf[0:n])
5 years ago
}
return nil
}
func (this StarCrypto) Detach(src string, bytenum int, dst1, dst2 string) error {
if !Exists(src) {
return errors.New("Source File Not Exists!")
5 years ago
}
fpsrc, err := os.Open(src)
if err != nil {
return err
5 years ago
}
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 {
5 years ago
break
}
return err
5 years ago
}
fpdst2.Write(buf[0:n])
5 years ago
}
return nil
5 years ago
}
func (this StarCrypto) Base64EncodeFile(src, dst string, shell func(float64)) error {
if !Exists(src) {
return errors.New("Source File Not Exists!")
5 years ago
}
fpsrc, err := os.Open(src)
if err != nil {
return err
5 years ago
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
sum := 0
fpdst, err := os.Create(dst)
if err != nil {
return err
5 years ago
}
defer fpdst.Close()
b64 := base64.NewEncoder(base64.StdEncoding, fpdst)
5 years ago
for {
buf := make([]byte, 1048575)
n, err := fpsrc.Read(buf)
5 years ago
if err != nil {
if err == io.EOF {
break
}
return err
5 years ago
}
sum += n
go shell(float64(sum) / filebig * 100)
b64.Write(buf[0:n])
5 years ago
}
return nil
}
5 years ago
func (this StarCrypto) Base64DecodeFile(src, dst string, shell func(float64)) error {
if !Exists(src) {
return errors.New("Source File Not Exists!")
}
fpsrc, err := os.Open(src)
if err != nil {
return err
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
sum := 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)
5 years ago
if err != nil {
if err == io.EOF {
break
}
return err
5 years ago
}
sum += n
go shell(float64(sum) / filebig * 100)
fpdst.Write(buf[0:n])
5 years ago
}
return nil
5 years ago
}
/*
bynum=true num
bynum=false num
*/
func (this StarCrypto) SplitFile(src, dst string, num int, bynum bool, shell func(float64)) error {
if !Exists(src) {
return errors.New("Source File Not Exists!")
}
fpsrc, err := os.Open(src)
5 years ago
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
5 years ago
}
nownum := 0
fpdst, err := os.Create(strings.Replace(dst, "*", fmt.Sprint(nownum), -1))
if err != nil {
return err
5 years ago
}
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
5 years ago
}
func (this StarCrypto) MergeFile(src, dst string, shell func(float64)) error {
tmp := strings.Replace(src, "*", "0", -1)
dir, err := ioutil.ReadDir(filepath.Dir(tmp))
5 years ago
if err != nil {
return err
}
base := filepath.Base(src)
tmp = strings.Replace(base, "*", "(\\d+)", -1)
reg := regexp.MustCompile(tmp)
count := 0
var filebig float64 = 0
for _, v := range dir {
if reg.MatchString(v.Name()) {
count++
filebig += float64(v.Size())
}
5 years ago
}
fpdst, err := os.Create(dst)
defer fpdst.Close()
if err != nil {
return err
}
sum := 0
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 += n
go shell(float64(sum) / filebig * 100)
fpdst.Write(buf[0:n])
}
fpsrc.Close()
}
return nil
5 years ago
}
func (this StarCrypto) 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)
5 years ago
if err != nil {
return []byte{}, err
5 years ago
}
return rsa.EncryptPKCS1v15(rand.Reader, pubkey.(*rsa.PublicKey), data)
5 years ago
}
func (this StarCrypto) RSADecrypt(data, private []byte, password string) ([]byte, error) {
var prikey *rsa.PrivateKey
var err error
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
}
prikey, err = x509.ParsePKCS1PrivateKey(tmp)
if err != nil {
return []byte{}, err
}
} else {
prikey, err = x509.ParsePKCS1PrivateKey(blk.Bytes)
if err != nil {
return []byte{}, err
}
5 years ago
}
return rsa.DecryptPKCS1v15(rand.Reader, prikey, data)
}
5 years ago
func (this StarCrypto) RSASign(hash256, private []byte, password string) ([]byte, error) {
var prikey *rsa.PrivateKey
var err error
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
}
prikey, err = x509.ParsePKCS1PrivateKey(tmp)
if err != nil {
return []byte{}, err
}
} else {
prikey, err = x509.ParsePKCS1PrivateKey(blk.Bytes)
if err != nil {
return []byte{}, err
}
}
return rsa.SignPKCS1v15(rand.Reader, prikey, crypto.SHA256, hash256)
5 years ago
}
func (this StarCrypto) RSAVerify(data, hash256, public []byte) error {
blk, _ := pem.Decode(public)
if blk == nil {
return errors.New("public key error")
}
pubkey, err := x509.ParsePKIXPublicKey(blk.Bytes)
5 years ago
if err != nil {
return err
5 years ago
}
return rsa.VerifyPKCS1v15(pubkey.(*rsa.PublicKey), crypto.SHA256, hash256, data)
5 years ago
}
func (this StarCrypto) 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)
5 years ago
}
data = append(data, byte(saku), byte(piku))
return data
}
5 years ago
func (this StarCrypto) 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 {
5 years ago
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
}
5 years ago
} 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
}
5 years ago
}
data[k] = byte(t)
data[lens-1-k] = byte(nv)
5 years ago
}
return data[:lens]
}
5 years ago
func (this StarCrypto) 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())
sum := 0
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)
5 years ago
if err != nil {
if err == io.EOF {
break
}
return err
5 years ago
}
sum += n
go shell(float64(sum) / filebig * 100)
data := this.VicqueEncodeV1(buf[0:n], pwd)
fpdst.Write(data)
5 years ago
}
return nil
5 years ago
}
func (this StarCrypto) 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())
sum := 0
defer fpsrc.Close()
fpdst, err := os.Create(dst)
if err != nil {
return err
}
defer fpdst.Close()
5 years ago
for {
buf := make([]byte, 1048578)
n, err := fpsrc.Read(buf)
5 years ago
if err != nil {
if err == io.EOF {
break
}
return err
5 years ago
}
sum += n
go shell(float64(sum) / filebig * 100)
data := this.VicqueDecodeV1(buf[0:n], pwd)
fpdst.Write(data)
5 years ago
}
return nil
}
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(255)))
}
buf = append(buf, buftmp)
5 years ago
}
sum := 0
5 years ago
for {
if filesize-sum < bufcap {
writer.Write(buf[rands.Intn(bufnum-1)][0 : filesize-sum])
sum += filesize - sum
} else {
writer.Write(buf[rands.Intn(bufnum-1)])
sum += bufcap
}
go shell(float64(sum) / float64(filesize) * 100)
if sum >= filesize {
5 years ago
break
}
}
writer.Flush()
return nil
5 years ago
}