package main

import (
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"log"
	"os"
	"unicode/utf8"
)

//Block块代表PEM编码的结构。
//
//编码形式为：
// ----- BEGIN类型-----
// Headers标头
// base64编码的字节
// ----- END类型-----
//Headers标头可以是键：值行的空序列。

func ExampleDecode() {
	var pubPEMData = []byte(`
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlRuRnThUjU8/prwYxbty
WPT9pURI3lbsKMiB6Fn/VHOKE13p4D8xgOCADpdRagdT6n4etr9atzDKUSvpMtR3
CP5noNc97WiNCggBjVWhs7szEe8ugyqF23XwpHQ6uV1LKH50m92MbOWfCtjU9p/x
qhNpQQ1AZhqNy5Gevap5k8XzRmjSldNAFZMY7Yv3Gi+nyCwGwpVtBUwhuLzgNFK/
yDtw2WcWmUU7NuC8Q6MWvPebxVtCfVp/iQU6q60yyt6aGOBkhAX0LpKAEhKidixY
nP9PNVBvxgu3XZ4P36gZV6+ummKdBVnc3NqwBLu5+CcdRdusmHPHd5pHf4/38Z3/
6qU2a/fPvWzceVTEgZ47QjFMTCTmCwNt29cvi7zZeQzjtwQgn4ipN9NibRH/Ax/q
TbIzHfrJ1xa2RteWSdFjwtxi9C20HUkjXSeI4YlzQMH0fPX6KCE7aVePTOnB69I/
a9/q96DiXZajwlpq3wFctrs1oXqBp5DVrCIj8hU2wNgB7LtQ1mCtsYz//heai0K9
PhE4X6hiE0YmeAZjR0uHl8M/5aW9xCoJ72+12kKpWAa0SFRWLy6FejNYCYpkupVJ
yecLk/4L1W0l6jQQZnWErXZYe0PNFcmwGXy1Rep83kfBRNKRy5tvocalLlwXLdUk
AIU+2GKjyT3iMuzZxxFxPFMCAwEAAQ==
-----END PUBLIC KEY-----
and some more`)

	//Decode将在输入中找到下一个PEM格式化的块（证书，私钥等）。 它返回该块和输入的其余部分。 如果未找到PEM数据，则p为nil，并且整个输入以“ rest”形式返回。
	block, rest := pem.Decode(pubPEMData)
	if block == nil || block.Type != "PUBLIC KEY" {
		log.Fatal("failed to decode PEM block containing public key")
	}
	// ParsePKIXPublicKey以AIX.1 DER形式的PKIX解析公共密钥。
	//
	//返回* rsa.PublicKey，* dsa.PublicKey，* ecdsa.PublicKey或ed25519.PublicKey。 将来可能会支持更多类型。
	//
	//这种密钥通常在“ PUBLIC KEY”类型的PEM块中编码。
	pub, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("解码后的数据对象是：",block)
	fmt.Println("解码后的字节数据是：",block.Bytes)
	fmt.Println("判断是否是utf8编码：",utf8.Valid(block.Bytes))
	fmt.Printf("Got a %T, with remaining data: %q", pub, rest)
	//输出：
	//解码后的数据对象是： &{PUBLIC KEY map[] [48 130 2 34 48 13 6 9 42 134 72 134 247 13 1 1 1 5 0 3 130 2 15 0 48 130 2 10 2 130 2
	//					1 0 149 27 145 157 56 84 141 79 63 166 188 24 197 187 114 88 244 253 165 68 72 222 86 236 40 200 129 232 89 255 84 115 138 19
	//					93 233 224 63 49 128 224 128 14 151 81 106 7 83 234 126 30 182 191 90 183 48 202 81 43 233 50 212 119 8 254 103 160 215 61 237
	//					104 141 10 8 1 141 85 161 179 187 51 17 239 46 131 42 133 219 117 240 164 116 58 185 93 75 40 126 116 155 221 140 108 229 159 10
	//					216 212 246 159 241 170 19 105 65 13 64 102 26 141 203 145 158 189 170 121 147 197 243 70 104 210 149 211 64 21 147 24 237 139
	//					247 26 47 167 200 44 6 194 149 109 5 76 33 184 188 224 52 82 191 200 59 112 217 103 22 153 69 59 54 224 188 67 163 22 188 247
	//					155 197 91 66 125 90 127 137 5 58 171 173 50 202 222 154 24 224 100 132 5 244 46 146 128 18 18 162 118 44 88 156 255 79 53 80 111
	//					198 11 183 93 158 15 223 168 25 87 175 174 154 98 157 5 89 220 220 218 176 4 187 185 248 39 29 69 219 172 152 115 199 119 154 71
	//					127 143 247 241 157 255 234 165 54 107 247 207 189 108 220 121 84 196 129 158 59 66 49 76 76 36 230 11 3 109 219 215 47 139 188 217
	//					121 12 227 183 4 32 159 136 169 55 211 98 109 17 255 3 31 234 77 178 51 29 250 201 215 22 182 70 215 150 73 209 99 194 220 98 244 45
	//					180 29 73 35 93 39 136 225 137 115 64 193 244 124 245 250 40 33 59 105 87 143 76 233 193 235 210 63 107 223 234 247 160 226 93 150
	//					163 194 90 106 223 1 92 182 187 53 161 122 129 167 144 213 172 34 35 242 21 54 192 216 1 236 187 80 214 96 173 177 140 255 254 23 154
	//					139 66 189 62 17 56 95 168 98 19 70 38 120 6 99 71 75 135 151 195 63 229 165 189 196 42 9 239 111 181 218 66 169 88 6 180 72 84 86 47
	//					46 133 122 51 88 9 138 100 186 149 73 201 231 11 147 254 11 213 109 37 234 52 16 102 117 132 173 118 88 123 67 205 21 201 176 25 124
	//					181 69 234 124 222 71 193 68 210 145 203 155 111 161 198 165 46 92 23 45 213 36 0 133 62 216 98 163 201 61 226 50 236 217 199 17 113 60 83 2 3 1 0 1]}
	//解码后的字节数据是： [48 130 2 34 48 13 6 9 42 134 72 134 247 13 1 1 1 5 0 3 130 2 15 0 48 130 2 10 2 130 2 1 0 149 27 145 157 56 84 141 79 63 166 188 24 197 187
	//					114 88 244 253 165 68 72 222 86 236 40 200 129 232 89 255 84 115 138 19 93 233 224 63 49 128 224 128 14 151 81 106 7 83 234 126 30 182 191 90 183 48 202 81
	//					43 233 50 212 119 8 254 103 160 215 61 237 104 141 10 8 1 141 85 161 179 187 51 17 239 46 131 42 133 219 117 240 164 116 58 185 93 75 40 126 116 155 221 140
	//					108 229 159 10 216 212 246 159 241 170 19 105 65 13 64 102 26 141 203 145 158 189 170 121 147 197 243 70 104 210 149 211 64 21 147 24 237 139 247 26 47 167 200
	//					44 6 194 149 109 5 76 33 184 188 224 52 82 191 200 59 112 217 103 22 153 69 59 54 224 188 67 163 22 188 247 155 197 91 66 125 90 127 137 5 58 171 173 50 202 222
	//					154 24 224 100 132 5 244 46 146 128 18 18 162 118 44 88 156 255 79 53 80 111 198 11 183 93 158 15 223 168 25 87 175 174 154 98 157 5 89 220 220 218 176 4 187 185
	//					248 39 29 69 219 172 152 115 199 119 154 71 127 143 247 241 157 255 234 165 54 107 247 207 189 108 220 121 84 196 129 158 59 66 49 76 76 36 230 11 3 109 219 215 47
	//					139 188 217 121 12 227 183 4 32 159 136 169 55 211 98 109 17 255 3 31 234 77 178 51 29 250 201 215 22 182 70 215 150 73 209 99 194 220 98 244 45 180 29 73 35 93 39
	//					136 225 137 115 64 193 244 124 245 250 40 33 59 105 87 143 76 233 193 235 210 63 107 223 234 247 160 226 93 150 163 194 90 106 223 1 92 182 187 53 161 122 129 167
	//					144 213 172 34 35 242 21 54 192 216 1 236 187 80 214 96 173 177 140 255 254 23 154 139 66 189 62 17 56 95 168 98 19 70 38 120 6 99 71 75 135 151 195 63 229 165 189
	//					196 42 9 239 111 181 218 66 169 88 6 180 72 84 86 47 46 133 122 51 88 9 138 100 186 149 73 201 231 11 147 254 11 213 109 37 234 52 16 102 117 132 173 118 88 123 67
	//					205 21 201 176 25 124 181 69 234 124 222 71 193 68 210 145 203 155 111 161 198 165 46 92 23 45 213 36 0 133 62 216 98 163 201 61 226 50 236 217 199 17 113 60 83 2 3 1 0 1]
	//判断是否是utf8编码： false
	//Got a *rsa.PublicKey, with remaining data: "and some more"
}

func ExampleEncode() {
	block := &pem.Block{
		Type: "MESSAGE",
		Headers: map[string]string{
			"Animal": "Gopher",
		},
		Bytes: []byte("test"),
	}

	if err := pem.Encode(os.Stdout, block); err != nil {
		log.Fatal(err)
	}
	//输出：
	//	-----BEGIN MESSAGE-----
	//	Animal: Gopher
	//
	//	dGVzdA==
	//	-----END MESSAGE-----
}

func main() {
	ExampleEncode()
	fmt.Println("--------------------------------")
	ExampleDecode()

	//这包具体原理和用法真的不知道，先搁置


}
