parent
286ba2b26e
commit
ba9651a369
@ -1,98 +0,0 @@ |
|||||||
package main |
|
||||||
|
|
||||||
import ( |
|
||||||
"bufio" |
|
||||||
"errors" |
|
||||||
"fmt" |
|
||||||
"os" |
|
||||||
"strconv" |
|
||||||
"strings" |
|
||||||
) |
|
||||||
|
|
||||||
type StringPrompt struct { |
|
||||||
question string |
|
||||||
defaultValue string |
|
||||||
required bool |
|
||||||
confirm bool |
|
||||||
validators []func(string) error |
|
||||||
} |
|
||||||
|
|
||||||
func String(question string) *StringPrompt { |
|
||||||
return &StringPrompt{question: question} |
|
||||||
} |
|
||||||
|
|
||||||
func Confirm(question string) *StringPrompt { |
|
||||||
return &StringPrompt{ |
|
||||||
question: question, |
|
||||||
confirm: true, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
func (s *StringPrompt) Required(required bool) *StringPrompt { |
|
||||||
s.required = required |
|
||||||
return s |
|
||||||
} |
|
||||||
|
|
||||||
func (s *StringPrompt) SetValidator(validators ...func(string) error) *StringPrompt { |
|
||||||
s.validators = validators |
|
||||||
return s |
|
||||||
} |
|
||||||
|
|
||||||
func (s *StringPrompt) Run() string { |
|
||||||
putsln := func(msg string) { |
|
||||||
lines := strings.Count(s.question+"\n"+msg, "\n") + 1 |
|
||||||
// https://blog.csdn.net/weixin_43988842/article/details/106169040
|
|
||||||
fmt.Fprintf(os.Stderr, "\x1b[%dA", lines) // 上移 lines 行
|
|
||||||
fmt.Fprint(os.Stderr, "\x1b[J") // 从光标位置到屏幕末尾擦除
|
|
||||||
fmt.Fprintln(os.Stderr, msg) |
|
||||||
} |
|
||||||
|
|
||||||
var input string |
|
||||||
r := bufio.NewReader(os.Stdin) |
|
||||||
|
|
||||||
WHILE: |
|
||||||
fmt.Fprint(os.Stderr, s.question+" ") |
|
||||||
input, _ = r.ReadString('\n') |
|
||||||
input = strings.TrimSpace(input) |
|
||||||
if input == "" { |
|
||||||
if !s.required { |
|
||||||
putsln(s.question) |
|
||||||
return "" |
|
||||||
} |
|
||||||
putsln("请输入内容!") |
|
||||||
goto WHILE |
|
||||||
} |
|
||||||
for _, v := range s.validators { |
|
||||||
err := v(input) |
|
||||||
if err != nil { |
|
||||||
putsln(err.Error()) |
|
||||||
goto WHILE |
|
||||||
} |
|
||||||
} |
|
||||||
if s.confirm && len(s.validators) == 0 { |
|
||||||
switch strings.ToLower(input) { |
|
||||||
case "y", "yes": |
|
||||||
input = "y" |
|
||||||
case "n", "no": |
|
||||||
input = "n" |
|
||||||
default: |
|
||||||
input = "" |
|
||||||
} |
|
||||||
} |
|
||||||
putsln(s.question + " " + input) |
|
||||||
return input |
|
||||||
} |
|
||||||
|
|
||||||
func main() { |
|
||||||
name := String("What is your name?"). |
|
||||||
Required(true). |
|
||||||
SetValidator(func(s string) error { |
|
||||||
_, err := strconv.ParseInt(s, 10, 64) |
|
||||||
if err != nil { |
|
||||||
return errors.New("请输入一个数字") |
|
||||||
} |
|
||||||
return nil |
|
||||||
}). |
|
||||||
Run() |
|
||||||
fmt.Printf("Hello, %s!\n", name) |
|
||||||
} |
|
@ -0,0 +1,85 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"crypto/rand" |
||||||
|
"crypto/rsa" |
||||||
|
"crypto/x509" |
||||||
|
"encoding/asn1" |
||||||
|
"encoding/gob" |
||||||
|
"encoding/pem" |
||||||
|
"os" |
||||||
|
) |
||||||
|
|
||||||
|
// TicketKeysGenerator 创建 ticket 密钥
|
||||||
|
type TicketKeysGenerator struct{} |
||||||
|
|
||||||
|
func (g *TicketKeysGenerator) Generate() (err error) { |
||||||
|
defer func() { |
||||||
|
if recovered := recover(); recovered != nil { |
||||||
|
err = recovered.(error) |
||||||
|
} |
||||||
|
}() |
||||||
|
|
||||||
|
reader := rand.Reader |
||||||
|
bitSize := 2048 |
||||||
|
|
||||||
|
key, err := rsa.GenerateKey(reader, bitSize) |
||||||
|
g.checkError(err) |
||||||
|
|
||||||
|
publicKey := key.PublicKey |
||||||
|
|
||||||
|
g.saveGobKey("private.key", key) |
||||||
|
g.savePEMKey("private.pem", key) |
||||||
|
|
||||||
|
g.saveGobKey("public.key", publicKey) |
||||||
|
g.savePublicPEMKey("public.pem", publicKey) |
||||||
|
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
func (g *TicketKeysGenerator) saveGobKey(fileName string, key interface{}) { |
||||||
|
outFile, err := os.Create(fileName) |
||||||
|
g.checkError(err) |
||||||
|
defer outFile.Close() |
||||||
|
|
||||||
|
encoder := gob.NewEncoder(outFile) |
||||||
|
err = encoder.Encode(key) |
||||||
|
g.checkError(err) |
||||||
|
} |
||||||
|
|
||||||
|
func (g *TicketKeysGenerator) savePEMKey(fileName string, key *rsa.PrivateKey) { |
||||||
|
outFile, err := os.Create(fileName) |
||||||
|
g.checkError(err) |
||||||
|
defer outFile.Close() |
||||||
|
|
||||||
|
var privateKey = &pem.Block{ |
||||||
|
Type: "PRIVATE KEY", |
||||||
|
Bytes: x509.MarshalPKCS1PrivateKey(key), |
||||||
|
} |
||||||
|
|
||||||
|
err = pem.Encode(outFile, privateKey) |
||||||
|
g.checkError(err) |
||||||
|
} |
||||||
|
|
||||||
|
func (g *TicketKeysGenerator) savePublicPEMKey(fileName string, pubkey rsa.PublicKey) { |
||||||
|
asn1Bytes, err := asn1.Marshal(pubkey) |
||||||
|
g.checkError(err) |
||||||
|
|
||||||
|
var pemkey = &pem.Block{ |
||||||
|
Type: "PUBLIC KEY", |
||||||
|
Bytes: asn1Bytes, |
||||||
|
} |
||||||
|
|
||||||
|
pemfile, err := os.Create(fileName) |
||||||
|
g.checkError(err) |
||||||
|
defer pemfile.Close() |
||||||
|
|
||||||
|
err = pem.Encode(pemfile, pemkey) |
||||||
|
g.checkError(err) |
||||||
|
} |
||||||
|
|
||||||
|
func (g *TicketKeysGenerator) checkError(err error) { |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package util |
||||||
|
|
||||||
|
import "os" |
||||||
|
|
||||||
|
func PathExists(path string) bool { |
||||||
|
_, err := os.Stat(path) |
||||||
|
if err == nil { |
||||||
|
return true |
||||||
|
} |
||||||
|
if os.IsNotExist(err) { |
||||||
|
return false |
||||||
|
} |
||||||
|
panic(err) |
||||||
|
} |
@ -1,76 +0,0 @@ |
|||||||
package main |
|
||||||
|
|
||||||
import ( |
|
||||||
"crypto/rand" |
|
||||||
"crypto/rsa" |
|
||||||
"crypto/x509" |
|
||||||
"encoding/asn1" |
|
||||||
"encoding/gob" |
|
||||||
"encoding/pem" |
|
||||||
"fmt" |
|
||||||
"os" |
|
||||||
) |
|
||||||
|
|
||||||
func main() { |
|
||||||
reader := rand.Reader |
|
||||||
bitSize := 2048 |
|
||||||
|
|
||||||
key, err := rsa.GenerateKey(reader, bitSize) |
|
||||||
checkError(err) |
|
||||||
|
|
||||||
publicKey := key.PublicKey |
|
||||||
|
|
||||||
saveGobKey("private.key", key) |
|
||||||
savePEMKey("private.pem", key) |
|
||||||
|
|
||||||
saveGobKey("public.key", publicKey) |
|
||||||
savePublicPEMKey("public.pem", publicKey) |
|
||||||
} |
|
||||||
|
|
||||||
func saveGobKey(fileName string, key interface{}) { |
|
||||||
outFile, err := os.Create(fileName) |
|
||||||
checkError(err) |
|
||||||
defer outFile.Close() |
|
||||||
|
|
||||||
encoder := gob.NewEncoder(outFile) |
|
||||||
err = encoder.Encode(key) |
|
||||||
checkError(err) |
|
||||||
} |
|
||||||
|
|
||||||
func savePEMKey(fileName string, key *rsa.PrivateKey) { |
|
||||||
outFile, err := os.Create(fileName) |
|
||||||
checkError(err) |
|
||||||
defer outFile.Close() |
|
||||||
|
|
||||||
var privateKey = &pem.Block{ |
|
||||||
Type: "PRIVATE KEY", |
|
||||||
Bytes: x509.MarshalPKCS1PrivateKey(key), |
|
||||||
} |
|
||||||
|
|
||||||
err = pem.Encode(outFile, privateKey) |
|
||||||
checkError(err) |
|
||||||
} |
|
||||||
|
|
||||||
func savePublicPEMKey(fileName string, pubkey rsa.PublicKey) { |
|
||||||
asn1Bytes, err := asn1.Marshal(pubkey) |
|
||||||
checkError(err) |
|
||||||
|
|
||||||
var pemkey = &pem.Block{ |
|
||||||
Type: "PUBLIC KEY", |
|
||||||
Bytes: asn1Bytes, |
|
||||||
} |
|
||||||
|
|
||||||
pemfile, err := os.Create(fileName) |
|
||||||
checkError(err) |
|
||||||
defer pemfile.Close() |
|
||||||
|
|
||||||
err = pem.Encode(pemfile, pemkey) |
|
||||||
checkError(err) |
|
||||||
} |
|
||||||
|
|
||||||
func checkError(err error) { |
|
||||||
if err != nil { |
|
||||||
fmt.Println("Fatal error ", err.Error()) |
|
||||||
os.Exit(1) |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue