golang中的md5的用法

代码

package main

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
)

func main() {
	// md5 加密的第一种方法
	srcData := []byte("iyannik0215")
	cipherText1 := md5.Sum(srcData)
	fmt.Printf("md5 encrypto is \"iyannik0215\": %x \n", cipherText1)

	// md5 加密的第二种方法
	hash := md5.New()
	hash.Write(srcData)
	cipherText2 := hash.Sum(nil)
	hexText := make([]byte, 32)
	hex.Encode(hexText, cipherText2)
	fmt.Println("md5 encrypto is \"iyannik0215\":", string(hexText))
}
# 执行结果
md5 encrypto is "iyannik0215": b6b20c73e6bc53bc691a6bb559cf9ca9
md5 encrypto is "iyannik0215": b6b20c73e6bc53bc691a6bb559cf9ca9

不同

解释一下两种加密方式的不一样之处.
第一种加密方法:
第一种加密方法所调用的函数

//Source file src/crypto/md5/md5.go
19	// The size of an MD5 checksum in bytes.
20	const Size = 16

130	// Sum returns the MD5 checksum of the data.
131	func Sum(data []byte) [Size]byte {
132		var d digest
133		d.Reset()
134		d.Write(data)
135		return d.checkSum()
136	}

func Sum(data []byte) [Size]byte
其 [Size]byte 是固定死的.所以说第一种方法返回的是 16长度的数组(无法转string类型,需使用第二种加密方法)
第二种加密方法:

//Source file src/crypto/md5/md5.go
50	// New returns a new hash.Hash computing the MD5 checksum.
51	func New() hash.Hash {
52		d := new(digest)
53		d.Reset()
54		return d
55	}
// 这里只放了函数签名部分, 关于函数具体内容这里就不详细复制了.
51	func New() hash.Hash {}
61	func (d *digest) Write(p []byte) (nn int, err error) {}
90	func (d0 *digest) Sum(in []byte) []byte {}

这里使用 func New() hash.Hash {} 函数进行生成对象.
使用 func (d *digest) Write(p []byte) (nn int, err error) {} 方法进行写入要加密的数据.
使用 func (d0 *digest) Sum(in []byte) []byte {} 方法进行数据的加密 看其返回值.
[]byte 可见使用第二种方式加密返回的是 []byte 类型的切片.

转:http://openskill.cn/article/206?utm_source=tuicool&utm_medium=referral

golang中chan实例

package main

import "fmt"

func main() {
 data := make(chan int) // 数据交换队列
 exit := make(chan bool) // 退出通知

go func() {
 for d := range data { // 从队列迭代接收数据,直到 close 。
   fmt.Println(d)
 }

 fmt.Println("recv over.")
 exit <- true // 发出退出通知。
}()

data <- 1 // 发送数据。
data <- 2
data <- 3

close(data) // 关闭队列。

fmt.Println("send over.")

<-exit // 等待退出通知。
}

输出结果:

1
2
3
send over.
recv over.

而如果将上面与 exit chan有关的三行删除掉,则结果为:

1
2
3
send over.

缺少了“recv over."一行,为什么?

大家可以  time.Sleep(time.Second * 2) 来自己分析一下

golang中chan的理解与使用教程

对于 chan 介绍见:https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/02.7.md

这里我们主要通过实例来介绍对chan的理解及用法.

无Buffer的Channels

实例1:

func main() {
ci := make(chan int)

ci < - 4

value := <-ci
fmt.Println(value)
}

执行结果错误为:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:

从上面“fatal error: all goroutines are asleep - deadlock!” 这句我们可以看出是groutings 阻塞了,这里为写阻塞,从“goroutine 1 [chan send]”可以看出来。 Continue reading

golang中flag包的用法

golang中flag包主要用来CLI下,获取命令参数,示例如下mysql.go:

package main

import (
"flag"
"fmt"
)

func main() {
host := flag.String("h", "localhost", "请指定一个主机")
user := flag.String("u", "root", "请指定数据库用户")
port := flag.Int("P", 3306, "Port number to use for commection or 0 for default to, in port 3306")

//var name string
//flag.StringVar(&name, "u", "root", "请指定用户名") 

flag.Parse() //参数解析

fmt.Println("主机地址:", *host)
fmt.Println("用户名:", *user)
fmt.Println("端口:", *port)
}

像flag.Int、flag.Bool、flag.String这样的函数格式都是一样的,第一个参数表示参数名称,第二个参数表示默认值,第三个参数表示使用说明和描述。flag.StringVar这样的函数第一个参数换成了变量地址,后面的参数和flag.String是一样的。

使用flag来操作命令行参数,支持的格式如下:

-id=1 go run mysql.go -h="127.0.0.1" -u="sxf" -P=3307 
--id=1: go run mysql.go --h="127.0.0.1" --u="sxf" --P=3307 
-id 1:  go run mysql.go -h "127.0.0.1" -u "sxf" 
--id 1:  go run mysql.go --h "127.0.0.1" --u "sxf" --P 3307

还是非常方便的。

这里不指定参数的情况,会使用默认值:

go run mysql.go

 

Golang语言的GOPATH与工作目录详解

这篇文章主要介绍了Go语言的GOPATH与工作目录详解,本文详细讲解了GOPATH设置、应用目录结构、编译应用等内容,需要的朋友可以参考下

GOPATH设置

go 命令依赖一个重要的环境变量:$GOPATH

(注:这个不是Go安装目录(GOROOT)。下面以笔者的工作目录为说明,请替换自己机器上的工作目录。)

在类似 Unix 环境大概这样设置:

export GOPATH=/home/apple/mygo

为了方便,应该把新建以上文件夹,并且把以上一行加入到 .bashrc 或者 .zshrc 或者自己的 sh 的配置文件中。

Windows 设置如下,新建一个环境变量名称叫做GOPATH:

GOPATH=c:\mygo

GOPATH允许多个目录,当有多个目录时,请注意分隔符,多个目录的时候Windows是分号,Linux系统是冒号,当有多个GOPATH时,默认会将go get的内容放在第一个目录下

以上 $GOPATH 目录约定有三个子目录:

1.src 存放源代码(比如:.go .c .h .s等)
2.pkg 编译后生成的文件(比如:.a)
3.bin 编译后生成的可执行文件(为了方便,可以把此目录加入到 $PATH 变量中,如果有多个gopath,那么使用${GOPATH//://bin:}/bin添加所有的bin目录)

以后我所有的例子都是以mygo作为我的gopath目录
Continue reading

golang中for循环方法的差异

用for循环遍历字符串时,也有 byte 和 rune 两种方式.第一种试为byte,第二种rune。

golang中string rune byte 三者的关系https://blog.haohtml.com/archives/17646

package main
import (
	"fmt"
)

func main() {
	s := "abc汉字"
 
	for i := 0; i < len(s); i++ {
	fmt.Printf("%c,", s[i])
	}
	 
	fmt.Println()
	 
	for _, r := range s {
		fmt.Printf("%c\n", r)
	}

}

输出结果:

a,b,c,d,e,f,d,ä,¸,­,
a,b,c,æ,±,‰,å,­,—,
a
b
c
汉
字