From cb2100c55a9fc3debf720b1983d47d2d50bd39fe Mon Sep 17 00:00:00 2001 From: dake Date: Sun, 1 Nov 2015 17:24:24 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E7=BF=BB=E8=AF=9112.11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eBook/12.10.md | 2 +- eBook/12.11.md | 134 +++++++++++++++++++++++++++++++++++++++++++++ eBook/directory.md | 1 + 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 eBook/12.11.md diff --git a/eBook/12.10.md b/eBook/12.10.md index 5d0bc48..8806ff2 100644 --- a/eBook/12.10.md +++ b/eBook/12.10.md @@ -78,4 +78,4 @@ XML 文本被循环处理直到 `Token()` 返回一个错误,因为已经到 - [目录](directory.md) - 上一节:[Json 数据格式](12.9.md) -- 下一节:[用 gob 传输数据](12.11.md) +- 下一节:[用 Gob 传输数据](12.11.md) diff --git a/eBook/12.11.md b/eBook/12.11.md new file mode 100644 index 0000000..38f5ecf --- /dev/null +++ b/eBook/12.11.md @@ -0,0 +1,134 @@ +# 用 Gob 传输数据 +Gob 是 Go 自己的以二进制形式序列化和反序列化程序数据的格式;可以在 `encoding` 包中找到。这种格式的数据简称为 Gob (即 Go binary 的缩写)。类似于 Python 的 "pickle" 和 Java 的 "Serialization"。 + +Gob 通常用于远程方法调用(RPCs,参见 15.9 的 rpc 包)参数和结果的传输,以及应用程序和机器之间的数据传输。 +它和 JSON 或 XML 有什么不同呢?Gob 被特定地用于纯 Go 的环境中,例如两个用 Go 写的服务之间的通信。这样的话服务可以被实现得更加高效和优化。Gob 不是可外部定义,语言无关的编码方式。因此它的首选格式是二进制,而不是像 JSON 和 XML 那样的文本格式。Gob 并不是一种跟 Go 不同的语言,而是在编码和解码过程中用到了 Go 的反射。 + +Gob 文件或流是完全自描述的:里面包含的所有类型都有一个对应的描述,并且总是可以用 Go 解码,而不需要了解文件的内容。 + +只有可导出的字段会被编码,零值会被忽略。在解码结构体的时候,只有同时匹配名称和可兼容类型的字段才会被解码。当源数据类型增加新字段后,Gob 解码客户端仍然可以以这种方式正常工作:解码客户端会继续识别以前存在的字段。并且还提供了很大的灵活性,比如在发送者看来,整数被编码成没有固定长度的可变长度,而忽略具体的 Go 类型。 + +假如在发送者这边有一个有结构 T: + +```go +type T struct { X, Y, Z int } +var t = T{X: 7, Y: 0, Z: 8} + +``` + +而在接收者这边可以用一个结构体 U 类型的变量 u 来接收这个值: + +```go +type U struct { X, Y *int8 } +var u U + +``` + +在接收者中,X 的值是7,Y 的值是0(Y的值并没有从 t 中传送过来,因为它是零值) + + +和 JSON 的使用方式一样,Gob 使用通用的 `io.Writer` 接口,通过 `NewEncoder()` 函数创建 `Encoder` 对象并调用 `Encode()`;相反的过程使用通用的 `io.Reader` 接口,通过 `NewDecoder()` 函数创建 `Decoder` 对象并调用 `Decode`。我们把示例 12.12 的信息写进名为 vcard.gob 的文件作为例子。这会产生一个文本可读数据和二进制数据的混合,当你试着在文本编辑中打开的时候会看到。 + +在示例 12.18 中你会看到一个编解码,并且以字节缓冲模拟网络传输的简单例子: + +示例 12.18 [gob1.go](examples/chapter_12/gob1.go): + +```go +// gob1.go +package main + +import ( + "bytes" + "fmt" + "encoding/gob" + "log" +) + +type P struct { + X, Y, Z int + Name string +} + +type Q struct { + X, Y *int32 + Name string +} + +func main() { + // Initialize the encoder and decoder. Normally enc and dec would be + // bound to network connections and the encoder and decoder would + // run in different processes. + var network bytes.Buffer // Stand-in for a network connection + enc := gob.NewEncoder(&network) // Will write to network. + dec := gob.NewDecoder(&network) // Will read from network. + // Encode (send) the value. + err := enc.Encode(P{3, 4, 5, "Pythagoras"}) + if err != nil { + log.Fatal("encode error:", err) + } + // Decode (receive) the value. + var q Q + err = dec.Decode(&q) + if err != nil { + log.Fatal("decode error:", err) + } + fmt.Printf("%q: {%d,%d}\n", q.Name, *q.X, *q.Y) +} +// Output: "Pythagoras": {3,4} + +``` + +示例 12.19[gob2.go](examples/chapter_12/gob2.go) 编码到文件: + +```go +// gob2.go +package main + +import ( + "encoding/gob" + "log" + "os" +) + +type Address struct { + Type string + City string + Country string +} + +type VCard struct { + FirstName string + LastName string + Addresses []*Address + Remark string +} + +var content string + +func main() { + pa := &Address{"private", "Aartselaar","Belgium"} + wa := &Address{"work", "Boom", "Belgium"} + vc := VCard{"Jan", "Kersschot", []*Address{pa,wa}, "none"} + // fmt.Printf("%v: \n", vc) // {Jan Kersschot [0x126d2b80 0x126d2be0] none}: + // using an encoder: + file, _ := os.OpenFile("vcard.gob", os.O_CREATE|os.O_WRONLY, 0) + defer file.Close() + enc := gob.NewEncoder(file) + err := enc.Encode(vc) + if err != nil { + log.Println("Error in encoding gob") + } +} + +``` + +**练习 12.8**:[degob.go](exercises/chapter_12/degob.go): + +写一个程序读取 vcard.gob 文件,编码并打印它的内容。 + + +## 链接 + +- [目录](directory.md) +- 上一节:[XML 数据格式](12.10.md) +- 下一节:[Go 中的密码学](12.12.md) \ No newline at end of file diff --git a/eBook/directory.md b/eBook/directory.md index 1b9477b..ee8465e 100644 --- a/eBook/directory.md +++ b/eBook/directory.md @@ -119,6 +119,7 @@ - 12.8 [一个使用接口的实际例子:fmt.Fprintf](12.8.md) - 12.9 [格式化 Json 数据](12.9.md) - 12.10 [XML 数据格式](12.10.md) + - 12.11 [用 Gob 传输数据](12.11.md) - 第13章:错误处理与测试 - 第14章:goroutine 与 channel - 第15章:网络、模版与网页应用 From b29b825ad8f29eb46e2445f3e97d6d04c6f079f7 Mon Sep 17 00:00:00 2001 From: dake Date: Sun, 1 Nov 2015 17:36:18 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=A0=A1=E5=AF=B912.11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eBook/12.11.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/eBook/12.11.md b/eBook/12.11.md index 38f5ecf..72d3602 100644 --- a/eBook/12.11.md +++ b/eBook/12.11.md @@ -2,7 +2,7 @@ Gob 是 Go 自己的以二进制形式序列化和反序列化程序数据的格式;可以在 `encoding` 包中找到。这种格式的数据简称为 Gob (即 Go binary 的缩写)。类似于 Python 的 "pickle" 和 Java 的 "Serialization"。 Gob 通常用于远程方法调用(RPCs,参见 15.9 的 rpc 包)参数和结果的传输,以及应用程序和机器之间的数据传输。 -它和 JSON 或 XML 有什么不同呢?Gob 被特定地用于纯 Go 的环境中,例如两个用 Go 写的服务之间的通信。这样的话服务可以被实现得更加高效和优化。Gob 不是可外部定义,语言无关的编码方式。因此它的首选格式是二进制,而不是像 JSON 和 XML 那样的文本格式。Gob 并不是一种跟 Go 不同的语言,而是在编码和解码过程中用到了 Go 的反射。 +它和 JSON 或 XML 有什么不同呢?Gob 特定地用于纯 Go 的环境中,例如,两个用 Go 写的服务之间的通信。这样的话服务可以被实现得更加高效和优化。Gob 不是可外部定义,语言无关的编码方式。因此它的首选格式是二进制,而不是像 JSON 和 XML 那样的文本格式。Gob 并不是一种不同于 Go 的语言,而是在编码和解码过程中用到了 Go 的反射。 Gob 文件或流是完全自描述的:里面包含的所有类型都有一个对应的描述,并且总是可以用 Go 解码,而不需要了解文件的内容。 @@ -24,10 +24,13 @@ var u U ``` -在接收者中,X 的值是7,Y 的值是0(Y的值并没有从 t 中传送过来,因为它是零值) +在接收者中,X 的值是7,Y 的值是0(Y的值并没有从 t 中传递过来,因为它是零值) -和 JSON 的使用方式一样,Gob 使用通用的 `io.Writer` 接口,通过 `NewEncoder()` 函数创建 `Encoder` 对象并调用 `Encode()`;相反的过程使用通用的 `io.Reader` 接口,通过 `NewDecoder()` 函数创建 `Decoder` 对象并调用 `Decode`。我们把示例 12.12 的信息写进名为 vcard.gob 的文件作为例子。这会产生一个文本可读数据和二进制数据的混合,当你试着在文本编辑中打开的时候会看到。 +和 JSON 的使用方式一样,Gob 使用通用的 `io.Writer` 接口,通过 `NewEncoder()` 函数创建 `Encoder` 对象并调用 `Encode()`;相反的过程使用通用的 `io.Reader` 接口,通过 `NewDecoder()` 函数创建 `Decoder` 对象并调用 `Decode`。 + + +我们把示例 12.12 的信息写进名为 vcard.gob 的文件作为例子。这会产生一个文本可读数据和二进制数据的混合,当你试着在文本编辑中打开的时候会看到。 在示例 12.18 中你会看到一个编解码,并且以字节缓冲模拟网络传输的简单例子: @@ -78,7 +81,7 @@ func main() { ``` -示例 12.19[gob2.go](examples/chapter_12/gob2.go) 编码到文件: +示例 12.19 [gob2.go](examples/chapter_12/gob2.go) 编码到文件: ```go // gob2.go @@ -124,7 +127,7 @@ func main() { **练习 12.8**:[degob.go](exercises/chapter_12/degob.go): -写一个程序读取 vcard.gob 文件,编码并打印它的内容。 +写一个程序读取 vcard.gob 文件,解码并打印它的内容。 ## 链接 From af7a9355ac916188e804f60ff84d5f665fb10283 Mon Sep 17 00:00:00 2001 From: dake Date: Sun, 1 Nov 2015 18:29:31 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E7=BF=BB=E8=AF=9112.12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eBook/12.11.md | 5 ++- eBook/12.12.md | 86 ++++++++++++++++++++++++++++++++++++++++++++++ eBook/directory.md | 3 +- 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 eBook/12.12.md diff --git a/eBook/12.11.md b/eBook/12.11.md index 72d3602..064d02a 100644 --- a/eBook/12.11.md +++ b/eBook/12.11.md @@ -1,8 +1,11 @@ # 用 Gob 传输数据 + Gob 是 Go 自己的以二进制形式序列化和反序列化程序数据的格式;可以在 `encoding` 包中找到。这种格式的数据简称为 Gob (即 Go binary 的缩写)。类似于 Python 的 "pickle" 和 Java 的 "Serialization"。 Gob 通常用于远程方法调用(RPCs,参见 15.9 的 rpc 包)参数和结果的传输,以及应用程序和机器之间的数据传输。 -它和 JSON 或 XML 有什么不同呢?Gob 特定地用于纯 Go 的环境中,例如,两个用 Go 写的服务之间的通信。这样的话服务可以被实现得更加高效和优化。Gob 不是可外部定义,语言无关的编码方式。因此它的首选格式是二进制,而不是像 JSON 和 XML 那样的文本格式。Gob 并不是一种不同于 Go 的语言,而是在编码和解码过程中用到了 Go 的反射。 +它和 JSON 或 XML 有什么不同呢?Gob 特定地用于纯 Go 的环境中,例如,两个用 Go 写的服务之间的通信。这样的话服务可以被实现得更加高效和优化。 +Gob 不是可外部定义,语言无关的编码方式。因此它的首选格式是二进制,而不是像 JSON 和 XML 那样的文本格式。 +Gob 并不是一种不同于 Go 的语言,而是在编码和解码过程中用到了 Go 的反射。 Gob 文件或流是完全自描述的:里面包含的所有类型都有一个对应的描述,并且总是可以用 Go 解码,而不需要了解文件的内容。 diff --git a/eBook/12.12.md b/eBook/12.12.md new file mode 100644 index 0000000..feb7af2 --- /dev/null +++ b/eBook/12.12.md @@ -0,0 +1,86 @@ +# Go 中的密码学 + +通过网络传输的数据必须加密,以防止被 hacker(黑客)读取或篡改,并且保证发出的数据和收到的数据检验和一致。 +鉴于 Go 母公司的业务,我们毫不惊讶地看到 Go 的标准库为该领域提供了超过 30 个的包: + +- `hash` 包:实现了 `adler32`、`crc32`、`crc64` 和 `fnv` 校验; +- `crypto` 包:实现了其它的 hash 算法,比如 `md4`、`md5`、`sha1` 等。以及完整地实现了 `aes`、`blowfish`、`rc4`、`rsa`、`xtea` 等加密算法。 + +下面的示例用 `sha1` 和 `md5` 计算并输出了一些校验值。 + +示例 12.20 [hash_sha1.go](examples/chapter_12/hash_sha1.go): + +```go +// hash_sha1.go +package main + +import ( + "fmt" + "crypto/sha1" + "io" + "log" +) + +func main() { + hasher := sha1.New() + io.WriteString(hasher, "test") + b := []byte{} + fmt.Printf("Result: %x\n", hasher.Sum(b)) + fmt.Printf("Result: %d\n", hasher.Sum(b)) + // + hasher.Reset() + data := []byte("We shall overcome!") + n, err := hasher.Write(data) + if n!=len(data) || err!=nil { + log.Printf("Hash write error: %v / %v", n, err) + } + checksum := hasher.Sum(b) + fmt.Printf("Result: %x\n", checksum) +} +/* Output: +Result: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 +Result: [169 74 143 229 204 177 155 166 28 76 8 115 211 145 233 135 152 47 187 211] +Result: e2222bfc59850bbb00a722e764a555603bb59b2a +*/ + +``` + +通过调用 `sha1.New()` 创建了一个新的 `hash.Hash` 对象,用来计算 SHA1 校验值。`Hash` 类型实际上是一个接口,它实现了 `io.Writer` 接口: + +```go +type Hash interface { + // Write (via the embedded io.Writer interface) adds more data to the running hash. + // It never returns an error. + io.Writer + + // Sum appends the current hash to b and returns the resulting slice. + // It does not change the underlying hash state. + Sum(b []byte) []byte + + // Reset resets the Hash to its initial state. + Reset() + + // Size returns the number of bytes Sum will return. + Size() int + + // BlockSize returns the hash's underlying block size. + // The Write method must be able to accept any amount + // of data, but it may operate more efficiently if all writes + // are a multiple of the block size. + BlockSize() int +} + +``` + +通过 io.WriteString 或 hasher.Write 计算给定字符串的校验值。 + +**练习 12.9**:[hash_md5.go](exercises/chapter_12/hash_md5.go): + +在示例 12.20 中检验 md5 算法。 + + +## 链接 + +- [目录](directory.md) +- 上一节:[用 Gob 传输数据](12.11.md) +- 下一章:[错误处理与测试](13.0.md) diff --git a/eBook/directory.md b/eBook/directory.md index ee8465e..504a83d 100644 --- a/eBook/directory.md +++ b/eBook/directory.md @@ -120,7 +120,8 @@ - 12.9 [格式化 Json 数据](12.9.md) - 12.10 [XML 数据格式](12.10.md) - 12.11 [用 Gob 传输数据](12.11.md) -- 第13章:错误处理与测试 + - 12.12 [Go 中的密码学](12.12.md) +- 第13章:[错误处理与测试](13.0.md) - 第14章:goroutine 与 channel - 第15章:网络、模版与网页应用