Go語言學習筆記 package

 加 Golang學習 QQ羣共同窗習進步成家立業工做 ^-^ 羣號:96933959html

strings

import "strings"前端

strings包實現了用於操做字符的簡單函數。java

strings.Index("suoning", "n")        //3(子串第一次出現的位置,不存在則返回-1)
strings.LastIndex("suoning", "n")    //5(子串最後一次出現的位置,不存在則返回-1)

strings.Replace("suoning", "ning", "nick", -1) //suonick(替換,n爲替換次數,<0替換全部子串)
strings.HasPrefix("suoning", "suo")            //true(判斷s是否有前綴字符串prefix)
strings.HasSuffix("suoning", "ning")           //true(判斷s是否有後綴字符串suffix)
strings.Contains("suoning", "suoni")           //true(判斷字符串s是否包含子串substr)

strings.Count("nnnnnn", "n")         //6(字符串中有幾個不重複的子串)
strings.Repeat("n", 6)               //nnnnnn(返回count個s串聯的字符串)

strings.ToLower("SuoNing")           //suoning(將全部字母都轉爲對應的小寫版本的拷貝)
strings.ToUpper("suoning")           //SUONING(將全部字母都轉爲對應的大寫版本的拷貝)

strings.TrimSpace("  \nsuoning\n  ") //suoning(去掉先後端全部空白)
strings.Trim("!!suoning!!", "!")     //suoning(將s先後端全部cutset包含的utf-8碼值都去掉的字符串)
strings.TrimLeft("!suoning!", "!")   //suoning!(將s前端全部cutset包含的utf-8碼值都去掉的字符串)
strings.TrimRight("!suoning!", "!")  //!suoning(將s後端全部cutset包含的utf-8碼值都去掉的字符串)

strings.Fields(" suo ning ")                   //[suo ning](按照空白分割的多個字符串)
strings.Split(",suo,ning,", ",")               //[ suo ning ](去掉s中出現的sep的方式進行分割)
strings.Join([]string{"suo", "ning"}, " ")     //suo ning(用sep來拼接爲一個字符串)

 

bytes

import "bytes"node

bytes包實現了操做[]byte的經常使用函數。本包的函數和strings包的函數至關相似。git

s1 := []byte("索寧")
s2 := []byte("")
fmt.Println(bytes.Equal(s1, s2)) //false(切片的內容是否徹底相同)

//Runes函數返回和s等價的[]rune切片。(將utf-8編碼的unicode碼值分別寫入單個rune)
r1 := bytes.Runes(s1)
r2 := bytes.Runes(s2)
fmt.Println(r1)             //[32034 23425]
fmt.Println(r2)             //[32034]
fmt.Println(r1[0] == r2[0]) //true(能夠判斷中文)

 

strconv

import "strconv"github

strconv包實現了基本數據類型和其字符串表示的相互轉換。golang

//返回字符串表示的整數值
fmt.Println(strconv.ParseInt("-999", 0, 0)) //-999 <nil>
fmt.Println(strconv.ParseUint("999", 0, 0)) //999 <nil>
fmt.Println(strconv.Atoi("999"))            //999 <nil>
//base指定進制(2到36),若是base爲0,則會從字符串前置判斷,"0x"是16進制,"0"是8進制,不然是10進制;
//bitSize指定結果必須能無溢出賦值的整數類型,0、八、1六、3二、64 分別表明 int、int八、int1六、int3二、int64;

//返回i的base進制的字符串表示
fmt.Println(strconv.FormatInt(-520, 10)) //-520
fmt.Println(strconv.FormatUint(520, 10)) //520
fmt.Println(strconv.Itoa(520))           //520
//base 必須在2到36之間,結果中會使用小寫字母'a'到'z'表示大於10的數字。

//返回字符串表示的bool值
fmt.Println(strconv.ParseBool("false"))         //false <nil>
fmt.Println(strconv.FormatBool(true))           //true
fmt.Println(strconv.AppendBool([]byte{}, true)) //[116 114 117 101]
//它接受一、0、t、f、T、F、true、false、True、False、TRUE、FALSE;不然返回錯誤。

//返回字符串表示的bool值
fmt.Println(strconv.ParseFloat("520.1314", 10))        //520.1314 <nil>
fmt.Println(strconv.FormatFloat(520.1314, 'f', 6, 32)) //520.131409
//fmt表示格式:'f'(-ddd.dddd)、'b'(-ddddp±ddd,指數爲二進制)、'e'(-d.dddde±dd,十進制指數)、'E'(-d.ddddE±dd,十進制指數)、'g'(指數很大時用'e'格式,不然'f'格式)、'G'(指數很大時用'E'格式,不然'f'格式)。
//prec控制精度(排除指數部分):對'f'、'e'、'E',它表示小數點後的數字個數;對'g'、'G',它控制總的數字個數。若是prec 爲-1,則表明使用最少數量的、但又必需的數字來表示f。
//bitSize表示f的來源類型(32:float3二、64:float64),會據此進行舍入。

  

time

import "time"json

time包提供了時間的顯示和測量用的函數。日曆的計算採用的是公曆。後端

fmt.Println(time.Now())        //2017-08-03 22:35:36.45766459 +0800 CST
fmt.Println(time.Now().Unix()) //時間戳1501771053
fmt.Println(time.Sunday)       //Sunday
fmt.Println(time.Stamp)        //Jan _2 15:04:05
fmt.Println(time.Date(2008, time.November, 11, 23, 0, 0, 0, time.UTC))
//2008-11-11 23:00:00 +0000 UTC

//格式化輸出
now := time.Now()
fmt.Println(now.Format("02/1/2006 15:04:05")) //03/8/2017 22:37:58
fmt.Println(now.Format("2006/02/1 15:04"))    //2017/03/8 22:37
fmt.Println(now.Format("2006-1-02 15:04:05")) //2017-8-03 22:37:58

m, _ := time.ParseDuration("-10m") //10分鐘前
fmt.Println(now.Add(m))            //2017-08-03 22:34:55.810202385 +0800 CST
d, _ := time.ParseDuration("-24h") //1天前
fmt.Println(now.Add(d))            //2017-08-02 22:46:28.742383801 +0800 CST
hh, _ := time.ParseDuration("1h")  //1小時後
fmt.Println(now.Add(hh))           //2017-08-03 23:47:21.458974014 +0800 CST

time.Sleep(time.Second) //睡一秒
//定時器
t := time.NewTicker(time.Second)
for v := range t.C { //每一秒執行一次, 這是個死循環
    fmt.Println(v) //2017-08-03 22:53:13.849203492 +0800 CST
}
t.Stop()

 

// 獲取到明天凌晨秒數
t := time.Now()
    t2 := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()).AddDate(0, 0, 1)
    fmt.Println(time.Second*time.Duration(t2.Unix()-t.Unix()))

 

 

math/rand

import "math/rand"安全

rand包實現了僞隨機數生成器。

隨機數從資源生成。包水平的函數都使用的默認的公共資源。該資源會在程序每次運行時都產生肯定的序列。若是須要每次運行產生不一樣的序列,應使用Seed函數進行初始化。默認資源能夠安全的用於多go程併發。

func init() {
    rand.Seed(time.Now().UnixNano()) //使用給定的seed來初始化生成器到一個肯定的狀態。
}

func main() {
    fmt.Println(rand.Int())     //9153536921449289609(返回一個非負的僞隨機int值)
    fmt.Println(rand.Int31())   //2037735069(返回一個int32類型的非負的31位僞隨機數)
    fmt.Println(rand.Int63())   //1132646811815532030(返回一個int64類型的非負的63位僞隨機數)

    fmt.Println(rand.Intn(100)) //95(取值範圍在[0,n)的僞隨機int值,n<=0會panic)
    fmt.Println(rand.Float32()) //0.09178123(取值範圍在[0.0, 1.0)的僞隨機float32值)

    fmt.Println(rand.Perm(5))   //[0 4 1 2 3](有n個元素的,[0,n)範圍內整數的僞隨機排列的切片)
}

 

os

import "os"

os包提供了操做系統函數的不依賴平臺的接口。設計爲Unix風格的,雖然錯誤處理是go風格的;失敗的調用會返回錯誤值而非錯誤碼。一般錯誤值裏包含更多信息。

fmt.Println(os.Hostname())             //bogon <nil>(返回內核提供的主機名)
fmt.Println(os.Getpagesize())          //4096(返回底層的系統內存頁的尺寸)
fmt.Println(os.Environ())              //(環境變量的格式爲"key=value"的字符串的切片拷貝)
fmt.Println(os.Getenv("GOPATH"))       //(名爲key的環境變量的值,不存在返回空)
fmt.Println(os.Setenv("Name", "Nick")) //(設置名爲key的環境變量)
os.Clearenv()    //(刪除全部環境變量)
os.Exit(0)       //(以給出的狀態碼code退出,程序會馬上終止,defer的函數不會被執行)

fmt.Println(os.Getuid())    //501(調用者的用戶ID)
fmt.Println(os.Geteuid())   //501(調用者的有效用戶ID)
fmt.Println(os.Getgid())    //20(調用者的組ID)
fmt.Println(os.Getegid())   //20(調用者的有效組ID)
fmt.Println(os.Getgroups()) //[20 701 12 61 79 80 81 ...](調用者所屬的全部用戶組的組ID)
fmt.Println(os.Getpid())    //62027(調用者所在進程的進程ID)
fmt.Println(os.Getppid())   //62020(調用者所在進程的父進程的進程ID)

fmt.Println(os.Getwd())                      //返回一個對應當前工做目錄的根路徑
os.Chdir("/tmp/")                            //將當前工做目錄修改成dir指定的目錄
os.Mkdir("/tmp/test", 0666)                  //用指定的權限和名稱建立一個目錄
os.MkdirAll("/tmp/test1/test2/test3", 0666)  //使用指定的權限和名稱建立一個目錄,遞歸上級目錄
os.Rename("/tmp/test", "/tmp/test1/testNew") //修改一個文件的名字,移動一個文件
os.Remove("/tmp/test1/test2/test3")          //刪除name指定的文件或目錄
os.RemoveAll("/tmp/test1/")                  //刪除path指定的文件

os.Create("/tmp/test")      //0666,建立文件,存在會清空
os.Open("/tmp/test")        //O_RDONLY,打開一個文件
os.OpenFile("/tmp/test", os.O_CREATE|os.O_WRONLY, 0666)

Args保管了命令行參數,第一個是程序名。

 

fmt

import "fmt"

mt包實現了相似C語言printf和scanf的格式化I/O。格式化動做('verb')源自C語言但更簡單。

通用:

%v    值的默認格式表示
%+v    相似%v,但輸出結構體時會添加字段名
%#v    值的Go語法表示
%T    值的類型的Go語法表示
%%    百分號

布爾值:

%t    單詞true或false

整數:

%b    表示爲二進制
%c    該值對應的unicode碼值
%d    表示爲十進制
%o    表示爲八進制
%q    該值對應的單引號括起來的go語法字符字面值,必要時會採用安全的轉義表示
%x    表示爲十六進制,使用a-f
%X    表示爲十六進制,使用A-F
%U    表示爲Unicode格式:U+1234,等價於"U+%04X"

浮點數與複數的兩個組分:

%b    無小數部分、二進制指數的科學計數法,如-123456p-78;參見strconv.FormatFloat
%e    科學計數法,如-1234.456e+78
%E    科學計數法,如-1234.456E+78
%f    有小數部分但無指數部分,如123.456
%F    等價於%f
%g    根據實際狀況採用%e或%f格式(以得到更簡潔、準確的輸出)
%G    根據實際狀況採用%E或%F格式(以得到更簡潔、準確的輸出)
%f:    默認寬度,默認精度
%9f    寬度9,默認精度
%.2f   默認寬度,精度2
%9.2f  寬度9,精度2
%9.f   寬度9,精度0 

字符串和[]byte:

%s    直接輸出字符串或者[]byte
%q    該值對應的雙引號括起來的go語法字符串字面值,必要時會採用安全的轉義表示
%x    每一個字節用兩字符十六進制數表示(使用a-f)
%X    每一個字節用兩字符十六進制數表示(使用A-F)

指針:

%p    表示爲十六進制,並加上前導的0x   

 

    //前置補0
    fmt.Printf("%03d", 22)
    fmt.Println("")
    fmt.Printf("%0*d", 3, 2)

 

 

errors

import "errors"

errors包實現了建立錯誤值的函數。

使用字符串建立一個錯誤,請類比fmt包的Errorf方法,差很少能夠認爲是New(fmt.Sprintf(...))。

err := errors.New("emit macho dwarf: elf header corrupted")
if err != nil {
    fmt.Print(err)    //emit macho dwarf: elf header corrupted
}
const name, id = "bimmler", 17
err := fmt.Errorf("user %q (id %d) not found", name, id)
if err != nil {
    fmt.Print(err)    //user "bimmler" (id 17) not found
}

 

json

import "encoding/json"

json包實現了json對象的編解碼。Marshal、Unmarshal函數。

 

Marshal函數返回v的json編碼:

type ColorGroup struct {
    ID     int
    Name   string
    Colors []string
}
group := ColorGroup{
    ID:     1,
    Name:   "Reds",
    Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
}
b, err := json.Marshal(group)
if err != nil {
    fmt.Println("error:", err)
}
os.Stdout.Write(b)
//{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}

 

Unmarshal函數解析json編碼的數據並將結果存入v指向的值:

var jsonBlob = []byte(`[
        {"Name": "Platypus", "Order": "Monotremata"},
        {"Name": "Quoll",    "Order": "Dasyuromorphia"}
    ]`)
type Animal struct {
    Name  string
    Order string
}
var animals []Animal
err := json.Unmarshal(jsonBlob, &animals)
if err != nil {
    fmt.Println("error:", err)
}
fmt.Printf("%+v", animals)
//[{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]

 

package main

import (
    "encoding/json"
    "fmt"
)

type User struct {
    Name string `json:"userName"`
    Age  int
}


func main() {
    u1 := &User{Name: "nick", Age: 18}

    u1Str, err := json.Marshal(u1)
    fmt.Println(err)
    fmt.Println(u1Str)

    var u User
    err = json.Unmarshal([]byte(u1Str), &u)
    fmt.Println(err)
    fmt.Println(u)

}

 

struct tag 使用: 

// 字段被本包忽略
Field int `json:"-"`
// 字段在json裏的鍵爲"myName"
Field int `json:"myName"`
// 字段在json裏的鍵爲"myName"且若是字段爲空值將在對象中省略掉
Field int `json:"myName,omitempty"`
// 字段在json裏的鍵爲"Field"(默認值),但若是字段爲空值會跳過;注意前導的逗號
Field int `json:",omitempty"`

 

time時間處理

type TimeBirthday time.Time
 
func (obj TimeBirthday) MarshalJSON() ([]byte, error) {
    seconds := time.Time(obj).Format("2006-01-02")
    return []byte(fmt.Sprintf(`"%s"`, seconds)), nil
}
 
type Account struct {
    Birthday     TimeBirthday `json:"birthday"`
    LastLoginTime  time.Time `json:"-"`
}

 

reflect

 

 

flag

import "flag"

flag包實現了命令行參數的解析。

func main() {
    var confPath string
    var port int
    var b bool

    flag.StringVar(&confPath, "conf", "", "input config path.")
    flag.IntVar(&port, "p", 8000, "input port.")
    flag.BoolVar(&b, "b", false, "input bool.")

    flag.Parse()    //註冊

    fmt.Println("config path: ", confPath)
    fmt.Println("port: ", port)
    fmt.Println("bool: ", b)
}
$ go build -o bin/test go_dev/args/main
$ bin/test -conf "/tmp/config" -p 9006 -b true
config path:  /tmp/config
port:  9006
bool:  true

 

context

 1、傳遞全局變量

func process(ctx context.Context)  {
    ret, ok := ctx.Value("trace_id").(int)
    if !ok {
        ret = 123456
    }
    fmt.Println(ret)    //111111

    s, _ := ctx.Value("name").(string)
    fmt.Println(s)    //suoning
}

func main()  {
    ctx := context.WithValue(context.Background(), "name", "suoning")
    ctx = context.WithValue(ctx, "trace_id", 111111)
    process(ctx)
}
func add(ctx context.Context, a, b int) int {
    traceId := ctx.Value("trace_id").(string)
    fmt.Printf("trace_id:%v\n", traceId)
    return a + b
}

func calc(ctx context.Context, a, b int) int {
    traceId := ctx.Value("trace_id").(string)
    fmt.Printf("trace_id:%v\n", traceId)
    return add(ctx, a, b)
}

func main() {
    ctx := context.WithValue(context.Background(), "trace_id", "123456")
    s := calc(ctx, 500, 20)
    fmt.Println(s)
}

 

2、Goroutine Timeout

package main

import (
    "net/http"
    "context"
    "time"
    "fmt"
    "io/ioutil"
)

type Result struct {
    r   *http.Response
    err error
}

func process() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    tr := &http.Transport{}
    client := &http.Client{Transport: tr}
    c := make(chan Result, 1)
    req, err := http.NewRequest("GET", "http://www.google.com", nil)
    if err != nil {
        fmt.Println("http NewRequest failed, err:", err)
        return
    }

    go func() {
        resp, err := client.Do(req)
        pack := Result{r: resp, err: err}
        c <- pack
    }()

    select {
    case <-ctx.Done():
        tr.CancelRequest(req)
        res := <-c
        fmt.Println("Timeout, err:", res.err)
    case res := <-c:
        defer res.r.Body.Close()
        out, _ := ioutil.ReadAll(res.r.Body)
        fmt.Printf("Server Response: %s", out)
    }

    return
}

func main() {
    process()
}

 

sync

等待一組Goroutine返回

package main

import (
    "sync"
    "fmt"
    "time"
)

func calc(w *sync.WaitGroup, i int)  {
    fmt.Println("calc: ", i)
    time.Sleep(time.Second)
    w.Done()
}

func main()  {
    wg := sync.WaitGroup{}
    for i:=0; i<10; i++ {
        wg.Add(1)
        go calc(&wg, i)
    }
    wg.Wait()
    fmt.Println("all goroutine finish")
}

 

net/url

    redirect := "http://cm-wzry.cmcm.com/spread/jump?uri=http%3a%2f%2fa.app.qq.com%2fo%2fsimple.jsp%3fpkgname%3dcom.cmcm.gamemaster%26f%3d6"
    // 編碼
    encodeurl := url.QueryEscape(redirect)
    fmt.Println(encodeurl)
    // 解碼
    decodeurl, err := url.QueryUnescape(encodeurl)
    if err != nil {
        panic(err)
    }
    fmt.Println(decodeurl)

 

 

regexp

 // 檢測中文字符

package main

import (
    "fmt"
    "regexp"
)

func main() {
    str := "Nick要脫單"
    var hzRegexp = regexp.MustCompile("^[\u4e00-\u9fa5]$")
    fmt.Println(hzRegexp.MatchString(str))
}

 

 // 中文截取

string([]rune(Text)[:Max])

 

 

Draw

Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op)
dst  繪圖的背景圖。
r    是背景圖的繪圖區域
src  是要繪製的圖
sp   是 src 對應的繪圖開始點(繪製的大小 r變量定義了)
mask 是繪圖時用的蒙版,控制替換圖片的方式。
mp   是繪圖時蒙版開始點(繪製的大小 r變量定義了)

// op Op is a Porter-Duff compositing operator.  參考文章:"http://blog.csdn.net/ison81/article/details/5468763"  http://blog.csdn.net/ison81/article/details/5468763
// Porter-Duff 等式12種規則能夠看這篇博客:"http://www.blogjava.net/onedaylover/archive/2008/01/16/175675.html" http://www.blogjava.net/onedaylover/archive/2008/01/16/175675.html

 

// 截取圖片的一部分
// in out 圖片絕對路徑    ("/data/zyn/%04d.jpg")("/data/zyn.jpeg")
// sx sy 開始截取點
// x1 y1 輸出圖片的大小
func CapturePortion(in, out string, sx, sy int, x1, y1 int, log *zap.SugaredLogger) error {
    file, err := os.Create(out)
    if err != nil {
        log.Errorf("os.Create(out) out(%v) err(%v)", out, err)
        return err
    }
    defer file.Close()

    file1, err := os.Open(in)
    if err != nil {
        log.Errorf("os.Open(in) in(%v) err(%v)", in, err)
        return err
    }
    defer file1.Close()

    img, err := jpeg.Decode(file1)
    if err != nil {
        log.Errorf("peg.Decode(file1) in(%v) err(%v)", in, err)
        return err
    }

    jpg := image.NewRGBA(image.Rect(0, 0, x1, y1))
    draw.Draw(jpg, img.Bounds(), img, image.Pt(sx, sy), draw.Src) //截取圖片的一部分
    if err := jpeg.Encode(file, jpg, nil); err != nil {
        log.Errorf("jpeg.Encode(file, jpg, nil) out(%v) err(%v)", out, err)
        return err
    }

    return nil
}
截取圖片的一部分

 

import (
    "errors"
    z "github.com/nutzam/zgo"
    "github.com/BurntSushi/graphics-go/graphics"
    "go.uber.org/zap"
)

// 修改圖片像素
//x1 := 720
//y1 := 1280
func PixelModification(srcPath string, outPath string, x1, y1 int, log *zap.SugaredLogger) error {
    // 打開圖片
    src, err := z.ImageJPEG(srcPath)
    // 打開失敗
    if err != nil {
        log.Errorf("z.ImageJPEG(srcPath) srcPath(%v) err(%v)", srcPath, err)
        return err
    }

    // 建立一張圖片
    dst := z.ImageRGBA(x1, y1)
    if dst == nil {
        // 異常返回
        log.Errorf("z.ImageRGBA(x1, y1) x1(%v) y1(%v) srcPath(%v)", x1, y1, srcPath)
        return errors.New("z.ImageRGBA eq nil")
    }

    // 將src圖片,縮小,放大,拉伸到dst圖片大小
    if err := graphics.Scale(dst, src); err != nil {
        log.Errorf("graphics.Scale(dst, src) x1(%v) y1(%v) srcPath(%v) err(%v)", x1, y1, srcPath, err)
        return err
    }

    if err := z.ImageEncodeJPEG(outPath, dst, 50); err != nil {
        log.Errorf("z.ImageEncodeJPEG(outPath, dst, 50) x1(%v) y1(%v) srcPath(%v) outPath(%v) err(%v)", x1, y1, srcPath, outPath, err)
        return err
    }

    return nil
}
截取圖片更改像素

 

package main

import (
    "fmt"
    "image"
    "image/draw"
    "image/jpeg"
    "image/png"
    "os"
)

func main() {
    file, err := os.Create("dst.jpg")
    if err != nil {
        fmt.Println(err)
    }
    defer file.Close()

    file1, err := os.Open("qr2tt.png")
    if err != nil {
        fmt.Println(err)
    }
    defer file1.Close()
    img, _ := png.Decode(file1)

    file2, err := os.Open("/Users/suoning/Documents/圖片/F1.jpeg")
    if err != nil {
        fmt.Println(err)
    }
    defer file2.Close()
    img2, _ := jpeg.Decode(file2)

    //jpg := image.NewRGBA(image.Rect(0, 0, 2976, 3968))
    jpg := image.NewRGBA(image.Rect(0, 0, 2976, 3968))

    draw.Draw(jpg, jpg.Bounds(), img2, img2.Bounds().Min, draw.Over)                   //首先將一個圖片信息存入jpg
    draw.Draw(jpg, jpg.Bounds(), img, img.Bounds().Min.Sub(image.Pt(800, 2300)), draw.Over)   //將另一張圖片信息存入jpg

    // draw.DrawMask(jpg, jpg.Bounds(), img, img.Bounds().Min, img2, img2.Bounds().Min, draw.Src) // 利用這種方法不可以將兩個圖片直接合成?目前尚不知道緣由。

    jpeg.Encode(file, jpg, nil)

}
兩張圖片合成

 

 

 

 

 

Cert

 

func GetCert(log *zap.SugaredLogger) (*tls.Certificate, error) {
    cert, err := tls.LoadX509KeyPair(CrtPemPath, KeyPemPath)
    if err != nil {
        log.Errorf("tls.LoadX509KeyPair() crt(%v) key(%v) err(%v)", CrtPemPath, KeyPemPath, err)
        return nil, err
    }
    return &cert, nil
}

 

pkcs12 轉 pem 
openssl pkcs12 -in path.p12 -out newfile.crt.pem -clcerts -nokeys -passin 'pass:password'
openssl pkcs12 -in path.p12 -out newfile.key.pem -nocerts -nodes  -passin 'pass:password'

  

證書請求

    client := &http.Client{
        Transport: &http.Transport{
            TLSClientConfig: &tls.Config{
                Certificates: []tls.Certificate{*cert},
            },
        },
    }
相關文章
相關標籤/搜索