# 文件操作

# ini 文件解析器

代码如下:

package main

import (
	"bufio"
	"errors"
	"io"
	"os"
	"regexp"
)
import "fmt"

type ConfigParser struct {
	sections map[string]*Section
}

func newConfigParser() *ConfigParser {
	return &ConfigParser{sections: make(map[string]*Section)}
}

type Section struct {
	name    string
	options map[string]string
}

func newSection(name string) *Section {
	return &Section{name: name, options: make(map[string]string)}
}

func (section *Section) put(key, value string) {
	section.options[key] = value
}

func (section *Section) get(key string) (string, bool) {
	value, ok := section.options[key]
	return value, ok
}

func (section *Section) OptionNames() (options []string) {
	for option := range section.options {
		options = append(options, option)
	}
	return options
}

func (parser *ConfigParser) Read(path string) error {
	inputFile, inputError := os.Open(path)
	if inputError != nil {
		fmt.Printf("An error occurred on opening the inputfile\n" +
			"Does the file exist?\n" +
			"Have you got acces to it?\n")
		return errors.New("can't open file")
	}
	defer inputFile.Close()
	inputReader := bufio.NewReader(inputFile)
	// 解析为sections
	return parser.parserLines(inputReader)
}

func (parser *ConfigParser) Get(sectionName, optionName string) string {
	if section, ok := parser.sections[sectionName]; ok {
		if val, ok := section.get(optionName); ok {
			return val
		}
	}
	panic("")
}

func (parser *ConfigParser) GetSectionNames() (sections []string) {
	for section := range parser.sections {
		sections = append(sections, section)
	}
	return sections
}

func (parser *ConfigParser) GetSection(name string) *Section {
	return parser.sections[name]
}
func (parser *ConfigParser) parserLines(inputReader *bufio.Reader) error {
	var currentSection string
	for {
		inputString, readerError := inputReader.ReadString('\n')
		if readerError == io.EOF {
			return nil
		}
		val1, val2, lineType := parserLine(inputString)
		switch lineType {
		case 0:
			currentSection = val1
			parser.sections[currentSection] = newSection(val1)
		case 1:
			parser.sections[currentSection].put(val1, val2)
		}
	}
}

func parserLine(inputString string) (string, string, int) {
	var setcionRe = regexp.MustCompile(`\[(\w+)\]`)
	var optionRe = regexp.MustCompile(`(\w+)=(\S+)`)
	if setcionRe.MatchString(inputString) {
		return setcionRe.FindStringSubmatch(inputString)[1], "", 0
	} else if optionRe.MatchString(inputString) {
		values := optionRe.FindStringSubmatch(inputString)
		return values[1], values[2], 1
	} else {
		return "", "", 2
	}
}


func main() {
	path := "example.ini"
	configParser := newConfigParser()
	configParser.Read(path)
	for _, sectionName := range configParser.GetSectionNames() {
		fmt.Printf("[%s]\n", sectionName)
		for _, optionName := range configParser.GetSection(sectionName).OptionNames() {
			fmt.Printf("%s = %s\n", optionName, configParser.Get(sectionName, optionName))
		}
		println()
	}
}

# RSA 加密解密

  1. 首先创建一个 RSA 密钥,我们使用的是 2048,你可以使用 1024 或者 4096

    但数字越大,加密后的数据也越大,耗时也越长

    openssl genrsa -out private.pem 2048
    
  2. 然后根据密钥创建公钥

    openssl rsa -in private.pem -pubout -out public.pem
    

代码测试:

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha1"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "fmt"
)

func private_key() []byte {
    return []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAzuYg4WLstsyB9yyEQ4r5G6HF2TncncEirrM+aQQfk2VFm+HG
9gZiqW8BZIuKcJ2yMfNn2pefsiFf56pijqafsxEUb9V+9xy3TBx51eqiQJE7DIOj
8iFBSQHMLsPR//3qFXlAZyysg0b+nnZ+/72P1OVljOYBs03JT4OkgPFbm3W6+T9B
TVEvW4SwmS0Tbw+1AYCBg60AiY2Y5/HeVnEtSPOsg8kKo4RukeKakHGAzpmnrlV4
uvWV7gGX4zB4XzCFXEylyAPwFZyBEsdiPwlqhIkiMth0rmgzb8ee6RQBbw3iltU0
e67ra+hinxMqdLIZ5uE1NsrbPXB2G4I6SP8V4QIDAQABAoIBAAE39cWeEYraFYHh
Lz4+mU0CXOn0n0oGky+4OovfzFfP5uMOJ1/XlcktsDJpZ/1V0HDe4CO3dOdVrvzs
UfxJGvOxDA/EkCTgdGvsVwNdiGsc794ZAGQysfG+Ive7i4cYdcJ+nlR9PN7hEirY
w9K5yRkV6M01pZjqwl7HhbaEtWdq/WEnjcQc9tWTcUh754NWCT8ukMdned/mx/f/
fZZMdlnO9ocR3OAW6aND+Zcw71Ui4QPKx5r8TEp1svBn2yuptxOHlcP6xeocU7av
PhgOTDB1D0YiAlJlYI6YeRg66Lrm3OKi2xlFUDfOA+a7qF9auJLsyDzGTt751aGS
3m5sGgECgYEA9xOc6ZPsPNtipy6/aNpuncodFCDQspDOPzwAzhge6w7LuDt20yev
546lN3YvE91dbZQ+HVG+/Uv6SRuDCsU5n0IjruoNvAz+D4q7GZu6+SgBeuXgEECk
D255eCi9aXpsiEgIM/9LOkKP1e7eEqdMTKDORN3a0Xh8exMp0bZaMdECgYEA1l8L
2Ju6iVrPOorNK79ftZRc0jbrX6DEvfaUfSZptB7BmLzJoaEcVdEXre93Ip2Hu6WA
i1Fm09HJXU0edI1wcI0e0gQSIOCqf3OEeNrBreBYFJpg4NgUa6Zs3VTlNezxFFbu
Vp6aah6UbwK8+0a0G8SC6gJbtq3vmUUHfkQIFxECgYB9l1GehZuCv72g36laQhYS
TOeFEL0k12iPSg/asvYcY7P4HPnkkXrfyGmBDKkXfuF7zuvX+XKMzK8XtE1jDyeg
JX1/7uc2XKBUBB/g/4EGH2jJMMo5WLJMScqi4oqNcDZ0+7B3xeBWZ/k3NKlbcADf
vqm65c7RxV35LZ+HQxsL0QKBgQDG0VP9S0FQDsbPdtge0NkFYVpNJN5bzJFr1XuW
LsAua7AF5mHi47eR5+DcUpHdqtiuMirsC00g+xqUy+eJFXzJBjklct0VXQkEN7EP
HWQvzTgjs6JSJlWaGbox9IC46M4WnSFjeKmh7kagRpvbOJHmhvUb75/754mmTx1J
//K44QKBgQCsQmsd5dnYLTfT6a8yQ0y0evWMlpBLkBwMSOhR9CYi9OrJZGkvuuz2
7gKXkL1oWPUoFZ6C3V/4hU9mt3lo/3D7LCqVrau9W3LQZlY7x/hbR8suoSjWmoxo
Q8n9IBNXoVGzFu4t/eQg5wTIm9aSO+uWBXKPYMmyXbItfiPfiX6UOA==
-----END RSA PRIVATE KEY-----
`)
}

func public_key() []byte {
    return []byte(`
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzuYg4WLstsyB9yyEQ4r5
G6HF2TncncEirrM+aQQfk2VFm+HG9gZiqW8BZIuKcJ2yMfNn2pefsiFf56pijqaf
sxEUb9V+9xy3TBx51eqiQJE7DIOj8iFBSQHMLsPR//3qFXlAZyysg0b+nnZ+/72P
1OVljOYBs03JT4OkgPFbm3W6+T9BTVEvW4SwmS0Tbw+1AYCBg60AiY2Y5/HeVnEt
SPOsg8kKo4RukeKakHGAzpmnrlV4uvWV7gGX4zB4XzCFXEylyAPwFZyBEsdiPwlq
hIkiMth0rmgzb8ee6RQBbw3iltU0e67ra+hinxMqdLIZ5uE1NsrbPXB2G4I6SP8V
4QIDAQAB
-----END PUBLIC KEY-----
`)
}

func EncryptOAEP(text string) (string, error) {
    rsaPublicKey, err := ParsePKIXPublicKey()
    if err != nil {
        return "", err
    }
    secretMessage := []byte(text)
    rng := rand.Reader
    cipherdata, err := rsa.EncryptOAEP(sha1.New(), rng, rsaPublicKey, secretMessage, nil)
    if err != nil {
        return "", nil
    }
    ciphertext := base64.StdEncoding.EncodeToString(cipherdata)
    return ciphertext, nil
}

// 解密
func DecryptOAEP(ciphertext string) (string, error) {
    rsaPrivateKey, err := ParsePKCS1PrivateKey()
    if err != nil {
        return "", err
    }

    cipherdata, _ := base64.StdEncoding.DecodeString(ciphertext)
    rng := rand.Reader
    plaintext, err := rsa.DecryptOAEP(sha1.New(), rng, rsaPrivateKey, cipherdata, nil)
    if err != nil {
        return "", nil
    }

    return string(plaintext), nil
}

func ParsePKIXPublicKey() (*rsa.PublicKey, error) {
    block, _ := pem.Decode(public_key())
    pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    return pubInterface.(*rsa.PublicKey), nil
}

func ParsePKCS1PrivateKey() (*rsa.PrivateKey, error) {
    block, _ := pem.Decode(private_key())
    privateInterface, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    return privateInterface, nil
}

func main() {

    ciphertext, err := EncryptOAEP("www.twle.cn")
    if err != nil {
        panic(err)
    }
    fmt.Printf("Ciphertext: \n%x\n", ciphertext)
    plaintext, err := DecryptOAEP(ciphertext)
    if err != nil {
        panic(err)
    }
    fmt.Printf("\nPlaintext: \n%s\n", string(plaintext))
}