golang go1.4 TestMain示例
go1.4 TestMain示例
testmain_example_test.go
package example_test
import (
"os"
"testing"
)
func TestA(t *testing.T) {
}
func TestB(t *testing.T) {
}
func setup() {
println("setup")
}
func teardown() {
println("teardown")
}
func TestMain(m *testing.M) {
setup()
ret := m.Run()
if ret == 0 {
teardown()
}
os.Exit(ret)
}
golang Go和MongoDB的JSON-API:最终部分
Go和MongoDB的JSON-API:最终部分
main.go
package main
import (
"encoding/json"
"log"
"net/http"
"reflect"
"time"
"github.com/gorilla/context"
"github.com/julienschmidt/httprouter"
"github.com/justinas/alice"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
// Repo
type Tea struct {
Id bson.ObjectId `json:"id,omitempty" bson:"_id,omitempty"`
Name string `json:"name"`
Category string `json:"category"`
}
type TeasCollection struct {
Data []Tea `json:"data"`
}
type TeaResource struct {
Data Tea `json:"data"`
}
type TeaRepo struct {
coll *mgo.Collection
}
func (r *TeaRepo) All() (TeasCollection, error) {
result := TeasCollection{[]Tea{}}
err := r.coll.Find(nil).All(&result.Data)
if err != nil {
return result, err
}
return result, nil
}
func (r *TeaRepo) Find(id string) (TeaResource, error) {
result := TeaResource{}
err := r.coll.FindId(bson.ObjectIdHex(id)).One(&result.Data)
if err != nil {
return result, err
}
return result, nil
}
func (r *TeaRepo) Create(tea *Tea) error {
id := bson.NewObjectId()
_, err := r.coll.UpsertId(id, tea)
if err != nil {
return err
}
tea.Id = id
return nil
}
func (r *TeaRepo) Update(tea *Tea) error {
err := r.coll.UpdateId(tea.Id, tea)
if err != nil {
return err
}
return nil
}
func (r *TeaRepo) Delete(id string) error {
err := r.coll.RemoveId(bson.ObjectIdHex(id))
if err != nil {
return err
}
return nil
}
// Errors
type Errors struct {
Errors []*Error `json:"errors"`
}
type Error struct {
Id string `json:"id"`
Status int `json:"status"`
Title string `json:"title"`
Detail string `json:"detail"`
}
func WriteError(w http.ResponseWriter, err *Error) {
w.Header().Set("Content-Type", "application/vnd.api+json")
w.WriteHeader(err.Status)
json.NewEncoder(w).Encode(Errors{[]*Error{err}})
}
var (
ErrBadRequest = &Error{"bad_request", 400, "Bad request", "Request body is not well-formed. It must be JSON."}
ErrNotAcceptable = &Error{"not_acceptable", 406, "Not Acceptable", "Accept header must be set to 'application/vnd.api+json'."}
ErrUnsupportedMediaType = &Error{"unsupported_media_type", 415, "Unsupported Media Type", "Content-Type header must be set to: 'application/vnd.api+json'."}
ErrInternalServer = &Error{"internal_server_error", 500, "Internal Server Error", "Something went wrong."}
)
// Middlewares
func recoverHandler(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
log.Printf("panic: %+v", err)
WriteError(w, ErrInternalServer)
}
}()
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func loggingHandler(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
t1 := time.Now()
next.ServeHTTP(w, r)
t2 := time.Now()
log.Printf("[%s] %q %v\n", r.Method, r.URL.String(), t2.Sub(t1))
}
return http.HandlerFunc(fn)
}
func acceptHandler(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Accept") != "application/vnd.api+json" {
WriteError(w, ErrNotAcceptable)
return
}
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func contentTypeHandler(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Content-Type") != "application/vnd.api+json" {
WriteError(w, ErrUnsupportedMediaType)
return
}
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func bodyHandler(v interface{}) func(http.Handler) http.Handler {
t := reflect.TypeOf(v)
m := func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
val := reflect.New(t).Interface()
err := json.NewDecoder(r.Body).Decode(val)
if err != nil {
WriteError(w, ErrBadRequest)
return
}
if next != nil {
context.Set(r, "body", val)
next.ServeHTTP(w, r)
}
}
return http.HandlerFunc(fn)
}
return m
}
// Main handlers
type appContext struct {
db *mgo.Database
}
func (c *appContext) teasHandler(w http.ResponseWriter, r *http.Request) {
repo := TeaRepo{c.db.C("teas")}
teas, err := repo.All()
if err != nil {
panic(err)
}
w.Header().Set("Content-Type", "application/vnd.api+json")
json.NewEncoder(w).Encode(teas)
}
func (c *appContext) teaHandler(w http.ResponseWriter, r *http.Request) {
params := context.Get(r, "params").(httprouter.Params)
repo := TeaRepo{c.db.C("teas")}
tea, err := repo.Find(params.ByName("id"))
if err != nil {
panic(err)
}
w.Header().Set("Content-Type", "application/vnd.api+json")
json.NewEncoder(w).Encode(tea)
}
func (c *appContext) createTeaHandler(w http.ResponseWriter, r *http.Request) {
body := context.Get(r, "body").(*TeaResource)
repo := TeaRepo{c.db.C("teas")}
err := repo.Create(&body.Data)
if err != nil {
panic(err)
}
w.Header().Set("Content-Type", "application/vnd.api+json")
w.WriteHeader(201)
json.NewEncoder(w).Encode(body)
}
func (c *appContext) updateTeaHandler(w http.ResponseWriter, r *http.Request) {
params := context.Get(r, "params").(httprouter.Params)
body := context.Get(r, "body").(*TeaResource)
body.Data.Id = bson.ObjectIdHex(params.ByName("id"))
repo := TeaRepo{c.db.C("teas")}
err := repo.Update(&body.Data)
if err != nil {
panic(err)
}
w.WriteHeader(204)
w.Write([]byte("\n"))
}
func (c *appContext) deleteTeaHandler(w http.ResponseWriter, r *http.Request) {
params := context.Get(r, "params").(httprouter.Params)
repo := TeaRepo{c.db.C("teas")}
err := repo.Delete(params.ByName("id"))
if err != nil {
panic(err)
}
w.WriteHeader(204)
w.Write([]byte("\n"))
}
// Router
type router struct {
*httprouter.Router
}
func (r *router) Get(path string, handler http.Handler) {
r.GET(path, wrapHandler(handler))
}
func (r *router) Post(path string, handler http.Handler) {
r.POST(path, wrapHandler(handler))
}
func (r *router) Put(path string, handler http.Handler) {
r.PUT(path, wrapHandler(handler))
}
func (r *router) Delete(path string, handler http.Handler) {
r.DELETE(path, wrapHandler(handler))
}
func NewRouter() *router {
return &router{httprouter.New()}
}
func wrapHandler(h http.Handler) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
context.Set(r, "params", ps)
h.ServeHTTP(w, r)
}
}
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
appC := appContext{session.DB("test")}
commonHandlers := alice.New(context.ClearHandler, loggingHandler, recoverHandler, acceptHandler)
router := NewRouter()
router.Get("/teas/:id", commonHandlers.ThenFunc(appC.teaHandler))
router.Put("/teas/:id", commonHandlers.Append(contentTypeHandler, bodyHandler(TeaResource{})).ThenFunc(appC.updateTeaHandler))
router.Delete("/teas/:id", commonHandlers.ThenFunc(appC.deleteTeaHandler))
router.Get("/teas", commonHandlers.ThenFunc(appC.teasHandler))
router.Post("/teas", commonHandlers.Append(contentTypeHandler, bodyHandler(TeaResource{})).ThenFunc(appC.createTeaHandler))
http.ListenAndServe(":8080", router)
}
golang 转到SSH服务器完整示例 - 在此处阅读更多内容https://blog.gopheracademy.com/go-and-ssh/
转到SSH服务器完整示例 - 在此处阅读更多内容https://blog.gopheracademy.com/go-and-ssh/
sshd.go
// A small SSH daemon providing bash sessions
//
// Server:
// cd my/new/dir/
// #generate server keypair
// ssh-keygen -t rsa
// go get -v .
// go run sshd.go
//
// Client:
// ssh foo@localhost -p 2200 #pass=bar
package main
import (
"encoding/binary"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"os/exec"
"sync"
"syscall"
"unsafe"
"github.com/kr/pty"
"golang.org/x/crypto/ssh"
)
func main() {
// In the latest version of crypto/ssh (after Go 1.3), the SSH server type has been removed
// in favour of an SSH connection type. A ssh.ServerConn is created by passing an existing
// net.Conn and a ssh.ServerConfig to ssh.NewServerConn, in effect, upgrading the net.Conn
// into an ssh.ServerConn
config := &ssh.ServerConfig{
//Define a function to run when a client attempts a password login
PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
// Should use constant-time compare (or better, salt+hash) in a production setting.
if c.User() == "foo" && string(pass) == "bar" {
return nil, nil
}
return nil, fmt.Errorf("password rejected for %q", c.User())
},
// You may also explicitly allow anonymous client authentication, though anon bash
// sessions may not be a wise idea
// NoClientAuth: true,
}
// You can generate a keypair with 'ssh-keygen -t rsa'
privateBytes, err := ioutil.ReadFile("id_rsa")
if err != nil {
log.Fatal("Failed to load private key (./id_rsa)")
}
private, err := ssh.ParsePrivateKey(privateBytes)
if err != nil {
log.Fatal("Failed to parse private key")
}
config.AddHostKey(private)
// Once a ServerConfig has been configured, connections can be accepted.
listener, err := net.Listen("tcp", "0.0.0.0:2200")
if err != nil {
log.Fatalf("Failed to listen on 2200 (%s)", err)
}
// Accept all connections
log.Print("Listening on 2200...")
for {
tcpConn, err := listener.Accept()
if err != nil {
log.Printf("Failed to accept incoming connection (%s)", err)
continue
}
// Before use, a handshake must be performed on the incoming net.Conn.
sshConn, chans, reqs, err := ssh.NewServerConn(tcpConn, config)
if err != nil {
log.Printf("Failed to handshake (%s)", err)
continue
}
log.Printf("New SSH connection from %s (%s)", sshConn.RemoteAddr(), sshConn.ClientVersion())
// Discard all global out-of-band Requests
go ssh.DiscardRequests(reqs)
// Accept all channels
go handleChannels(chans)
}
}
func handleChannels(chans <-chan ssh.NewChannel) {
// Service the incoming Channel channel in go routine
for newChannel := range chans {
go handleChannel(newChannel)
}
}
func handleChannel(newChannel ssh.NewChannel) {
// Since we're handling a shell, we expect a
// channel type of "session". The also describes
// "x11", "direct-tcpip" and "forwarded-tcpip"
// channel types.
if t := newChannel.ChannelType(); t != "session" {
newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
return
}
// At this point, we have the opportunity to reject the client's
// request for another logical connection
connection, requests, err := newChannel.Accept()
if err != nil {
log.Printf("Could not accept channel (%s)", err)
return
}
// Fire up bash for this session
bash := exec.Command("bash")
// Prepare teardown function
close := func() {
connection.Close()
_, err := bash.Process.Wait()
if err != nil {
log.Printf("Failed to exit bash (%s)", err)
}
log.Printf("Session closed")
}
// Allocate a terminal for this channel
log.Print("Creating pty...")
bashf, err := pty.Start(bash)
if err != nil {
log.Printf("Could not start pty (%s)", err)
close()
return
}
//pipe session to bash and visa-versa
var once sync.Once
go func() {
io.Copy(connection, bashf)
once.Do(close)
}()
go func() {
io.Copy(bashf, connection)
once.Do(close)
}()
// Sessions have out-of-band requests such as "shell", "pty-req" and "env"
go func() {
for req := range requests {
switch req.Type {
case "shell":
// We only accept the default shell
// (i.e. no command in the Payload)
if len(req.Payload) == 0 {
req.Reply(true, nil)
}
case "pty-req":
termLen := req.Payload[3]
w, h := parseDims(req.Payload[termLen+4:])
SetWinsize(bashf.Fd(), w, h)
// Responding true (OK) here will let the client
// know we have a pty ready for input
req.Reply(true, nil)
case "window-change":
w, h := parseDims(req.Payload)
SetWinsize(bashf.Fd(), w, h)
}
}
}()
}
// =======================
// parseDims extracts terminal dimensions (width x height) from the provided buffer.
func parseDims(b []byte) (uint32, uint32) {
w := binary.BigEndian.Uint32(b)
h := binary.BigEndian.Uint32(b[4:])
return w, h
}
// ======================
// Winsize stores the Height and Width of a terminal.
type Winsize struct {
Height uint16
Width uint16
x uint16 // unused
y uint16 // unused
}
// SetWinsize sets the size of the given pty.
func SetWinsize(fd uintptr, w, h uint32) {
ws := &Winsize{Width: uint16(w), Height: uint16(h)}
syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
}
// Borrowed from https://github.com/creack/termios/blob/master/win/win.go
golang 使用接口进行从字符串到Struct的类型转换的基本示例
使用接口进行从字符串到Struct的类型转换的基本示例
nativecmdr.go
// nativecmdr project nativecmdr.go
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
"strconv"
"strings"
"syscall"
)
const (
ENOSLC = "failed to produce slice of values"
ENOMATRIX = "there are no x,y elements in matrix"
PYCMD = "/usr/local/bin/python"
PYARG_WORK = "for i in range(0, 16): print('%d,%d' % (i, i*i))"
PYARG_NO_WORK = "for i in range(0, 16): print('%d:%d' % (i, i*i))"
)
type Nativer interface {
NativeType(s string) error
HasError() bool
}
type MatrixArrayResult struct {
Xprime []int
Yprime []int
Error error
ExitCode int
}
type CmdResult struct {
Stdout string
Stderr string
ExitCode int
}
func (m *MatrixArrayResult) HasError() bool {
if m.ExitCode == 0 {
return false
} else {
return true
}
}
func (m *MatrixArrayResult) NativeType(s string) error {
var mkerr = func(s string) error {
return fmt.Errorf("%v", s)
}
var strslc = strings.Split(s, "\n")
if len(strslc) < 1 {
m.Error = mkerr(ENOSLC)
return mkerr(ENOSLC)
}
for _, val := range strslc {
tm := strings.Split(val, ",")
if len(tm) < 2 { // range errors are not what we want
break
}
x, _ := strconv.Atoi(tm[0]) // Unchecked err
y, _ := strconv.Atoi(tm[1]) // Unchecked err
m.Xprime = append(m.Xprime, x)
m.Yprime = append(m.Yprime, y)
}
if len(m.Xprime) < 1 || len(m.Yprime) < 1 {
m.Error = mkerr(ENOMATRIX)
return mkerr(ENOMATRIX)
}
return nil
}
func ErrHandle(e error) error {
if e != nil {
log.Printf("%v", fmt.Errorf("%v", e.Error()))
return e
}
return nil
}
func RunCmd(ex Nativer, command string, args ...string) error {
var result CmdResult
cmd := exec.Command(command, args...)
// Stdout buffer
cmdOutput := &bytes.Buffer{}
// Attach buffer to command
cmd.Stdout = cmdOutput
//Stderr buffer
cmdError := &bytes.Buffer{}
//Attach buffer to cmd
cmd.Stderr = cmdError
var waitStatus syscall.WaitStatus
if err := cmd.Run(); err != nil {
//Grab stderr
result.Stderr = string(cmdError.Bytes())
// Did the command fail because of an unsuccessful exit code
if exitError, ok := err.(*exec.ExitError); ok {
waitStatus = exitError.Sys().(syscall.WaitStatus)
//Store exit code
result.ExitCode = waitStatus.ExitStatus()
} else {
//There was not exit error because the command never ran.
//Let's set an error ourselves so there is no confusion.
result.Stderr = fmt.Sprintf("error running command: %s", command)
//Store exit code for Bash command not found
result.ExitCode = 127
}
} else {
//Grab stdout and stuff it into return stdout as string
result.Stdout = string(cmdOutput.Bytes())
// Command was successful
waitStatus = cmd.ProcessState.Sys().(syscall.WaitStatus)
//Store exit code
result.ExitCode = waitStatus.ExitStatus()
}
if e := ex.NativeType(result.Stdout); e != nil {
return nil // In reality this should return `e` instead of nil
}
return nil
}
func main() {
var Amatrix Nativer = &MatrixArrayResult{}
var Bmatrix Nativer = &MatrixArrayResult{}
//var Amatrix = Nativer(&MatrixArrayResult{}) // A bit more ugly than above
//var Bmatrix = Nativer(&MatrixArrayResult{})
// This should work, Nil error
if e := RunCmd(Amatrix, PYCMD, "-c", PYARG_WORK); e == nil {
fmt.Printf("Matrix Xs: %v\nMatrix Ys: %v\nError: %v\n",
Amatrix.(*MatrixArrayResult).Xprime, // assertions must be checked
Amatrix.(*MatrixArrayResult).Yprime,
Amatrix.(*MatrixArrayResult).Error)
}
// This should not work, non-Nil error
if e := RunCmd(Bmatrix, PYCMD, "-c", PYARG_NO_WORK); e == nil {
fmt.Printf("Matrix Xs: %v\nMatrix Ys: %v\nError: %v\n",
Bmatrix.(*MatrixArrayResult).Xprime, // assertions must be checked
Bmatrix.(*MatrixArrayResult).Yprime,
Bmatrix.(*MatrixArrayResult).Error)
}
//
// Results of running above should look something like this:
//
//Matrix Xs: [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
//Matrix Ys: [0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225]
//Error: <nil>
//Matrix Xs: []
//Matrix Ys: []
//Error: there are no x,y elements in matrix
}
mknativetype.go
// mknativetype project main.go
package main
import (
"fmt"
"strconv"
"strings"
)
type Nativer interface {
NativeType(s string) error
}
type Foo struct {
Fruit string
Veg string
Array []byte
}
type Bar struct {
First string
Last string
Array []byte
}
type Matrix struct {
X int
Y int
}
func (m *Matrix) NativeType(s string) error {
var sep = ","
var strslc = strings.SplitN(s, sep, 4)
m.X, _ = strconv.Atoi(strslc[0])
m.Y, _ = strconv.Atoi(strslc[2])
return nil
}
func (f *Foo) NativeType(s string) error {
var sep = ";"
var strslc = strings.SplitN(s, sep, 3)
f.Fruit = strslc[0]
f.Veg = strslc[1]
f.Array = []byte(s)
return nil
}
func (b *Bar) NativeType(s string) error {
var sep = " "
var strslc = strings.SplitN(s, sep, 5)
b.First = strslc[2]
b.Last = strslc[3]
b.Array = []byte(fmt.Sprintf("%s %s", strslc[2], strslc[3]))
return nil
}
func MimicCommand(s string, n Nativer) error {
err := n.NativeType(s)
if err != nil {
return fmt.Errorf("%s", "poof")
}
return nil
}
func main() {
var f1 Nativer = &Foo{}
var b1 Nativer = &Bar{}
var m1 Nativer = &Matrix{}
MimicCommand("apple;detroit-red beet;banana;sweet potato", f1)
MimicCommand("junk more.junk Joe Buckeye is a Ducks Fan", b1)
MimicCommand("100,-0.5,20,-0.3", m1)
fmt.Printf("Food -- Fruit: %v Vegetable: %v Array: %v\n", f1.(*Foo).Fruit, f1.(*Foo).Veg, f1.(*Foo).Array)
fmt.Printf("Name -- First: %v Last: %v Array: %v\n", b1.(*Bar).First, b1.(*Bar).Last, b1.(*Bar).Array)
fmt.Printf("Matrix -- X: %v Y: %v\n", m1.(*Matrix).X, m1.(*Matrix).Y)
}
golang 从切片中删除元素
从切片中删除元素
remove.go
func remove(array []interface{}, index int) []interface{} {
if index < 0 || index > len(array) {
return array
}
return append(array[0:index], array[index+1:]...)
}
golang 在切片中查找元素
在切片中查找元素
find.go
func find(array []interface{}, item interface{}) (index int) {
index = -1
for idx, value := range array {
if value == item {
index = idx
break
}
}
return
}
golang 去lang SSH连接
去lang SSH连接
ssh.go
package main
import (
"bytes"
"code.google.com/p/go.crypto/ssh"
"fmt"
"io/ioutil"
"os"
)
func main() {
pk, _ := ioutil.ReadFile(os.Getenv("HOME") + "/.ssh/id_rsa")
signer, err := ssh.ParsePrivateKey(pk)
if err != nil {
panic(err)
}
config := &ssh.ClientConfig{
User: "root",
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
}
client, err := ssh.Dial("tcp", "hostname:22", config)
if err != nil {
panic("Failed to dial: " + err.Error())
}
// Each ClientConn can support multiple interactive sessions,
// represented by a Session.
session, err := client.NewSession()
if err != nil {
panic("Failed to create session: " + err.Error())
}
defer session.Close()
// Once a Session is created, you can execute a single command on
// the remote side using the Run method.
var b bytes.Buffer
session.Stdout = &b
if err := session.Run("ls"); err != nil {
panic("Failed to run: " + err.Error())
}
fmt.Println(b.String())
}
golang Golang RSA OAEP Decrypt
Golang RSA OAEP Decrypt
golang_rsa_oaep_decrypt.go
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
)
//c# encrypted data
var encryptedData = `A1bZVqSMn983riamWR1ArGVOlMEllOjkCZVcmlyl9sgUYWr4ui1_g6XAfFi0EJrRsLeI2I2586x76fDN_8thT1jLcjdYcWDrcB24f7bgZ8iyRI2qMEJxYln4pkz3v5R07T7eG0sv1p5YNihObg48PzjIydaey5yM7vl8Cq1Hs-chz77qu6heObkyh6239WQgyRF3cqpLH_OPQ51fjTYI9zDfiptbAOJSE5WKDEArXLZxnb1NissiqOGdkpM9q4F7TRKzJ3RFxH5Gkcpx0A3xq8_HU7Z71O4Dv_emfjIcJyAJLWA4Ye831MVblcGYexcNzVqHQPmkJSfgl5GmQwyKbTevsggIMh9Jzhrbrg9En2zScnGMRsbJDC6zdoupr5EIXLfU`
var privateKeyData = `
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAygGoUiTD+LjwZIgwFZyjiibWNQ2LM9xZ2pjKQGP8iUBtAuAW
629/Ofw8qxToMyixPrG4A7j8+KOPwYrWPGV6Og//4zm3cG+1hQvnNUWtMjHHBY8O
ByUPQ6/T8XHER1DxFBfnWfFLZ1yFX6oNNuvtLgOreI6ehehJd5IB/4mOjMvFEBgO
Eejado2n55VNdcFpdQ3RcvGV+f/rl/lsIM08QvL3lc5gqawj53sW9YZi1DL/uN48
R+ghvAYhtx2jpHDBvlH1NCF1rU6CynYsgV9QIksv0ihwl4T+k5F9ir0uv0WIS6kK
KS1SRpAprRKunos4PlE8l2+jC6LaJUPhDZlj/wIDAQABAoIBAHIcX5YPeLie2AUi
PW9n7aYT7DtJ7FGebw+h8dZP5Q8vWqUeKzRR5p+90hOemtCTcxSEVfucWyKlWoat
Q/oYJOR5t0YHi40zPWnr4G7ibkUFg3Sra/QzRh0pTON+La9PlO+R1TmkqcC4rgrt
R8u3mGK+5fUTM49XOXEXBJPyg5kaXQpiA4BoIRdRnCSitNxWA8kxMkQYJYlwAYab
cKo4Ik/J6+YGG7m2FtrUAWpWVUMBzEYOmGJ7JhSJ1u0UC/Oh1HOS1xlGopkmexbd
EygY3hTNWzHmYaYcYQs0f+8aVcVL64Gm0dtqvAHNnBvudMThhQgdYPc39mNLbrwI
ks4uS8ECgYEA9XfvcGKsNrHA0nqoPUPMT0Nfvv/4XCaKOYk25brH4LbqJPm6CiU6
uNlKFQsxzHPmx7OEK7EYVVZCbSO9s4t/xCzDVNbOZ9kDL6bkTX9DArLE4d6IRF/1
WW/AlNPuwVgxl0kcJILFtLqA1WoC5UWMhbYe2YB/Q3rCozmn0AiwyqECgYEA0qxd
KClKAMIsrB0WJ9gZEsJOpFi4q4g6T1BwT40Xj6Ul6o6DHi6hFhPgZAstqmnY0ANz
ezQ2yxtIm7zSy7S+nwDUycjY9riJcomc/YQZNA2QVM16hEv84VLwH1MVV2wkTb41
DWjbcg/ZNofZHl9AQIw7es+R3mmtDN+8BZOZSp8CgYBHtwmaUQm1VQtbswAyHfuz
8KApgklCSvQ5SRBj38UDrw0LTnZ+/k+Ar+MH8ORUskvrblQgG7ZbQD9Z+YYzzX6/
hsBuqe9Vwb4/jsfGqHagdDA3OTegmlRpE9A06xInJKggZfi15gry+UYok7dS2pXq
fsHWk8capOP2oiKYEeHs4QKBgF2KcLaDVrtte/5Tz+GTHtbodZidWCm5jAJpeeSo
hfye3G4AJxHArH+sBacGG5md88mwrpbWwTl/fMbBmWsfbsAU02ZhCozJtSWpGo6q
F7K4DwzIS4zwXHEDrWCLOF+fwaLPQKkalM1ZYh3HRc0ph9LhMQu/nEn/6/laYhar
yZWLAoGASvCrpFKn0qllMKNUetBmYFpgtjmnNuW7l0xT2UftkW6AuFjU19gKgXhe
I+uZciHQ8kIUHfNLYBbhETsF3iqsklKfeoIr23zYHLE5GpoC151IpKf4guoPbCHX
a1oCDuZm//f5HMePb9juJN0WR//d5jWuizAycZf41XoEd8Bqydg=
-----END RSA PRIVATE KEY-----
`
func main() {
//golang encrypted data
encryptedData = `eE167RoMG0AgczAMUdaQ0581PRuCQA1_xNNkqiq-zR6y93YXz6hqqP-arAwGCcUySFqxvvgopVyWBABM5MBnhEGhUBvADae6EAwNWSFxm5buUBHFmHqYNrRWQaxO8F7QUZK1llctd_euoWixxAKCVIqnE0UsbcZEveULYgm3EVwbJTPUyfdRbX--lmDbsWHM2YEVuwL6f1jph_XrwKWUt62jbRnp21f7zPj2mWFZEUvCt_s6KfzymZRNky-0-QSKVI4IygZM2ZZ9gjjj7CXnrvpyTYc2_P86SHaYTP9ZhoOwdTixaRE60hnzZ5N1oUXYI99LD_-E6NziZxGoXg6qsA==`
hash := sha1.New()
random := rand.Reader
privateKeyBlock, _ := pem.Decode([]byte(privateKeyData))
var pri *rsa.PrivateKey
pri, parseErr := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
if parseErr != nil {
fmt.Println("Load private key error")
panic(parseErr)
}
decodedData, _ := base64.URLEncoding.DecodeString(encryptedData)
decryptedData, decryptErr := rsa.DecryptOAEP(hash, random, pri, decodedData, nil)
if decryptErr != nil {
fmt.Println("Decrypt data error")
panic(decryptErr)
}
fmt.Println(string(decryptedData))
}
golang Golang RSA-OAEP加密和解密
Golang RSA-OAEP加密和解密
golang_rsa_oaep.go
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
)
func main() {
var publicKeyData = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAygGoUiTD+LjwZIgwFZyj
iibWNQ2LM9xZ2pjKQGP8iUBtAuAW629/Ofw8qxToMyixPrG4A7j8+KOPwYrWPGV6
Og//4zm3cG+1hQvnNUWtMjHHBY8OByUPQ6/T8XHER1DxFBfnWfFLZ1yFX6oNNuvt
LgOreI6ehehJd5IB/4mOjMvFEBgOEejado2n55VNdcFpdQ3RcvGV+f/rl/lsIM08
QvL3lc5gqawj53sW9YZi1DL/uN48R+ghvAYhtx2jpHDBvlH1NCF1rU6CynYsgV9Q
Iksv0ihwl4T+k5F9ir0uv0WIS6kKKS1SRpAprRKunos4PlE8l2+jC6LaJUPhDZlj
/wIDAQAB
-----END PUBLIC KEY-----
`
var privateKeyData = `
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAygGoUiTD+LjwZIgwFZyjiibWNQ2LM9xZ2pjKQGP8iUBtAuAW
629/Ofw8qxToMyixPrG4A7j8+KOPwYrWPGV6Og//4zm3cG+1hQvnNUWtMjHHBY8O
ByUPQ6/T8XHER1DxFBfnWfFLZ1yFX6oNNuvtLgOreI6ehehJd5IB/4mOjMvFEBgO
Eejado2n55VNdcFpdQ3RcvGV+f/rl/lsIM08QvL3lc5gqawj53sW9YZi1DL/uN48
R+ghvAYhtx2jpHDBvlH1NCF1rU6CynYsgV9QIksv0ihwl4T+k5F9ir0uv0WIS6kK
KS1SRpAprRKunos4PlE8l2+jC6LaJUPhDZlj/wIDAQABAoIBAHIcX5YPeLie2AUi
PW9n7aYT7DtJ7FGebw+h8dZP5Q8vWqUeKzRR5p+90hOemtCTcxSEVfucWyKlWoat
Q/oYJOR5t0YHi40zPWnr4G7ibkUFg3Sra/QzRh0pTON+La9PlO+R1TmkqcC4rgrt
R8u3mGK+5fUTM49XOXEXBJPyg5kaXQpiA4BoIRdRnCSitNxWA8kxMkQYJYlwAYab
cKo4Ik/J6+YGG7m2FtrUAWpWVUMBzEYOmGJ7JhSJ1u0UC/Oh1HOS1xlGopkmexbd
EygY3hTNWzHmYaYcYQs0f+8aVcVL64Gm0dtqvAHNnBvudMThhQgdYPc39mNLbrwI
ks4uS8ECgYEA9XfvcGKsNrHA0nqoPUPMT0Nfvv/4XCaKOYk25brH4LbqJPm6CiU6
uNlKFQsxzHPmx7OEK7EYVVZCbSO9s4t/xCzDVNbOZ9kDL6bkTX9DArLE4d6IRF/1
WW/AlNPuwVgxl0kcJILFtLqA1WoC5UWMhbYe2YB/Q3rCozmn0AiwyqECgYEA0qxd
KClKAMIsrB0WJ9gZEsJOpFi4q4g6T1BwT40Xj6Ul6o6DHi6hFhPgZAstqmnY0ANz
ezQ2yxtIm7zSy7S+nwDUycjY9riJcomc/YQZNA2QVM16hEv84VLwH1MVV2wkTb41
DWjbcg/ZNofZHl9AQIw7es+R3mmtDN+8BZOZSp8CgYBHtwmaUQm1VQtbswAyHfuz
8KApgklCSvQ5SRBj38UDrw0LTnZ+/k+Ar+MH8ORUskvrblQgG7ZbQD9Z+YYzzX6/
hsBuqe9Vwb4/jsfGqHagdDA3OTegmlRpE9A06xInJKggZfi15gry+UYok7dS2pXq
fsHWk8capOP2oiKYEeHs4QKBgF2KcLaDVrtte/5Tz+GTHtbodZidWCm5jAJpeeSo
hfye3G4AJxHArH+sBacGG5md88mwrpbWwTl/fMbBmWsfbsAU02ZhCozJtSWpGo6q
F7K4DwzIS4zwXHEDrWCLOF+fwaLPQKkalM1ZYh3HRc0ph9LhMQu/nEn/6/laYhar
yZWLAoGASvCrpFKn0qllMKNUetBmYFpgtjmnNuW7l0xT2UftkW6AuFjU19gKgXhe
I+uZciHQ8kIUHfNLYBbhETsF3iqsklKfeoIr23zYHLE5GpoC151IpKf4guoPbCHX
a1oCDuZm//f5HMePb9juJN0WR//d5jWuizAycZf41XoEd8Bqydg=
-----END RSA PRIVATE KEY-----
`
pubKeyBlock, _ := pem.Decode([]byte(publicKeyData))
hash := sha1.New()
random := rand.Reader
msg := []byte("helloworldjemyme")
var pub *rsa.PublicKey
pubInterface, parseErr := x509.ParsePKIXPublicKey(pubKeyBlock.Bytes)
if parseErr != nil {
fmt.Println("Load public key error")
panic(parseErr)
}
pub = pubInterface.(*rsa.PublicKey)
encryptedData, encryptErr := rsa.EncryptOAEP(hash, random, pub, msg, nil)
if encryptErr != nil {
fmt.Println("Encrypt data error")
panic(encryptErr)
}
encodedData := base64.URLEncoding.EncodeToString(encryptedData)
fmt.Println(encodedData)
fmt.Println()
fmt.Println("------I AM JUST A LINE------")
fmt.Println()
privateKeyBlock, _ := pem.Decode([]byte(privateKeyData))
var pri *rsa.PrivateKey
pri, parseErr = x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
if parseErr != nil {
fmt.Println("Load private key error")
panic(parseErr)
}
decryptedData, decryptErr := rsa.DecryptOAEP(hash, random, pri, encryptedData, nil)
if decryptErr != nil {
fmt.Println("Decrypt data error")
panic(decryptErr)
}
fmt.Println(string(decryptedData))
}
golang Lockfile使用PID文件
Lockfile使用PID文件
lock.go
// Handle pid file based locking.
package lockfile
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"syscall"
)
type Lockfile string
var (
ErrBusy = errors.New("Locked by other process") // If you get this, retry after a short sleep might help
ErrNeedAbsPath = errors.New("Lockfiles must be given as absolute path names")
ErrInvalidPid = errors.New("Lockfile contains invalid pid for system")
ErrDeadOwner = errors.New("Lockfile contains pid of process not existent on this system anymore")
)
// Describe a new filename located at path. It is expected to be an absolute path
func New(path string) (Lockfile, error) {
if !filepath.IsAbs(path) {
return Lockfile(""), ErrNeedAbsPath
}
return Lockfile(path), nil
}
// Who owns the lockfile?
func (l Lockfile) GetOwner() (*os.Process, error) {
name := string(l)
// Ok, see, if we have a stale lockfile here
content, err := ioutil.ReadFile(name)
if err != nil {
return nil, err
}
var pid int
_, err = fmt.Sscanln(string(content), &pid)
if err != nil {
return nil, ErrInvalidPid
}
// try hard for pids. If no pid, the lockfile is junk anyway and we delete it.
if pid > 0 {
p, err := os.FindProcess(pid)
if err != nil {
return nil, err
}
err = p.Signal(os.Signal(syscall.Signal(0)))
if err == nil {
return p, nil
}
errno, ok := err.(syscall.Errno)
if !ok {
return nil, err
}
switch errno {
case syscall.ESRCH:
return nil, ErrDeadOwner
case syscall.EPERM:
return p, nil
default:
return nil, err
}
} else {
return nil, ErrInvalidPid
}
panic("Not reached")
}
// Try to get Lockfile lock. Returns nil, if successful and and error describing the reason, it didn't work out.
// Please note, that existing lockfiles containing pids of dead processes and lockfiles containing no pid at all
// are deleted.
func (l Lockfile) TryLock() error {
name := string(l)
// This has been checked by New already. If we trigger here,
// the caller didn't use New and re-implemented it's functionality badly.
// So panic, that he might find this easily during testing.
if !filepath.IsAbs(string(name)) {
panic(ErrNeedAbsPath)
}
tmplock, err := ioutil.TempFile(filepath.Dir(name), "")
if err != nil {
return err
} else {
defer tmplock.Close()
defer os.Remove(tmplock.Name())
}
_, err = tmplock.WriteString(fmt.Sprintf("%d\n", os.Getpid()))
if err != nil {
return err
}
// return value intentionally ignored, as ignoring it is part of the algorithm
_ = os.Link(tmplock.Name(), name)
fiTmp, err := os.Lstat(tmplock.Name())
if err != nil {
return err
}
fiLock, err := os.Lstat(name)
if err != nil {
return err
}
// Success
if os.SameFile(fiTmp, fiLock) {
return nil
}
_, err = l.GetOwner()
switch err {
default:
// Other errors -> defensively fail and let caller handle this
return err
case nil:
return ErrBusy
case ErrDeadOwner, ErrInvalidPid:
// cases we can fix below
}
// clean stale/invalid lockfile
err = os.Remove(name)
if err != nil {
return err
}
// now that we cleaned up the stale lockfile, let's recurse
return l.TryLock()
}
// Release a lock again. Returns any error that happend during release of lock.
func (l Lockfile) Unlock() error {
return os.Remove(string(l))
}