-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
322 lines (167 loc) · 318 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>比特币地址的生成算法</title>
<link href="/posts/52fae707.html"/>
<url>/posts/52fae707.html</url>
<content type="html"><![CDATA[<blockquote><p> Go加密算法_⽐比特币地址的生成算法</p></blockquote><h4 id="⼀、⽐特币地址的⽣成步骤"><a href="#⼀、⽐特币地址的⽣成步骤" class="headerlink" title="⼀、⽐特币地址的⽣成步骤"></a>⼀、⽐特币地址的⽣成步骤</h4><h5 id="⼀-、概述"><a href="#⼀-、概述" class="headerlink" title="(⼀)、概述"></a>(⼀)、概述</h5><p>1、⽐特币是建⽴在数学加密学基础上的,中本聪⽤了椭圆曲线数字签名算法(ECDSA)来产⽣⽐特币的私钥和公钥。</p><p>ECDSA算法(Elliptic Curve Digital Signature Algorithm , 椭圆曲线数字 签名算法),是使⽤椭圆曲线加密学(ECC ,Elliptic Curve Cryptography )对数字签名算法(DSA , Digital Signature Algorithm)的模拟。 ECDSA 在1998年就被ISO所接受,于1999年成为ANSI标准,并于2000年成为IEEE 和NIST标准。</p><p>具体来说,⽐特币系统中的椭圆曲线是Certicom推荐的SECP256K1算法。</p><p>Certicom是国际上著名的椭圆曲线密码技术公司。⽽SECP256K1算法由于其构造的特殊性,优化后性能⽐其它曲线算法提⾼30%。</p><p>2、由私钥可以计算出公钥,公钥经过⼀系列数字签名运算会得到⽐特币地址。</p><p>3、因为由公钥可以算出⽐特币地址,所以有⼈经常把公钥和⽐特币地址相混 淆。不过可以把⽐特币地址理解成是另⼀种格式的公钥,所以有时候将⽐特币地 址⼜叫做公钥哈希。</p><p>4、从⽐特币私钥得到⽐特币地址需要10个步骤。中间依次会⽤到SECP256K1、SHA256、RIPEMD160以及BASE58编码。我们平时使⽤的⽐特币地址都是经过BASE58编码之后的结果。⼀般以“1”、“3”开头的34位字符串。(在⽐特币testnet⽹络中⽐特币地址以2开头)<img src="https://wx3.sinaimg.cn/large/e64a4785gy1fxq21c8k3rj20fu09fac0.jpg" alt=""></p><h5 id="(⼆)、Base58Check"><a href="#(⼆)、Base58Check" class="headerlink" title="(⼆)、Base58Check"></a>(⼆)、Base58Check</h5><p>1、Base58Check是⼀种常⽤在⽐特币中的Base58编码格式,增加了错误校验码 来检查数据在转录中出现的错误。</p><p> 2、在⽣成⽐特币地址以及⽣成WIF-compressed格式私钥的过程中都⽤到了 Base58Check。</p><p> 3、在Base58Check中,对数据添加了⼀个称作“版本字节”的前缀,这个前缀⽤ 来明确需要编码的数据的类型。 4、Base58Check的作⽤</p><p> 既然有了Base58编码,已经不会搞错0和O, 1和l和I,也把⼤整数转换成了 可读字符串,为什么还要再有Base58Check这个环节呢?</p><p> 假设⼀种情况,你在程序中输⼊⼀个Base58编码的地址,尽管你已经不 会搞错0和O, 1和l和I,但是万⼀你不⼩⼼输错⼀个字符,或者少写多写⼀个 字符,会咋样?你可能会说,没啥⼤不了的,错个字符⽽已,这不是很常⻅见 嘛,重新输⼊不就可以了吗?但是当⽤户给⼀个⽐特币地址转账,如果输⼊ 错误,那么对⽅就不会收到资⾦,更关键的是该笔资⾦发给了⼀个根本不存 在的⽐特币地址,那么这笔资⾦也就永远不可能被交易,也就是说⽐特币丢 失了。</p><p> 使⽤Base58check编码格式时,程序会计算原始数据的校验码并和⾃带的校验码进⾏对⽐,⼆者若不匹配则表明有错误产⽣。</p><p> 实际上,在⽐特币交易中,都会校验⽐特币地址是否合法,如果经过 Base58Check的⽐特币地址被⽐特币钱包程序判定是⽆效的,当然会阻⽌ 交易继续进⾏,就避免了资⾦损失。</p><h5 id="(三)、⽐特币地址⽣成步骤"><a href="#(三)、⽐特币地址⽣成步骤" class="headerlink" title="(三)、⽐特币地址⽣成步骤"></a>(三)、⽐特币地址⽣成步骤</h5><p>1、第⼀步,随机选取⼀个32字节的数、⼤⼩介于1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141之间,作为私钥。私钥为64位16进制数字。</p><p>A376D3867EA8F2DDB6D80B0A7BD1C57FE51B659D7B0EE264949D02983624344C</p><p>2、第⼆步,使⽤椭圆曲线加密算法(ECDSA-secp256k1)计算私钥所对应的⾮压缩公钥。</p><p>⾮压缩公钥共65字节, 第1个字节是 0x04, 32字节为x坐标,32字节为y 坐标,⼀共是130位16进制数字。</p><p>压缩公钥共33字节,第1个字节是0x02或0x03, 再加x坐标的32字节,⼀ 共是66位16进制数字。</p><p>04</p><p>1BF6C2F0F5DD3F86907F2A942B97C38AB797EB7E73BA80C88371B77EA5C2E040 8AE994868BD2141FEE0695905090BD5FE8B939FEEF6A0BAE0D11D2412DB78B2B</p><p>3、第三步,计算公钥的 SHA-256 哈希值</p><p>F24B7CF9A2378C2F9C1BEB5B4B4C8A3CA16E9F6C076680CAD4BBCBD783B30D89</p><p>4、第四步,取上⼀步结果,计算 RIPEMD-160 哈希值</p><p>9353BD455CDBCAEC7BDBA6AE7224CBF3D9B6D50C</p><p>5、第五步,取上⼀步结果,前⾯加⼊⽹络ID号</p><p>⽐特币主⽹id号:0x00 </p><p>testnet测试⽹络id号:0x6f 009353BD455CDBCAEC7BDBA6AE7224CBF3D9B6D50C</p><p>6、第六步,取上⼀步结果,计算 SHA-256 哈希值</p><p>907202A7758189FFA8BD65C2FE0C4DEA768BBE6766E7758B893DD3E97A AAE613</p><p>7、第七步,取上⼀步结果,再计算⼀下 SHA-256 哈希值</p><p>D0295602554B9234DDCBB016F9D6D4E480155482434DEBD297972987A 9E7BA22</p><p>8、第⼋步,取上⼀步结果的前4个字节(8位⼗六进制)作为校验码</p><p>D0295602</p><p>9、第九步,将校验码加在第五步的结果后⾯,这就形成了⽐特币地址的16进制格式。(50位16进制数字)</p><p>009353BD455CDBCAEC7BDBA6AE7224CBF3D9B6D50CD0295602</p><p>10、第⼗步,⽤Base58编码(这是最常使⽤的⽐特币地址格式,34字节⻓度)。</p><p>1ERzeWbxZsZYu7JzR4H2JYx4gNK6Y7Aibb</p><p>我们经常说的⽐特币公钥就是指的图中第⼆步所产⽣的结果。⽽HASH160指的是第四步RIPEMD160签名所产⽣的结果,由于RIPEMD也是⼀种HASH算法所以就统称为HASH160。</p><p><code>⽣成⽐特币地址的步骤详⻅见⽹站</code></p><p>[<a href="http://gobittest.appspot.com/Address]" rel="external nofollow noopener noreferrer" target="_blank">http://gobittest.appspot.com/Address]</a>:</p><p><img src="https://wx3.sinaimg.cn/large/e64a4785gy1fxq2bodbsmj20ow0bzn0w.jpg" alt=""></p><h4 id="⼆、⽣成WIF或WIF-compressed格式私钥的步骤"><a href="#⼆、⽣成WIF或WIF-compressed格式私钥的步骤" class="headerlink" title="⼆、⽣成WIF或WIF-compressed格式私钥的步骤"></a>⼆、⽣成WIF或WIF-compressed格式私钥的步骤</h4><p>1、第⼀步,随机选取⼀个32字节的数作为私钥。私钥为64位16进制数字。</p><p>例如:</p><p>18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725</p><p>2、第⼆步,取上⼀步结果,前⾯加⼊版本号(版本号“0x80”),末尾添加压缩标识符(“0x01”)</p><p>根据是否添加压缩标识符,将私钥根式分为WIF和WIF-compressed格式,最终经过Base58编码后分别为51位长度和52位长度。</p><p>WIF格式以“5”开头,WIF-compressed格式以“L”或“K”开头。</p><p>8018E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A20632172501</p><p>3、第三步,取上⼀步结果,计算两次SHA-256后的哈希值</p><p>281938ff642c734eb0ffcc8a394c5490dcc5d67b79257832eb8011857018eeef</p><p>4、第四步,取上⼀步结果的前4个字节(8位⼗六进制)作为校验码</p><p>281938ff</p><p>5、第五步,把校验码加在第⼆步的结果后⾯,形成增加校验码之后的16进制格式</p><p>8018E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206 32172501281938ff</p><p>6、第六步,⽤base58表示法变换⼀下私钥(这就是最常⻅见的私钥的形态)。</p><p>Kx45GeUBSMPReYQwgXiKhG9FzNXrnCeutJp4yjTd5kKxCitadm3C</p><p><code>⽣成私钥的步骤详⻅见⽹站</code> —— </p><p>[<a href="http://gobittest.appspot.com/PrivateKey]" rel="external nofollow noopener noreferrer" target="_blank">http://gobittest.appspot.com/PrivateKey]</a>:</p><p><img src="https://ws4.sinaimg.cn/large/e64a4785gy1fxq2h3karnj20r60oanb1.jpg" alt=""></p><h4 id="三、⽐特币地址⽣成"><a href="#三、⽐特币地址⽣成" class="headerlink" title="三、⽐特币地址⽣成"></a>三、⽐特币地址⽣成</h4><pre class=" language-go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">GenerateAddress</span><span class="token punctuation">(</span>pubkey <span class="token builtin">string</span><span class="token punctuation">,</span> nettype <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">//1、判断公钥有效性</span><span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>pubkey<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">130</span> <span class="token operator">&&</span> <span class="token function">len</span><span class="token punctuation">(</span>pubkey<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">66</span> <span class="token punctuation">{</span> err <span class="token operator">:=</span> errors<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token string">"公钥输⼊入错误!"</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">""</span><span class="token punctuation">,</span> err <span class="token punctuation">}</span><span class="token comment" spellcheck="true">//2、计算公钥sha256</span>hashString <span class="token operator">:=</span> cryptotool<span class="token punctuation">.</span><span class="token function">HASH</span><span class="token punctuation">(</span>pubkey<span class="token punctuation">,</span> <span class="token string">"sha256"</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//fmt.Println("sha256:", hashString)</span><span class="token comment" spellcheck="true">// 3、RipeMD160</span>ripemd160String <span class="token operator">:=</span> cryptotool<span class="token punctuation">.</span><span class="token function">HASH</span><span class="token punctuation">(</span>hashString<span class="token punctuation">,</span> <span class="token string">"ripemd160"</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//ripemd160String = fmt.Sprintf("%s", ripemd160String) </span><span class="token comment" spellcheck="true">//fmt.Println("ripemd160:", ripemd160String)</span><span class="token comment" spellcheck="true">// 4、增加⽹网络id号 ● ⽐比特币主⽹网id号:0x00 ● testnet测试⽹网络id号:0x6f </span>prefix <span class="token operator">:=</span> <span class="token string">""</span><span class="token keyword">switch</span> nettype <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token number">0</span><span class="token punctuation">:</span> prefix <span class="token operator">=</span> <span class="token string">"00"</span> <span class="token keyword">case</span> <span class="token number">1</span><span class="token punctuation">:</span> prefix <span class="token operator">=</span> <span class="token string">"6f"</span> <span class="token keyword">case</span> <span class="token number">2</span><span class="token punctuation">:</span> prefix <span class="token operator">=</span> <span class="token string">"34"</span> <span class="token punctuation">}</span>versionString <span class="token operator">:=</span> prefix <span class="token operator">+</span> ripemd160String<span class="token comment" spellcheck="true">//fmt.Println("加前缀:", versionString)</span><span class="token comment" spellcheck="true">// 5、计算两次hash</span>sha256DoubleString <span class="token operator">:=</span> cryptotool<span class="token punctuation">.</span><span class="token function">SHA256Double</span><span class="token punctuation">(</span>versionString<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//fmt.Println(sha256DoubleString)</span><span class="token comment" spellcheck="true">// 6、获取校验码</span>rs <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token function">rune</span><span class="token punctuation">(</span>sha256DoubleString<span class="token punctuation">)</span> checknum <span class="token operator">:=</span> <span class="token function">string</span><span class="token punctuation">(</span>rs<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//fmt.Println(checknum)</span><span class="token comment" spellcheck="true">// 7、形成16进制⽐比特币地址</span>addrHex <span class="token operator">:=</span> versionString <span class="token operator">+</span> checknum <span class="token comment" spellcheck="true">//fmt.Println(addrHex)</span><span class="token comment" spellcheck="true">// 8、对16进制地址进⾏行行Base58编码</span>arr<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> hex<span class="token punctuation">.</span><span class="token function">DecodeString</span><span class="token punctuation">(</span>addrHex<span class="token punctuation">)</span> addrBase58 <span class="token operator">:=</span> cryptotool<span class="token punctuation">.</span><span class="token function">Base58Encode</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span> result <span class="token operator">:=</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">"%s \n"</span><span class="token punctuation">,</span> addrBase58<span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//fmt.Println(result)</span><span class="token keyword">return</span> result<span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">}</span></code></pre><h4 id="四、默克尔根⽣生成"><a href="#四、默克尔根⽣生成" class="headerlink" title="四、默克尔根⽣生成"></a>四、默克尔根⽣生成</h4><blockquote><p> 以0为例:只有唯⼀⼀笔coinbase交易。那么coinbase交易的hash就是默克尔根的hash值</p><p> txhash_0 :=</p><p> “4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b”</p><p> res := “4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b”</p></blockquote><pre class=" language-go"><code class="language-go"><span class="token keyword">func</span> <span class="token function">GetMerkleRoot</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">//以98901为例例:有两笔交易易。coinbase交易易及真实交易易 </span>txhash_01 <span class="token operator">:=</span><span class="token string">"16f0eb42cb4d9c2374b2cb1de4008162c06fdd8f1c18357f0c849eb423672f5f"</span>txhash_02 <span class="token operator">:=</span><span class="token string">"cce2f95fc282b3f2bc956f61d6924f73d658a1fdbc71027dd40b06c15822e061"</span><span class="token comment" spellcheck="true">//cryptotool.HASH()</span><span class="token comment" spellcheck="true">//将两笔交易易进⾏行行⼩小端排序</span>fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"交易易1:"</span> <span class="token punctuation">,</span> cryptotool<span class="token punctuation">.</span><span class="token function">ReverseHexString</span><span class="token punctuation">(</span>txhash_01<span class="token punctuation">)</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"交易易2:"</span> <span class="token punctuation">,</span> cryptotool<span class="token punctuation">.</span><span class="token function">ReverseHexString</span><span class="token punctuation">(</span>txhash_02<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//5f2f6723b49e840c7f35181c8fdd6fc0628100e41dcbb274239c4dcb42ebf016 </span><span class="token comment" spellcheck="true">//61e02258c1060bd47d0271bcfda158d6734f92d6616f95bcf2b382c25ff9e2cc</span><span class="token comment" spellcheck="true">//将交易易拼接在⼀一起</span>a <span class="token operator">:=</span><span class="token string">"5f2f6723b49e840c7f35181c8fdd6fc0628100e41dcbb274239c4dcb42ebf0166"</span><span class="token operator">+</span><span class="token string">"1e02258c1060bd47d0271bcfda158d6734f92d6616f95bcf2b382c25ff9e2cc"</span>str <span class="token operator">:=</span> cryptotool<span class="token punctuation">.</span><span class="token function">SHA256Double</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//转成⼤大端排序格式</span>fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"默克尔根:"</span> <span class="token punctuation">,</span> cryptotool<span class="token punctuation">.</span><span class="token function">ReverseHexString</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span></code></pre>]]></content>
<categories>
<category> 区块链 </category>
<category> 密码学 </category>
</categories>
<tags>
<tag> 加密算法 </tag>
<tag> 比特币 </tag>
</tags>
</entry>
<entry>
<title>初识Go</title>
<link href="/posts/3e321210.html"/>
<url>/posts/3e321210.html</url>
<content type="html"><![CDATA[<blockquote><p> <strong>HelloWorld</strong>程序解释及<strong>Go</strong>编码规范</p></blockquote><h4 id="⼀、HelloWorld程序解释"><a href="#⼀、HelloWorld程序解释" class="headerlink" title="⼀、HelloWorld程序解释"></a>⼀、<strong>HelloWorld</strong>程序解释</h4><h5 id="(⼀)、第⼀个HelloWorld程序"><a href="#(⼀)、第⼀个HelloWorld程序" class="headerlink" title="(⼀)、第⼀个HelloWorld程序"></a>(⼀)、第⼀个HelloWorld程序</h5><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main<span class="token keyword">import</span> <span class="token string">"fmt"</span><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment" spellcheck="true">/*这是第一个简单的程序*/</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Hello, World!"</span>)<span class="token punctuation">}</span></code></pre><h5 id="(⼆)、程序解释"><a href="#(⼆)、程序解释" class="headerlink" title="(⼆)、程序解释"></a>(⼆)、程序解释</h5><ol><li>第⼀⾏代码 package main 定义了包名。必须在源⽂件中⾮注释的第⼀⾏ 指明这个⽂件属于哪个包,如:package main。package main表示⼀个可 独⽴执⾏的程序,每个 Go 应⽤程序都包含⼀个名为 main 包。</li><li>下⼀⾏ import “fmt” 告诉 Go 编译器这个程序需要使⽤ fmt 包,fmt 包实 现了格式化 IO(输⼊/输出)的函数。</li><li>下⼀⾏ func main() 是程序⼊⼝。main 函数是每⼀个可执⾏程序所必须包 含的,⼀般来说都是在启动后第⼀个执⾏的函数,如果有 init() 函数则会先执⾏init()函数。</li><li>下⼀⾏ /<em>…</em>/ 是注释,在程序执⾏时将被忽略。单⾏注释是最常⻅见的注释形式,你可以在任何地⽅使⽤以 // 开头的单⾏注释。多⾏注释也叫块注释, 均已以 /<em> 开头,并以 </em>/ 结尾,且不可以嵌套使⽤,多⾏注释⼀般⽤于⽂档描述或代码⽚段。</li><li>下⼀⾏ fmt.Println(…) 可以将字符串输出到控制台,并在最后⾃动增加换 ⾏字符 \n。 使⽤ fmt.Print(“hello, world\n”) 可以得到相同的结果。</li></ol><h4 id="⼆、Go语⾔编码规范"><a href="#⼆、Go语⾔编码规范" class="headerlink" title="⼆、Go语⾔编码规范"></a>⼆、<strong>Go</strong>语⾔编码规范</h4><h5 id="(⼀)、注释"><a href="#(⼀)、注释" class="headerlink" title="(⼀)、注释"></a>(⼀)、注释</h5><ul><li>单⾏注释是最常⻅见的注释形式,你可以在任何地⽅使⽤以 // 开头的单⾏注释</li><li>多⾏注释也叫块注释,均已以 /<em> 开头,并以 </em>/ 结尾,且不可以嵌套使</li></ul><h5 id="(⼆)、标识符"><a href="#(⼆)、标识符" class="headerlink" title="(⼆)、标识符"></a>(⼆)、标识符</h5><ol><li>标识符⽤来命名变量、类型等程序实体。⼀个标识符实际上就是⼀个或是多 个字⺟(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第⼀个字符必须是字 ⺟或下划线⽽不能是数字。</li><li>Go不允许在标识符中使⽤@、$和%等标点符号。</li><li>Go是⼀种区分⼤⼩写的编程语⾔。因此,Manpower和manpower是两个不 同的标识符。</li><li>以下是⽆效的标识符:<ul><li>1xy(以数字开头)</li><li>case(Go 语⾔的关键字)</li><li>chan(Go 语⾔的关键字) </li><li>x+y(运算符是不允许的)</li></ul></li></ol><h5 id="(三)、Go-语⾔的空格"><a href="#(三)、Go-语⾔的空格" class="headerlink" title="(三)、Go 语⾔的空格"></a>(三)、Go 语⾔的空格</h5><ol><li>Go 语⾔中变量的声明必须使⽤空格隔开,如:var age int; </li><li>语句中适当使⽤空格能让程序更易阅读。</li><li>在变量与运算符间加⼊空格,程序看起来更加美观,如:a = x + y;</li></ol><h5 id="(四)、语句的结尾"><a href="#(四)、语句的结尾" class="headerlink" title="(四)、语句的结尾"></a>(四)、语句的结尾</h5><ol><li>在 Go 程序中,⼀⾏代表⼀个语句结束。Go语⾔中是不需要类似于Java需要 分号结尾,因为这些⼯作都将由 Go 编译器⾃动完成;</li><li>如果打算将多个语句写在同⼀⾏,它们则必须使⽤ 分号“;” ⼈为区分,但在实际开发中并不⿎励这种做法。</li></ol><h5 id="(五)、可⻅见性规则"><a href="#(五)、可⻅见性规则" class="headerlink" title="(五)、可⻅见性规则"></a>(五)、可⻅见性规则</h5><ol><li>Go语⾔中,使⽤⼤⼩写来决定标识符(常量、变量、类型、接⼝、结构或函 数)是否可以被外部包所调⽤。</li><li>、以⼀个⼤写字⺟开头,那么使⽤这种形式的标识符的对象就可以被外部包的 代码所使⽤(使⽤时程序需要先导⼊这个包),如同⾯向对象语⾔中的 public。 </li><li>如果以⼩写字⺟开头,则对包外是不可⻅见的,但是他们在整个包的内部是可 ⻅见并且可⽤的,像⾯向对象语⾔中的 private 。</li></ol><h4 id="三、Go语⾔关键字及保留字"><a href="#三、Go语⾔关键字及保留字" class="headerlink" title="三、Go语⾔关键字及保留字"></a>三、<strong>Go</strong>语⾔关键字及保留字</h4><p>下⾯列举了 Go 代码中会使⽤到的 25 个关键字或保留字:<img src="https://wx1.sinaimg.cn/large/e64a4785gy1fxptihx9alj211g0fmgnj.jpg" alt=""></p><p>除了以上介绍的这些关键字,Go 语⾔还有 36 个预定义标识符:<img src="https://wx1.sinaimg.cn/large/e64a4785gy1fxptjo7r1qj211c0bwq4p.jpg" alt=""></p><p> </p><h4 id="四、Go-程序结构组成"><a href="#四、Go-程序结构组成" class="headerlink" title="四、Go 程序结构组成"></a>四、Go 程序结构组成</h4><h5 id="(⼀)、Go⼀般结构"><a href="#(⼀)、Go⼀般结构" class="headerlink" title="(⼀)、Go⼀般结构"></a>(⼀)、Go⼀般结构</h5><pre class=" language-go"><code class="language-go"><span class="token comment" spellcheck="true">// 当前程序的包名</span><span class="token keyword">package</span> main<span class="token comment" spellcheck="true">// 导⼊其他包</span><span class="token keyword">import</span> <span class="token string">"fmt"</span><span class="token comment" spellcheck="true">// 常量定义</span><span class="token keyword">const</span> PI <span class="token operator">=</span> <span class="token number">3.14</span><span class="token comment" spellcheck="true">// 全局变量的声明和赋值</span><span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token string">"gopher"</span><span class="token comment" spellcheck="true">// ⼀般类型声明</span><span class="token keyword">type</span> newType <span class="token builtin">int</span><span class="token comment" spellcheck="true">// 结构的声明</span><span class="token keyword">type</span> gopher <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 接⼝的声明</span><span class="token keyword">type</span> golang <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 由main函数作为程序⼊⼝点启动</span><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Hello World!"</span><span class="token punctuation">)</span><span class="token punctuation">}</span></code></pre><h5 id="(⼆)、Go-⽂件的基本组成部分"><a href="#(⼆)、Go-⽂件的基本组成部分" class="headerlink" title="(⼆)、Go ⽂件的基本组成部分"></a>(⼆)、Go ⽂件的基本组成部分</h5><ol><li>包声明</li><li>引入包</li><li>函数</li><li>变量</li><li>语句&表达式</li><li>注释</li></ol><h5 id="(三)、Go⽂件结构组成"><a href="#(三)、Go⽂件结构组成" class="headerlink" title="(三)、Go⽂件结构组成"></a>(三)、Go⽂件结构组成</h5><ol><li><p>Go 程序是通过 package 来组织的。</p><ul><li>只有 package 名称为 main 的包可以包含 main 函数。</li><li>⼀个可执⾏程序有且仅有⼀个 main 包。</li><li>通过 import 关键字来导⼊其他⾮ main 包。</li><li>可以通过 import 关键字单个导⼊,也可以同时导⼊多个</li></ul></li><li><p>程序⼀般由关键字、常量、变量、运算符、类型和函数组成。</p></li><li><p>程序中可能会使⽤到这些分隔符:括号 (),中括号 [] 和⼤括号 {}。</p></li><li><p>程序中可能会使⽤到这些标点符号:</p><ul><li>点</li><li>逗号</li><li>分号</li><li>冒号</li><li>省略号(三个点)</li></ul></li><li><p>通过 const 关键字来进⾏常量的定义。</p></li><li><p>通过在函数体外部使⽤ var 关键字来进⾏全局变量的声明和赋值。</p></li><li><p>通过 type 关键字来进⾏结构(struct)和接⼝(interface)的声明。</p></li><li><p>通过 func 关键字来进⾏函数的声明。</p></li></ol>]]></content>
<categories>
<category> 后端 </category>
</categories>
<tags>
<tag> GoLang </tag>
</tags>
</entry>
<entry>
<title>比特币客户端Bitcoin Core及Bitcoin-cli命令</title>
<link href="/posts/f69008c9.html"/>
<url>/posts/f69008c9.html</url>
<content type="html"><![CDATA[<h2 id="一、区块链节点及⽐比特币钱包"><a href="#一、区块链节点及⽐比特币钱包" class="headerlink" title="一、区块链节点及⽐比特币钱包"></a>一、区块链节点及⽐比特币钱包</h2><h4 id="一-、节点的分类"><a href="#一-、节点的分类" class="headerlink" title="(一)、节点的分类"></a>(一)、节点的分类</h4><ol><li>全节点:同步整个区块链并对交易易做验证;<ul><li>全节点是指维持包含全部交易易信息的完整区块链的节点。辨别您是否在运行全节点是十分容易的:只需要查看您的永久性存储设备(如硬盘)是否有超过20GB的空间被用来存储完整区块链即可。<ul><li>2013年时全节点⼤⼩在⼏⼗个G,2017年8⽉全节点⼤⼩已经达到130G左右,2018年3⽉则达到200多G。</li></ul></li></ul></li><li>轻节点:不保存所有区块,依赖全节点做交易验证;</li><li>记账节点:挖矿节点(具有挖矿功能的全节点)、公证⼈节点。</li></ol><h4 id="二-、维护区块链需要优质节点"><a href="#二-、维护区块链需要优质节点" class="headerlink" title="(二)、维护区块链需要优质节点"></a>(二)、维护区块链需要优质节点</h4><ol><li><p>⽐特币⽤户包含⼤量对计算机了解有限的⼈,核⼼钱包对他们来说体验极差,他们对钱包⽂件不加密、少备份,⽽且敢于允许不认识的⼈远程控制,他们没有能⼒去维护节点。</p></li><li><p>维护节点不是免费的,节点消耗⼤量的硬盘空间、带宽、电、时间、精⼒,这些加起来可能已经超过⼀些⽤户持有⽐特币的总价值。最重要的是他们使⽤结束后随⼿就把电脑关了,可能⼏个⽉⼏年才想起来再打开⽐特币客户端。他们没有动⼒去维护节点。</p></li><li><p>另⼀⽅⾯,⽐特币专业⽤户(矿场、专业个⼈、交易所、⼤商家、⽐特币服务供应商),有能⼒也有动⼒去维护⾄少⼀个优质节点,这些⼈才是⽐特币交易的主⼒——⼤多数⽐特币的(链上)交易来⾃相对较少的⽐特币专业⽤户。</p></li><li><p>所以有⼀种看法认为,低速节点是有害的,它们浪费⽹络资源,对安全性并没有什么实质帮助;只有⾼速的、专业的节点才有益于⽐特币⽹络。⽐特币未来的趋势是节点更加专业,数量更少但速度更快、更稳定,这不代表更危险,反⽽让⽐特币⽹络更加强壮。</p></li><li><p>区块链⽂件变得越来越⼤,要每个使⽤者都去做节点的维护者,既不现实也不科学,过低的易⽤性反⽽会影响⽐特币的推⼴和使⽤。</p></li><li><p>同步200多G的节点⽂件对普通⽤户来说是不必要的。如果是区块时间很短的ETH,更不敢想象。截⽌现在,全球⽐特币⽤户规模⼤概500W左右,对于这样⼀个⽤户群体数量,1W个左右的节点,这⼀⽐例已经不低了。毕竟维护节点⼏乎是公益性质的⾏为,也只有专业⽤户才有这样的技术、能⼒<br>和动⼒。</p><p><img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwtoz08wt7j21xg12wb29.jpg" alt="1541139351195"></p></li></ol><h4 id="三-、节点相关问题"><a href="#三-、节点相关问题" class="headerlink" title="(三)、节点相关问题"></a>(三)、节点相关问题</h4><ol><li>什么原因造成节点数不多?<ul><li>全节点需要加载全部历史数据,BTC目前区块总大小大约200G,这个数目对于矿池、交易所、钱包来说是毛毛雨,但是对于绝大多数个人投资者来说,意味着相当大的硬盘资源,更别说还需要占用一部分带宽,消耗电力等,所以对于普通投资者大部分要么是把钱放在交易所里面,要么是选择轻钱包。运行全节点,并没有太多的经济利益。</li></ul></li><li>为了维护整个⽐特币系统的安全,节点数⽬有必要增多吗?<ul><li>需要,作为⼀个去中⼼化的的P2P⽹络,更多、更分散的节点数才能保证系统能够抵抗突发的技术冲击,甚⾄是政治冲击。但是维护整个⽹络正常运⾏还是需要优质节点。</li></ul></li><li>中本聪等⼈设计之初衷,是希望每个⽐特币⽤户都成为⼀个全节点吗?<ul><li>并⾮每个⽐特币⽤户都能成为全节点。中本聪预测到了当⽐特币⽹络⾜够⼤的时候,运⾏全节点的任务会被交给专业的服务者集群“sever farm”⽽不是“most users”。对于个⼈节点,他们的硬件性能、⽹络资源、维护意愿都不够强,这样的全节点其实是很难起到维护全⽹安全性的作⽤。下⾯这个是早年中本聪在邮件组⾥给⼈的回复。 Long before the network gets anywhere near as large as that, it would be safe for<br>users to use Simplified Payment Verification (section 8) to check for double<br>spending, which only requires having the chain of block headers, or about 12KB<br>per day. Only people trying to create new coins would need to run network nodes.<br>At first, most users would run network nodes, but as the network grows beyond a certain point, it would be left more and more to specialists with server farms of specialized hardware. A server farm would only need to have one node on the network and the rest of the LAN connects with that one node.<br>The bandwidth might not be as prohibitive as you think. A typical transaction<br>would be about 400 bytes (ECC is nicely compact). Each transaction has to be broadcast twice, so lets say 1KB per transaction. Visa processed 37 billion<br>transactions in FY2008, or an average of 100 million transactions per day.<br>That many transactions would take 100GB of bandwidth, or the size of 12 DVD or 2<br>HD quality movies, or about $18 worth of bandwidth at current prices.<br>If the network were to get that big, it would take several years, and by then,<br>sending 2 HD movies over the Internet would probably not seem like a big deal.<br>Satoshi Nakamoto</li></ul></li></ol><h4 id="四-、钱包的含义"><a href="#四-、钱包的含义" class="headerlink" title="(四)、钱包的含义"></a>(四)、钱包的含义</h4><ol><li>“钱包”⼀词在⽐特币中有多重含义。</li><li>⼴义上,钱包是⼀个应⽤程序,为⽤户提供交互界⾯。 钱包控制⽤户访问权限、管理密钥和地址、跟踪余额、创建交易和签名交易。</li><li>ሀ义上,即从程序员的⻆度来看,“钱包”是指⽤于存储和管理⽤户密钥的数据结构。</li><li>钱包是私钥的容器,⼀般是通过结构化⽂件或简单数据库来实现。</li><li>⼀个常⻅误解是,⽐特币钱包⾥含有⽐特币。 事实上,钱包⾥只含有钥匙。 “钱币”被记录在⽐特币⽹络的区块链中。 ⽤户通过钱包中的密钥签名交易,从⽽来控制⽹络上的钱币。 在某种意义上,⽐特币钱包是密钥链。</li><li>⽐特币钱包只含有密钥,⽽不是钱币。 每个⽤户有⼀个包含多个密钥的钱包。 钱包只包含私钥/公钥对的密钥链。 ⽤户⽤密钥签名交易,从⽽证明他们拥有交易输出(他们的钱币)。 钱币以交易输出的形式存储在区块链中(通常记为vout或txout)。</li><li>钱包的作⽤:<ul><li>保存⽤户私钥</li><li>保存交易记录,管理⽤户余额</li><li>提供⽐特币交易(⽀付和转账)</li></ul></li></ol><h4 id="五-、钱包的含义"><a href="#五-、钱包的含义" class="headerlink" title="(五)、钱包的含义"></a>(五)、钱包的含义</h4><ol><li>根据密钥关联性分类<ul><li>第⼀种类型是⾮确定性钱包(Nondeterministic Wallet)<ul><li>钱包中每个密钥都是从随机数ᇿ⽴⽣成的,密钥彼此⽆关。</li><li>最早的⼀批⽐特币客户端(以前叫Bitcoin-QT, 现在称作⽐特币核⼼客户端Bitcoin Core),钱包只是随机⽣成的私钥集合。这种类型的钱包被称作零型⾮确定钱包。</li><li>虽然⽐特币核⼼客户端包含零型钱包,但⽐特币的核⼼开发者并不⿎励⼤家使⽤。这种钱包现在正在被确定性钱包替换。</li><li>⾮确定性钱包直接保存私钥,私钥数据保存在Berkeley DB上。</li><li>⾮确定性钱包因为直接保存私钥,如果私钥被盗窃,钱包⾥的⽐特币就会被盗⾛。因此⾮确定性钱包安全性不⾼。</li><li>⽐特币系统出于隐私保护的缘故,不⿎励⽐特币地址重复使⽤。所以⽐特币地址对应的私钥⾃然会⽐较多,⽽⾮确定性钱包管理这些私钥⽐较麻烦,备份也不⽅便。</li></ul></li><li>第⼆种类型是确定性钱包(Deterministic Wallet)<ul><li>钱包中所有的私钥都是从⼀个私钥种⼦(seed)通过哈希算法⽣成,该类型钱包中所有私钥都相互关联。因此备份该类钱包⾮常容易,只要备份私钥种⼦,就可以利⽤种⼦⼀次性恢复所有的私钥。</li><li>确定性钱包根据不同的密钥推导⽅法。分为普通型确定性钱包和层级确定性钱包(HD钱包,Hierarchical Deterministic Wallet)。</li><li>普通型确定性钱包,私钥种⼦直接⽣成所有私钥。</li><li>最常⽤的推导⽅法是使⽤树状结构,这就是层级确定性钱包或HD钱包。它的私钥保存在⼀个树形结构,由⼀个总私钥⽣成⽗私钥,⽗私钥⽣成⼦私钥。</li><li>确定性钱包由种⼦衍⽣创造。为了便于使⽤,种⼦被编码为英⽂单词,称为助记词。</li><li>HD钱包有两个主要的优势。<ul><li>第⼀,树状结构可以被⽤来表达额外的组织含义。</li><li>HD钱包的第⼆个好处就是它可以允许让使⽤者去建⽴⼀个公共密钥的序列⽽不需要访问相对应的私钥。</li></ul></li></ul></li></ul></li><li>根据部署的平台分类:<ul><li>桌⾯钱包<ul><li>分为厚钱包和薄钱包</li><li>厚钱包下载整条区块链并进⾏完整的交易校验。厚钱包主要有BitcoinCore、Armory钱包。</li><li>薄钱包不下载整条区块链,⽽是采⽤如SPV等⽅式验证⽀付交易。例如Multibit钱包、Electrum钱包。</li><li>厚钱包优点是安全,缺点是数据保存和验证的开销成本⼤;薄钱包优点是灵活⾼效,缺点是安全性不⾼。</li></ul></li><li>⼿机钱包(移动钱包)<ul><li>运⾏在只能⼿机上的轻量级钱包。由于运⾏资源有限,不会下载整条区块链,⽽采⽤SPV的⽅法验证交易,因此这类钱包也叫做SPV钱包。</li><li>SPV(Simplified Payment Verification , 简化⽀付验证):⽤户不需要验证交易,只是连接到⼀个可信任的节点,从该节点下载所有的区块头信息。⽤户根据区块头信息的查询,以及该区块的交易确认数来验证⽀付的真伪。</li></ul></li><li>在线钱包(互联⽹钱包)<ul><li>在线钱包也不下载整条区块链,⽽是依托第三⽅平台提供对⽤户隐私的保护。</li><li>优点是可以在任何地⽅、任何设备管理钱包,使⽤灵活⽅便;缺点是安全性不⾼。</li><li>例如Blockchain.info提供的互联⽹钱包以及CoinCornet等。</li><li>硬件钱包</li><li>纸钱包<ul><li>⽤于将私钥进⾏冷备份,防范由于电⼦设备损坏造成的私钥丢失。</li></ul></li><li>脑钱包</li></ul></li></ul></li><li>根据钱包的⾃主程度以及如何与⽐特币⽹络进⾏交互:<ul><li>全节点客户端</li><li>轻量级客户端</li><li>第三⽅API客户端</li></ul></li></ol><h2 id="二、比特币核⼼钱包Bitcoin-Core"><a href="#二、比特币核⼼钱包Bitcoin-Core" class="headerlink" title="二、比特币核⼼钱包Bitcoin Core"></a>二、比特币核⼼钱包Bitcoin Core</h2><h4 id="一-、Bitcoin-Core的安装"><a href="#一-、Bitcoin-Core的安装" class="headerlink" title="(一)、Bitcoin Core的安装"></a>(一)、Bitcoin Core的安装</h4><ol><li><p>⽐特币官⽅钱包客户端的原名是Bitcoin-QT,现在更名为Bitcoin Core(⽐特币核⼼钱包),⽬前最新版本是0.16.1版本。</p></li><li><p>Bitcoin Core钱包是完整的、安全的⽐特币钱包客户端,但是,他的区块链数据⽂件(blockchain)体积庞⼤,不适合普通的⽐特币⽤户使⽤。</p></li><li><p>⾸先,到⽐特币官⽅⽹站下载钱包,注意选择32位或者64位。<br><a href="https://bitcoin.org/zh_CN/download" rel="external nofollow noopener noreferrer" target="_blank">https://bitcoin.org/zh_CN/download</a></p><p><img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwtp4npx00j21ua11awmy.jpg" alt="1541139475103"></p></li><li><p>安装钱包,然后启动钱包,设置数据存储位置。安装完毕就可以数据同步,截⽌2018年7⽉区块总数达到53万多,需要205GB 以上的空间。</p><p><img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwtp57qpeqj21aq0xwn9s.jpg" alt="1541139503286"></p><p><img src="http://wx3.sinaimg.cn/large/e64a4785gy1fwtp5tzs1ij20ww0p8jud.jpg" alt="1541139513031"></p><p><img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwtp7ua621j21re14swix.jpg" alt="1541139523333"></p></li><li><p>下载区块链的数据⽂件</p><ul><li>新安装的⽐特币核⼼客户端需要同步数据是⼀个漫⻓的过程,⼀般的使⽤者想要快速使⽤的话推荐使⽤multibit等轻客户端。</li></ul></li><li><p>加密钱包</p><ul><li><p>数据同步完成后,钱包才能正常⼯作。这时,请⽴即设置密码并备份钱包。</p></li><li><p>⼀个好的密码,应该包括16位以上(最好20位以上)的⼤⼩写字⺟、数字及特殊符号,且不要使⽤⽣⽇、名字、证件号码等易被猜测的密码。警告:遗忘密码等于丢失所有⽐特币。</p><p><img src="http://ws4.sinaimg.cn/large/e64a4785gy1fwtp6i9bukj21zq18cn1a.jpg" alt="1541139639080"></p></li><li><p>伯克利市(City of Berkeley),是美国加州旧⾦⼭湾区的城市,是世界著名⾼等学府加州⼤学伯克利分校(UC Berkeley)所在地;</p></li><li><p>Berkeley DB是⼀个开源的⽂件数据库,介于关系数据库与内存数据库之间,使⽤⽅式与内存数据库类似,它提供的是⼀系列直接访问数据库的函数,⽽不是像关系数据库那样需要⽹络通讯、SQL解析等步骤。</p></li></ul></li><li><p>进⾏交易</p><ul><li><p>在“发送”选项卡,可以把你的⽐特币发送给其他⽐特币⽤户。请注意:交易⼀经确认,⽆法逆转!请仔细确认交易信息。系统可能根据情况征收交易费,请选择⽀付。(⼀般情况是0.0001BTC,万分之⼀⽐特币)</p></li><li><p>在“接收”选项卡,我们可以获取⾃⼰的钱包地址。直接点击“请求付款”,将⽣成⼀个新的地址。你可以将这个地址给别⼈,让他们向你发送⽐特币。</p></li><li><p>点击“请求付款”按钮,即可显示接收地址和⼆维码了。</p><p><img src="http://wx4.sinaimg.cn/large/e64a4785gy1fwtp8a7q5tj20vq132q4p.jpg" alt="1541139656928"></p></li></ul></li></ol><h4 id="二-、Bitcoin-Core客户端⽬录结构"><a href="#二-、Bitcoin-Core客户端⽬录结构" class="headerlink" title="(二)、Bitcoin Core客户端⽬录结构"></a>(二)、Bitcoin Core客户端⽬录结构</h4><ol><li><p>数据区块⽂件的位置</p><ul><li>如果你⽤的是Bitcoin-Core客户端,那么数据区块的信息就存在你的电脑⾥⾯。每次当你打开BitcoinCore,数据区块都会跟整个P2P⽹络分布式数据库同步。根据操作系统的不同,数据区块⽬录blocks⼀般存放路径为:<ul><li>Windows: %APPDATA%\Bitcoin\</li><li>Linux:~/.bitcoin/</li><li>Mac OS: ~/Library/Application Support/Bitcoin/</li></ul></li></ul></li><li><p>打开数据区块⽂</p><ul><li><p>blocks⽬录</p><ul><li>blocks/blk*.dat:区块数据。该⽬录下可以看到很多名为blkXXXXX.dat的⽂件,这些⽂件中保存了每个区块的完整数据。保存在磁盘上的这些数据,同时还提供给其他正在同步的节点。</li><li>blocks/rev*.dat:these contain “undo” data.</li></ul></li><li><p>index⽬录</p><ul><li>blocks/index/*.ldb:区块索引⽂件。该⽬录下存放的是LevelDB数据库⽂件,它包含关于所有已知块的元数据,以及它们在磁盘上的位置。如果没有这些索引⽂件,找到⼀个块将会⾮常缓慢。</li></ul></li><li><p>chainstate ⽬录</p><ul><li>chainstate/*.ldb:交易状态数据。该⽬录下存放的是LevelDB数据库⽂件,它包含所有UTXO交易信息,以及这些交易信息的元数据。这对于交易验证⾮常必要。如果没有它,理论上仍然可以进⾏交易验证,但这意味着要对每⼀个输出进⾏⼀次完整的扫描(到2018年4⽉,区块数据⼤⼩已经达到200多 GB)。</li></ul></li><li><p>其他⽂件</p><ul><li><p>bitcoin.conf ⽐特币客户端的配置⽂件</p></li><li><p>debug.log 调试信息⽂件,各种⽇志均写⼊到该⽂件中</p></li><li><p>peers.dat 节点的信息</p></li><li><p>wallet.dat 钱包⽂件,保存⽤户私钥和交易记录,⾮常重要</p></li><li><p>testnet3⽬录 测试链的数据⽬录(bitcoin.conf配置testnet=1即可使⽤测试⽹络)There are basically four pieces of data that are maintained:<br>• blocks/blk<em>.dat : the actual Bitcoin blocks, in network format, dumped in raw on disk. They are only needed for rescanning missing transactions in a wallet, reorganizing to a different part of the chain, and serving the block data to other nodes that are synchronizing.<br>• blocks/index/</em> : this is a Level DB database that contains metadata about all known blocks,<br>and where to find them on disk. Without this, finding a block would be very slow.<br>• chainstate/<em> : this is a LevelDB database with a compact representation of all currently<br>unspent transaction outputs and some metadata about the transactions they are from. The data here is necessary for validating new incoming blocks and transactions. It can theoretically be rebuilt from the block data (see the -reindex command line option), but this takes a rather long time. Without it, you could still theoretically do validation indeed, but it would mean a full scan through the blocks (140 GB as of july 2017) for every output being spent.<br>• blocks/rev</em>.dat : these contain “undo” data. You can see blocks as ‘patches’ to the chain state<br>(they consume some unspent outputs, and produce new ones), and see the undo data as reverse patches. They are necessary for rolling back the chainstate, which is necessary in case of reorganisations.</p><p><img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwtox0jvpkj20ks0tm42v.jpg" alt="1541139243374"></p></li></ul></li></ul></li><li><p>数据区块结构(blkXXX.dat⽂件)</p><ul><li><p>使⽤UltraEdit编辑器打开。</p><p><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwtugm7np4j20l30lx4gz.jpg" alt="1541138843710"></p></li><li><p>数据区块⽂件⼗六进制</p><ul><li><p>每⼀个数据区块记录了六个内容:神奇数、区块⼤⼩、数据区块头部信息、交易计数、交易详情。</p></li><li><p>在这当中,数据区块头部信息的HASH值是下⼀个新区块的HASH值的参考⽬标数,最后⼀项交易详情记录了该区块中所有的交易记录</p></li><li><p>数据区块结构如下图:</p><p><img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwtos43wbrj20g308pwet.jpg" alt=""></p><p><img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwtou2biaoj211212kamz.jpg" alt="1541139077107"></p></li><li><p>该文件中最后一个区块的信息:</p><ul><li><p>上一个区块的哈希:00000000000039C58815C3CB356A6CD84B9674DC4AFCC26E8A 456C8EA4BCBED8</p></li><li><p>时间戳:1303688583 (北京时间2011-04-25 07:43:03)</p><p><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwtqf1kt98j210q13eqhb.jpg" alt="1541140103847"></p></li><li><p>查找⽐特币浏览器后,详细信息为:</p><p><img src="http://wx3.sinaimg.cn/large/e64a4785gy1fwtqfe31n9j21sc0dewhl.jpg" alt="1541140153262"></p></li><li><p>blk00000.dat中存储了12万个区块的信息,因为早期⽐特币区块因为交易信息少,所以区块⼤⼩都很⼩,所以100多M的⽂件中能存储12万条区块数据;</p></li><li><p>⽽后期⽐特币交易增多,区块变⼤,则每个blk*.dat⽂件中存储的区块数量就变少了。</p></li></ul></li></ul></li></ul></li></ol><h4 id="三-、轻节点钱包——Multibit"><a href="#三-、轻节点钱包——Multibit" class="headerlink" title="(三)、轻节点钱包——Multibit"></a>(三)、轻节点钱包——Multibit</h4><ol><li><p>MultiBit 钱包是⼀个易于使⽤,占据空间少的轻量级桌⾯钱包,适合个⼈⽇常使⽤。但由于其使⽤⽹络节点查询交易信息,安全性稍低;该钱包不适合⼤额⽐特币⽀付及冷存储使⽤。</p></li><li><p>下载地址:<a href="https://multibit.org/download.html" rel="external nofollow noopener noreferrer" target="_blank">https://multibit.org/download.html</a></p></li><li><p>安装</p><ul><li><p>选择安装语⾔</p><p><img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwtqfta5ugj21k813k416.jpg" alt="1541140266439"></p></li><li><p>选择创建⼀个新钱包</p><p><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwtqg3ddf3j21k813k0vj.jpg" alt="1541140287186"></p></li><li><p>创建钱包准备</p><p><img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwtqglv7xij21k813kag8.jpg" alt="1541140319535"></p></li><li><p>选择备份位置</p><p><img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwtqgv788mj21k813k0wm.jpg" alt="1541140334855"></p></li><li><p>创建钱包密语</p><p><img src="http://wx3.sinaimg.cn/large/e64a4785gy1fwtqh95oyjj21k813kq89.jpg" alt="1541140348681"></p></li><li><p>确认钱包密语</p><p><img src="http://wx3.sinaimg.cn/large/e64a4785gy1fwtqi60197j21k813ktcx.jpg" alt="1541140363704"></p></li><li><p>创建钱包密码</p><p><img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwtqihnqsjj21k813kq6h.jpg" alt="1541140376466"></p></li><li><p>创建钱包报告</p><p><img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwtqiu9mpej21k813kgow.jpg" alt="1541140392640"></p></li><li><p>安装完成。输⼊钱包密码,进⼊钱包<img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwtqj53fmhj21k813kwj2.jpg" alt="1541140562826"></p></li><li><p>钱包启动<img src="http://wx3.sinaimg.cn/large/e64a4785gy1fwtquh1svrj21k813k774.jpg" alt="1541140588638"><img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwtqkb9bxtj21k813k0ux.jpg" alt="1541140604795"></p></li></ul></li></ol><h2 id="三、测试⽹络中⽤钱包实现⽐特币交易"><a href="#三、测试⽹络中⽤钱包实现⽐特币交易" class="headerlink" title="三、测试⽹络中⽤钱包实现⽐特币交易"></a>三、测试⽹络中⽤钱包实现⽐特币交易</h2><h4 id="一-、切换到测试⽹络"><a href="#一-、切换到测试⽹络" class="headerlink" title="(一)、切换到测试⽹络"></a>(一)、切换到测试⽹络</h4><p>1.进⼊Bitcoin Core 偏好设置<img src="http://ws4.sinaimg.cn/large/e64a4785gy1fwtqkq6sgoj212g0weac6.jpg" alt="1541140744894"></p><ol start="2"><li><p>打开配置⽂件</p><ul><li>⽂件路径:Mac OS: ~/Library/Application Support/Bitcoin/bitcoin.conf</li><li><p>testnet=1表示为测试⽹络</p></li><li><p>testnet=0表示为正式⽐特币⽹络<img src="http://ws4.sinaimg.cn/large/e64a4785gy1fwtqjj0xwvj21so19iahw.jpg" alt="1541140787958"></p></li></ul></li></ol><ol start="3"><li>退出Bitcoin Core钱包后,重新启动,进⼊到测试⽹络的Bitcoin Core<img src="http://wx3.sinaimg.cn/large/e64a4785gy1fwtql4s6tej20ww0p8q6d.jpg" alt="1541140877239"></li><li>同步数据<ul><li>同步数据开始,将在Bitcoin⽬录下产⽣testnet3⽬录;</li><li>测试⽹络下,截⽌到2018年4⽉,区块链的区块总数为129万多,区块⽂件⼤⼩合计约14G。<img src="http://wx4.sinaimg.cn/large/e64a4785gy1fwtqlfi1pej20ho0mu414.jpg" alt="1541140926569"><img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwtqtpic54j20wq0p8tft.jpg" alt="1541140935371"><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwtqlq3bixj21ge14cn16.jpg" alt="1541140942623"></li></ul></li></ol><h4 id="二-、获取测试⽐特币"><a href="#二-、获取测试⽐特币" class="headerlink" title="(二)、获取测试⽐特币"></a>(二)、获取测试⽐特币</h4><ol><li><p>登录测试⽐特币的⽔⻰头⽹站</p><ul><li><p>打开⽔⻰头⽹站:<a href="https://testnet.manu.backend.hamburg/faucet" rel="external nofollow noopener noreferrer" target="_blank">https://testnet.manu.backend.hamburg/faucet</a></p><ul><li><p>⽐特币⽔⻰头”是⼀种全新的免费获取⽐特币的体验站点,英⽂为“Bitcoin Faucet”。</p></li><li><p>只需要输⼊简单的验证码,可以在固定的时间段免费获得⼀定⽐例⽐特币。⼀般每次可以获取0.00000012个⽐特币。</p></li><li><p>正式⽐特币的⽔⻰头⽹站地址例如:<a href="http://bfaucet.com" rel="external nofollow noopener noreferrer" target="_blank">http://bfaucet.com</a></p></li></ul></li><li>通过⽐特币钱包,复制⽐特币地址</li><li>把复制的⽐特币地址粘贴到输⼊框,点击 “Give me some coins”</li><li>如果获取⽐特币成功,则会在输⼊框上⽅显示绿⾊的字符串:“Sent!TXID:交易id号”<img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwtqmitu97j226815c46e.jpg" alt="1541141092438"></li></ul></li></ol><ol start="2"><li>通过钱包查看交易记录<img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwtqmyrrfdj215m0rqq96.jpg" alt="1541141153183"><img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwtqnrshf6j215o0ruwjr.jpg" alt="1541141161001"></li></ol><ol start="3"><li>⽐特币测试⽹络浏览器<ul><li><a href="https://testnet.blockchain.info" rel="external nofollow noopener noreferrer" target="_blank">https://testnet.blockchain.info</a></li></ul></li></ol><p><img src="http://ws4.sinaimg.cn/large/e64a4785gy1fwtqo85muij226815ctfr.jpg" alt="1541141200226"></p><h4 id="三-、测试⽹络下进⾏⽐特币交易"><a href="#三-、测试⽹络下进⾏⽐特币交易" class="headerlink" title="(三)、测试⽹络下进⾏⽐特币交易"></a>(三)、测试⽹络下进⾏⽐特币交易</h4><ol><li>填写“发送”数据<ul><li>填写“付给”,也就是收款⼈的⽐特币地址</li><li>设置找零地址<ul><li>⽐特币在转帐时,内部实现要求每⼀个输⼊都要被完全花掉,BitcoinCore客户端会通过“找零”机制,将不想转给别⼈的部分转给⾃⼰的另外⼀个地址。</li><li>通常,这个“⾃⼰的另外⼀个地址”是⼀个新⽣成的地址,这给备份⽐特币钱包带来了麻烦。其实可以通过将找零地址指定为⾃⼰的“旧”地址来避开这个麻烦。</li><li>点击“添加收款⼈”,将找零的⾦额发送给⾃⼰的旧地址即可。余额数据通过点击“Use avaliable balance”获取,因为交易要付⼿续费,所以勾选“从⾦额中减去交易费”<img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwtqor6v9hj21yw14s0xf.jpg" alt="1541141309974"></li></ul></li></ul></li></ol><ol start="2"><li>通过⽐特币浏览器查看交易记录</li></ol><p><img src="http://ws4.sinaimg.cn/large/e64a4785gy1fwtqp5pj39j21ya0fq78z.jpg" alt="1541141411497"></p><p><img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwtqpluztcj21v00bwacs.jpg" alt="1541141421051"></p><h2 id="四、bitcoin-cli-命令"><a href="#四、bitcoin-cli-命令" class="headerlink" title="四、bitcoin-cli 命令"></a>四、bitcoin-cli 命令</h2><h4 id="一-、进⼊Bitcoin-Core-的-RPC-控制台"><a href="#一-、进⼊Bitcoin-Core-的-RPC-控制台" class="headerlink" title="(一)、进⼊Bitcoin Core 的 RPC 控制台"></a>(一)、进⼊Bitcoin Core 的 RPC 控制台</h4><p><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwtqq3nfqaj21ge14c0z4.jpg" alt="1541141485063"></p><h4 id="二-、执⾏bitcoin-cli-命令(108条)"><a href="#二-、执⾏bitcoin-cli-命令(108条)" class="headerlink" title="(二)、执⾏bitcoin-cli 命令(108条)"></a>(二)、执⾏bitcoin-cli 命令(108条)</h4><ol><li>== Blockchain ==<ul><li>getbestblockhash</li><li>getblock “blockhash” ( verbosity )</li><li>getblockchaininfo</li><li>getblockcount</li><li>getblockhash height</li><li>getblockheader “hash” ( verbose )</li><li>getchaintips</li><li>getchaintxstats ( nblocks blockhash )</li><li>getdifficulty</li><li>getmempoolancestors txid (verbose)</li><li>getmempooldescendants txid (verbose)</li><li>getmempoolentry txid</li><li>getmempoolinfo</li><li>getrawmempool ( verbose )</li><li>gettxout “txid” n ( include_mempool )</li><li>gettxoutproof [“txid”,…] ( blockhash )</li><li>gettxoutsetinfo</li><li>preciousblock “blockhash”</li><li>pruneblockchain</li><li>savemempool</li><li>verifychain ( checklevel nblocks</li></ul></li><li>== Control ==<ul><li>getmemoryinfo (“mode”)</li><li>help ( “command” )</li><li>logging ( <include> <exclude> )</exclude></include></li><li>stop</li><li>uptime</li></ul></li><li>== Generating ==<ul><li>generate nblocks ( maxtries )</li><li>generatetoaddress nblocks address (maxtries)</li></ul></li><li>== Mining ==<ul><li>etblocktemplate ( TemplateRequest )</li><li>getmininginfo</li><li>getmininginfo</li><li>prioritisetransaction <txid> <dummy value=""> <fee delta=""></fee></dummy></txid></li><li>submitblock “hexdata” ( “dummy” )</li></ul></li><li>== Network ==<ul><li>addnode “node” “add|remove|onetry”</li><li>clearbanned</li><li>disconnectnode “[address]” [nodeid]</li><li>getaddednodeinfo ( “node” )</li><li>getconnectioncount</li><li>getnettotals</li><li>getnetworkinfo</li><li>getpeerinfo</li><li>listbanned</li><li>ping</li><li>setban “subnet” “add|remove” (bantime) (absolute)</li><li>setnetworkactive true|false</li></ul></li><li>== Rawtransactions ==<ul><li>combinerawtransaction [“hexstring”,…]</li><li>createrawtransaction [{“txid”:”id”,”vout”:n},…]{“address”:amount,”data”:”hex”,…} ( locktime ) ( replaceable )</li><li>decoderawtransaction “hexstring” ( iswitness )</li><li>decodescript “hexstring”</li><li>fundrawtransaction “hexstring” ( options iswitness</li><li>getrawtransaction “txid” ( verbose “blockhash” )</li><li>sendrawtransaction “hexstring” ( allowhighfees )</li><li>signrawtransaction “hexstring” ([{“txid”:”id”,”vout”:n,”scriptPubKey”:”hex”,”redeemScript”:”hex”},…][“privatekey1”,…] sighashtype )</li></ul></li><li>== Util ==<ul><li>createmultisig nrequired [“key”,…]</li><li>estimatefee nblocks</li><li>estimatesmartfee conf_target (“estimate_mode”)</li><li>signmessagewithprivkey “privkey” “message”</li><li>validateaddress “address”</li><li>verifymessage “address” “signature” “message”</li></ul></li><li>== Wallet ==<ul><li>abandontransaction “txid”</li><li>abortrescan</li><li>addmultisigaddress nrequired [“key”,…] ( “account” “address_type” )</li><li>backupwallet “destination”</li><li>bumpfee “txid” ( options )</li><li>dumpprivkey “address”</li><li>dumpwallet “filename”</li><li>encryptwallet “passphrase”</li><li>getaccount “address”</li><li>getaccountaddress “account</li><li>getaddressesbyaccount “account</li><li>getbalance ( “account” minconf include_watchonly )</li><li>getnewaddress ( “account” “address_type” )</li><li>getrawchangeaddress ( “address_type” )</li><li>getreceivedbyaccount “account” ( minconf )</li><li>getreceivedbyaddress “address” ( minconf )</li><li>gettransaction “txid” ( include_watchonly )</li><li>getunconfirmedbalance</li><li>getwalletinfo</li><li>importaddress “address” ( “label” rescan p2sh )</li><li>importmulti “requests” ( “options” )</li><li>importprivkey “privkey” ( “label” ) ( rescan )</li><li>importprunedfunds</li><li>importpubkey “pubkey” ( “label” rescan</li><li>importwallet “filename</li><li>keypoolrefill ( newsize )</li><li>listaccounts ( minconf include_watchonly)</li><li>listaddressgroupings</li><li>listlockunspent</li><li>istreceivedbyaccount ( minconf include_empty include_watchonly )</li><li>listreceivedbyaddress ( minconf include_empty include_watchonly)</li><li>listsinceblock ( “blockhash” target_confirmations include_watchonly include_removed )</li><li>listtransactions ( “account” count skip include_watchonly)</li><li>listunspent ( minconf maxconf [“addresses”,…][include_unsafe][query_options])</li><li>listwallets</li><li>lockunspent unlock ([{“txid”:”txid”,”vout”:n},…])</li><li>move “fromaccount” “toaccount” amount ( minconf “comment” )</li><li>removeprunedfunds “txid”</li><li>rescanblockchain (“start_height”) (“stop_height”)</li><li>sendfrom “fromaccount” “toaddress” amount ( minconf “comment””comment_to” )</li><li>sendmany “fromaccount” {“address”:amount,…} ( minconf “comment” [“address”,…] replaceable conf_target “estimate_mode”)</li><li>sendtoaddress “address” amount ( “comment” “comment_to” subtractfeefromamount replaceable conf_target “estimate_mode”)</li><li>setaccount “address” “account”</li><li>settxfee amount</li><li>signmessage “address” “message”</li><li>walletlock</li><li>walletpassphrase “passphrase” timeout</li><li>walletpassphrasechange “oldpassphrase” “newpassphrase</li></ul></li></ol>]]></content>
<categories>
<category> 区块链 </category>
</categories>
<tags>
<tag> 比特币 </tag>
</tags>
</entry>
<entry>
<title>比特币及区块链中常见问题</title>
<link href="/posts/6a013406.html"/>
<url>/posts/6a013406.html</url>
<content type="html"><![CDATA[<h2 id="⽐特币及区块链中常⻅问题"><a href="#⽐特币及区块链中常⻅问题" class="headerlink" title="⽐特币及区块链中常⻅问题"></a>⽐特币及区块链中常⻅问题</h2><h4 id="一、⽐特币挖矿相关问题"><a href="#一、⽐特币挖矿相关问题" class="headerlink" title="一、⽐特币挖矿相关问题"></a>一、⽐特币挖矿相关问题</h4><ol><li>比特币节点<ul><li>运行区块链软件的计算机就是一个节点<ul><li>每个比特币钱包都是一个节点</li></ul></li><li>全节点<ul><li>拥有完整区块链账本的节点叫做全节点,负责比特币转账交易的广播和验证</li><li>同步整个区块链并对交易做验证,同时中继区块的在网络上的传播</li></ul></li><li>轻节点<ul><li>不挖矿,只进行比特币交易的普通节点</li></ul></li><li>挖矿节点<ul><li>带挖矿功能的全节点</li><li>转账交易发生后由所有节点共同广播至全网,挖矿节点验证该交易正确后会记录至区块链账本</li><li>挖矿节点一般就是记账节点</li></ul></li><li>因为不需要安装全节点也可以进行比特币转账,所以比特币全节点个数只占全部节点数的一小部分。目前比特币网络中大约有500万节点,其中全节点有1万多。</li></ul></li></ol><ol start="2"><li><p>挖矿、矿工、矿机、矿场、矿池:</p><ul><li><p>挖矿是在争取记账权,将一段时间内比特币系统中发生的交易进行确认,并记录在区块链上的过程。</p><ul><li>挖矿就是⼤⼀个猜数字游戏,谁先猜出来谁就是挖矿成功。</li><li>挖矿实际就是矿工之间比拼算力,拥有较大算力的矿工挖到比特币的概率更大。</li><li>挖矿需要矿机、比特币地址、挖矿软件。</li><li>比特币挖矿软件,分配好每台矿机的任务就可以挖矿了。</li><li>每种代币的算法不同,所需的矿机各不相同。</li></ul></li><li><p>矿工:从事虚拟货币挖掘的人就是比特币矿工。</p><ul><li>矿工的主要工作是交易确认和数据打包。</li><li>实际挖矿不需要矿工实际动手,由电脑执行特定运算,只要保证电力供应和网络连接就可以了。</li></ul></li><li><p>矿机:矿机就是通过大量计算来争夺记账权的专业设备,通过争夺记账权获得比特币奖励。</p><ul><li>矿机由挖矿芯片、散热片、风扇组成。</li><li>只执行单一的计算程序,耗电量很大</li></ul></li><li><p>矿场:矿机集中起来形成矿场和矿池。矿场只负责计算。</p></li><li><p>矿池:参与挖矿的人数越来越多,全网算力上涨,挖矿难度持续上涨,单个设备或少量算力都是很难再挖到比特币,这时矿池诞生了。很多矿工加入矿池一起挖矿。</p><ul><li><p>矿池突破地理位置限制,将分散在全球的矿工及矿场的算力连接到一起挖矿。</p></li><li><p>矿池负责信息打包,接入到矿池的矿场负责计算,竞争记账权。</p></li><li><p>挖到比特币后,矿池根据矿场的算力占比分配收益,以此保证更稳定的投入产出。</p></li><li><p>矿池算力越大,挖到比特币的概率就更高。</p></li><li><p>全球算力较大的矿池:【前四名全在中国】</p><p>■鱼池 F2Pool</p><p>■蚊池 AntPool</p><p>■国池 btcc.com</p><p>■币网 bw.com</p><p>■ BitFury (BitFury Group 2011年创立于俄罗 斯,在旧金山和阿姆斯特丹设有管理部门,在冰岛和格鲁吉亚共和国设有数据中心。BitFury早期是一个ASIC比特币矿机芯片研发团队,现在转型做区块链基础数据服务和交易处理服务。)</p></li></ul><p><img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwsob1ekt2j20z60po4qq.jpg" alt="1541062946968"></p></li></ul></li></ol><ol start="3"><li><p>挖矿设备</p><ul><li>CPU挖矿</li><li>GPU挖矿:2010年9月18日,第一个显卡挖矿软件发布,一张显卡等于几十张CPU;</li><li>专业矿机挖矿:蚂蚊矿机=30000张GPU;</li><li>矿场挖矿</li><li>矿池挖矿</li><li>算力(计算能力)。目前主流的矿机为14T左右的计算量级。即一台矿机就能每秒做 至少1.4*10的13次方次hash碰撞。一台14T的矿机就有14T的算力。</li></ul><p><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwsojbt2cwj20nu0ddaqr.jpg" alt="1541063722088"></p><p><img src="http://wx4.sinaimg.cn/large/e64a4785gy1fwsok8ufo4j20gq0dp44f.jpg" alt="1541063789327"></p></li></ol><p><img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwsoli4w7ej20vy0i27wh.jpg" alt="1541063850130"></p><ol start="4"><li>⽐比特币挖矿奖励机制<ul><li>北京时间2009年1月4日 2G15G05 AM(英国时间约2009年1月3日18G15G05 PM) 比特币的第一个区块,这就是创世区块产生。中本聪获得了第一批50个比特币。</li><li>挖矿奖励⽐特币数并不是固定的,每产⽣21万个区块奖励就减半。</li><li>⽐特币区块的产⽣⼤约是10分钟,每产⽣21万个区块⼤约就需要4年。因此每四年挖矿奖励减半。</li><li>从0号到第209999号区块的奖励都是50BTC,从21万号到419999号区块的奖励都是25BTC,从第42万个开始奖励是12.5BTC。截⽌到⽬前每挖到⼀个区块奖励为12.5个⽐特币。</li><li>⽐特币总量被限定为2100万,⽐特币刚诞⽣时,挖矿奖励为50个⽐特币。当总量达到1050万(1050=2100<em>50%)时,奖励减半为25个。当总量达到1575万(即⼜产⽣525万,525=1050</em>50%),奖励减半为12.5个。</li></ul></li></ol><ol start="5"><li>哈希算法<ul><li>Hash算法是现代密码体系中的一个重要组成部分,主要用于信息安全领域中加密算法。</li><li>Hash算法是一种只能加密不能解密的算法,可以将任意长度的信息转成杂乱的固定长度的字符串,叫做Hash值,又称”数字摘要”、“消息摘要” (Message Digest)或“杂凑字符串”。</li><li>也可以说,hash就是找到一种数据内容和数据存放地址之间的映射关系。由于非对称算法的运算速度较慢,所以在数字签名协议中,哈希函数扮演了一个重要的角色而被用于数字签名。</li><li>著名的hash算法有MD5和SHA-1(Secure Hash Algorithm,安全Hash算法),是应用最广泛的Hash算法,而它们都是以MD4为基础设计的。由于MD5及SHA-1的安全受到质疑,比特币系统中使用SHA-256。</li><li>哈希算法具有以下两个特点:<ul><li>输入值只要改变一点,输出的hash值会天差地别。因此只有完全一样的输入值才能达到完全一样的输出值;</li><li>输入值和输出值之间没有规律,所以不能通过输出值反推出输入值。</li></ul></li></ul></li></ol><ol start="6"><li>难度、难度目标、难度重定<ul><li>难度 Difficulty:<ul><li>整个网络会通过调整“难度”这个变量来控制生成工作量证明所需要的计算力。</li><li>随着难度增加,矿工通常在循环便利4亿次随机数值后仍未找到区块,则会启用超额随机数。</li></ul></li><li>难度目标Bits:<ul><li>使整个网络的计算力大致每10分钟产生一个区块所需要的难度数值即为难度目标。</li><li>Bits是用来存储难度目标的16进制数值。</li><li>例如516532块:<ul><li>Bits = “0x17502ab7”</li><li>coefficient系数,coefficient = 0x502ab7</li><li>exponent^旨数,exponent = 0x17</li><li>target = coefficient <em> Math.pow(2, 8 </em> (exponent - 3))</li><li>目标hash:000000000000000000502ab700000000d6420b16625d309c4561290000000000</li><li>实际hash:00000000000000000041ff1cfc5f15f929c1a45d262f88e4db83680d90658c0c</li><li>Bits值越小,难度越大,越难挖矿。</li><li>目前挖比特币的难度,相当于1亿个骰子扔出小于1亿零50的数字,谁先扔出来,谁就获得记账权。</li></ul></li></ul></li><li>难度重定:<ul><li>为了保证各个节点信息同步,新区块产⽣速度不能太快,系统设定为10分钟产⽣⼀个区块。为了保证正好10分钟产⽣⼀个区块,设计了难度⽬标(bits)来动态调整。</li><li>全⽹中每新增2016个区块,全⽹难度将重新计算,该新难度值将依据前2016个区块的哈希算⼒⽽定。</li><li>按每10分钟产⽣⼀个区块的速度计算,每产⽣2016个区块⼤约需要14天,也就是两周。</li><li>每两周调整⼀次难度⽬标(每产⽣2016个区块)。<img src="http://wx3.sinaimg.cn/large/e64a4785gy1fwttqg9jpyj20l30bv40b.jpg" alt="1541144145291"></li></ul></li></ul></li></ol><ol start="7"><li><p>区块结构</p><ul><li>区块包括:区块头、区块体</li><li>区块体记载了交易详情、交易计数器、区块大小</li><li><p>区块头:是每个区块的前80个字节(640bits)。包含6部分信息</p></li><li><p>Version版本号,占4字节</p></li><li>前一个区块的hash,占32字节</li><li>本区块所有交易的默克尔根,占32字节</li><li>时间戳,占4字节<ul><li>比特币是P2P网络,没有中心服务器,每个节点的时间戳有可能不一样。因此比特币系统规定:1、新区块时间戳要大于前11个区块平均时间戳;2、不超过当前网络时间2个小时。</li><li>所以后一个区块时间戳比前一个区块的时间戳反而小也是有可能的。</li></ul></li><li>难度目标Bits,占4字节</li><li>随机数Nonce,占4字节。<ul><li>Nonce是全网矿工计算当前区块hash值的核心参数。</li><li>Nonce的取值范围是0-2的32次方(42亿)</li></ul></li></ul></li></ol><ol start="8"><li><p>默克尔树及默克尔根</p><ul><li><p>Merkle Tree,通常也被称作Hash Tree,顾名思义,就是存储hash值的一棵树;</p></li><li><p>每条交易信息都具有hash值,将所有交易按照手续费高低排序,第一笔交易是挖矿所得的coinbase交易。挖矿系统将该区块能容纳下的所有交易信息打包,两两hash。如果出现奇数,则复制自身然后hash;</p></li><li><p>Coinbase交易是每个区块中的第一个交易,该交易是由矿工创建的,交易内容是系统奖励给矿工的比特币;</p></li><li><p>生成一棵完整的Merkle树需要递归地对哈希节点对进行哈希,并将新生成的哈希节点插入到Merkle树中,直到只剩一个哈希节点,该节点就是Merkle树的根;</p></li><li><p>区块链的区块头必须包含区块中所有交易哈希计算得到的有效默克尔根。而该值也是挖矿非常重要的参数。</p><p><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwspcgrf3dj20v40hb44f.jpg" alt="1541065409128"></p><pre><code> ![1541144219488](http://ws2.sinaimg.cn/large/e64a4785gy1fwttr2938pj20ee08umy5.jpg)</code></pre></li><li><p>以98901为例:</p><p>第⼀笔hash:16f0eb42cb4d9c2374b2cb1de4008162c06fdd8f1c18357f0c849eb423672f5f</p><p>⼤⼩端转换为:<br>5f2f6723b49e840c7f35181c8fdd6fc0628100e41dcbb274239c4dcb42ebf016</p><p>第⼆笔hash:<br>cce2f95fc282b3f2bc956f61d6924f73d658a1fdbc71027dd40b06c15822e061<br>⼤⼩端转换为:<br>61e02258c1060bd47d0271bcfda158d6734f92d6616f95bcf2b382c25ff9e2cc<br>将两个拼接在⼀起:<br>5f2f6723b49e840c7f35181c8fdd6fc0628100e41dcbb274239c4dcb42ebf01661e02258c1060bd47d0271bcfda158d6734f92d6616f95bcf2b382c25ff9e2cc<br>将上⾯拼接的字符串进⾏两次hash如下:</p><p>第⼀次hash结果:<br>9b2ec096d49fee8b310752082d63d8fe198386ae2172d90533d9186bb28df63d<br>将上⾯计算出的hash值再次进⾏hash:<br>525894ddd0891b36c5ff8658e2a978d615b35ce6dedb5cb83f2420dbcd40a0c7<br>⼤⼩端转换即为结果:<br>c7a040cddb20243fb85cdbdee65cb315d678a9e25886ffc5361b89d0dd945852</p></li></ul></li></ol><ol start="9"><li><p>挖矿原理(详⻅⽐特币PoW共识算法)</p><ul><li><p>挖矿的过程就是重复计算区块头的hash, 不断修改随机数Nonce,直到小于难度目标Bits计算出来的hash。<img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwttsf6q7fj20is0m00x9.jpg" alt="1541144730591"></p></li><li><p>以125552区块为例,模拟一个验证挖矿的过程:</p><ul><li><p>将区块头中六个参数以十六进制的小端结尾方式连接在一起</p></li><li><p>版本号:00000001 version = “O1OOOOOO”</p></li><li><p>上一块的hash:00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81</p></li><li><p>pre_hash = “81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a30 8000000000000”</p></li><li><p>merkle根:2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3</p></li><li><p>merkle_root = e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b</p></li><li><p>时间戳:1305998791(May 22, 2011 1:26:31 AM,转成16进制为:4dd7f5c7)timeStamp = “c7f5d74d”</p></li><li><p>难度目标Bits:1a44b9f2 bits = Nf2b9441a”</p></li><li><p>Nonce:2504433986, 10进制转16进制为:9546a142 ■ nonce = ,,42a14695H</p></li><li><p>header_hex = version + pre_hash + merkle_root + timeStamp + bits + nonce</p></li><li><p>经过两次hash256算法以及转码,能得出以下结果:1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e000 0000000000000</p></li><li><p>将十六进制的大小端颠倒顺序,得出以下结果:00000000000000001e8d6829a8a21adc5d38d0a473b144b676 5798e61f98bd1d</p></li><li><p>高度为125552的区块目标hash为:00000000000044b9f1fffffffeb42e33d248e71469a7653bb7d68 00000000000</p></li><li><p>比对大小:实际计算的hash值 < 目标hash,所以验证成功。</p><p>【备注】</p><p>区块链浏览器中16进制数字显示为⼤头端表示的数值,数字⾸部是最⼤的数字,从左向右读。区块中则以⼩头端存储,即⼩头位序(⾼位在后)。在计算机中数字通常⽤⼩头位序的形式表示。 这就是⼩端格式编码。</p></li></ul></li></ul></li></ol><ol start="10"><li><p>区块链的本质是什么?</p><ul><li>区块链是一组使用密码学算法产生的区块,每个区块按时间顺序依次相连,形成链状结构,得名区块链;</li><li><p>区块链可以理解成是一个类似电子表格的数据结构,通过互联网定时在成千上万台节点计算机上进行复制和更新。这种数据结构消除了单个实体集中掌握数据带来的风险;</p></li><li><p>区块链本质上是一个应用了密码学技术的,多方参与、共同维护、持续增长的分布式数据库系统,也称为分布式共享账本。共享账本中的每一个账页就是一个区块,每一个区块写满了交易记录,区块首尾衔接,紧密相连, 形成链状结构;</p></li><li>区块链数据由所有节点共同维护,每个参与维护的节点都能获得一份完整的数据拷贝。所有节点共同维护一条不断增长的链,只能添加记录,不可删除、不可篡改记录;</li><li>区块链是制作信任的技术;<ul><li>区块链具有匿名性、去中心化、公开透明、不可篡改等特点。区块链被誉为制造信用的机器;</li><li>区块链本质上解决了信任和价值传递。这种强信任背书的情况下,任何人没有能力,也没有必要质疑数据的质量和真实性。</li></ul></li></ul></li></ol><ol start="11"><li><p>⽐特币私钥、公钥、⽐特币地址的⻓度?</p><ul><li>私钥⻓度<ul><li>256位⼆进制数字</li><li>64位16进制数字</li><li>WIF格式私钥。以5开头,51位Base58编码</li><li>WIF-compressed格式。以L或K开头,52位Base58编码。增加“01”作为压缩标识。</li></ul></li><li><p>公钥⻓度:</p><ul><li>130位16进制数字——⾮压缩公钥(以“04”开头)</li><li>66位16进制数字——压缩公钥(以“03、02”开头)</li></ul></li><li><p>⽐特币地址⻓度</p><ul><li>⽐特币地址⻓度</li><li>正式⽹络以“1、3”开头,测试⽹络以“2”开头。</li></ul></li></ul></li></ol><h4 id="二、⽐特币交易相关问题"><a href="#二、⽐特币交易相关问题" class="headerlink" title="二、⽐特币交易相关问题"></a>二、⽐特币交易相关问题</h4><ol><li><p>比特币网络:</p><ul><li>是一个由若干节点组成的用以广播交易信息和数据区块的P2P网络。</li></ul></li><li><p>交易(比特币转账)</p><ul><li>简单地说,交易就是把比特币从一个地址转到另一个地址。更准确地说,一笔“交易”指一个经过签名运算的,表达价值转移的数据结构。</li><li>比特币交易本质上是在传递比特币所有权,这就是价值传递。</li><li>每一笔“交易”都经过比特币网络传输,由矿工节点收集并打包进区块中,永久保存在区块链中。</li><li>比特币转账交易通过比特币交易平台、比特币地址、比特币客户端操作。</li></ul></li><li><p>非对称加密(公开密钥加密)</p><ul><li>公开密钥加密(英语:Public-key cryptography),也称为非对称加密(英语:asymmetric cryptography),是密码学的一种算法。</li><li>非对称加密发展史<ul><li>1976年,惠特菲尔德•迪菲(Whitfield Diffie)与马丁•赫尔曼(Martin Hellman)斯坦福的两位学者提出了密码交换算法,也就是DH算法。</li><li>1978年,MIT(Massachusetts Institute of Technology,麻州理工大 学)的Rivest、Shmir和Adleman发表了RSA (三位发明者姓氏首字母缩写)算法,这是最著名的公开秘钥加密算法。三位教授也因此荣获2002年图灵奖。</li><li>常见的公钥加密算法有:迪菲-赫尔曼密钥交换协议中的公钥加密算 法、RSA算法、椭圆曲线加密算法(Elliptic Curve Cryptography,ECC)、EIGamal。使用最广泛的是RSA算法,EIGamal是另一种常用的非对称加密算法。</li></ul></li><li>非对称加密,就是加密和解密需要两把钥匙:一把公钥和一把私钥。由于加密和解密需要两个不同的密钥,故被称为非对称加密。</li><li>公钥和私钥两把钥匙中,如果一个用作加密,则另一个就用作解密。使用其中一个密钥把明文加密后所得的密文,只能用相对应的另一个密钥才能解 密得到原本的明文;甚至连最初用来加密的密钥也不能用作解密。</li><li>不同于加密和解密都使用同一个密钥的对称加密。</li><li>对称加密算法(data encryption algorithm, DEA),也叫做私钥加密算法。是加密和解密使用相同密钥的加密算法。也叫做单密钥算法,传统密钥算法。</li><li><img src="http://wx4.sinaimg.cn/large/e64a4785gy1fwtn6f9hsfj213g0bn7c8.jpg" alt="1541135651773"></li><li><p>虽然两个密钥在数学上相关,但如果知道了其中一个,并不能凭此计算出另外一个。因此其中一个可以公开,称为公钥,任意向外发布;不公开的密钥为私钥,必须由用户自行严格秘密保管,绝不能通过任何途 径向任何人提供。</p></li><li><p>他人使用你的公钥加密信息,然后发送给你,你用私钥解密,取出信息;</p></li><li><p>反过来,你用私钥加密信息,别人用你的公钥解开,从而证明这个信息确实是你发出的,且未被篡改,这叫做数字签名。</p></li><li><p>比特币保证支付可靠性的原理就是非对称加密</p><ul><li>别人用你的公钥加密一笔钱发送给你,你用该公钥对应的私钥解密后就能收到钱。而别人没有私钥就没有办法收到钱;</li><li>你用私钥做了一个数字签名,别人用你的公钥能验证该签名是否属于你;</li><li>由于支付的钱必须通过私钥才能使用,所以你是谁并不重要,重要的是谁拥有私钥。只有拥有了私钥,才能取出支付给你的钱;</li><li>事实上,私钥保证的不是取出支付给你的钱,而是保证只有你能把这些属于你的钱支付出去。<img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwttt9dtt7j20eo07s0up.jpg" alt="1541145956736"></li></ul></li></ul></li><li><p>比特币钱包</p><ul><li><p>比特币钱包指保存比特币地址和私钥的软件,可以用它来接受、发送、储存你的比特币。</p></li><li><p>换句话说钱包就是私钥、比特币地址和区块链数据的管理工具。比特币钱包的核心功能就是保护私钥。如果私钥丢失,将永远失去这笔比特币。</p></li><li><p>比特币地址如同银行卡卡号,私钥类似于银行卡密码,钱包里可以存放多张银行卡。比特币钱包里可以存储多个比特币地址以及每个比特币地址所对应的唯一的私钥。</p></li><li><p>大多数比特币钱包为了方便,大多是将私钥、公钥以密码对的形式储存在一起。但是公钥可以由私钥计算出,所以只储存私钥也是可以的。</p></li><li><p>比特币钱包有多种形态:PC钱包、手机钱包、在线网页钱包、纸钱包、月茵钱包等等。采用多种方式分散存储是降低风险的有效方式。</p><ul><li>纸钱包:人们通常使用该术语来表达以物理文件形式离线存储比特币私钥的方式。</li><li>硬件钱包:硬件钱包是一种特殊的比特币钱包,硬件钱包可以将用户的私钥存储在安全的硬件设备中。类似于银行加密狗。</li><li>脑钱包:脑钱包顾名思义,即存在于脑海中的比特币钱包。它其实是一种比特币私钥的生成方式,通过对用户的输入进行计算生成相应的比特币地址。让你只需要记住一个密码,便可以用这个密码在脑钱包程序中恢复比特币地址和私钥。<img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwtttmgddlj20l009gae6.jpg" alt="1541146002543"></li></ul></li></ul></li><li><p>冷钱包和热钱包</p><ul><li>按私钥存储方式分:冷钱包和热钱包</li><li>冷钱包:指网络不能访问到私钥的钱包。冷钱包往往依靠冷设备确保比特币私钥的安全。比如不联网的电脑、手机,写着私钥的本子等。冷钱包避免了被黑客盗取私钥的风险,但是可能面临物理安全风险,比如电脑丢失损坏或数据损坏。另外冷钱包无法直接发送交易,便利性差。</li><li>热钱包:是互联网能访问到私钥的钱包。往往是在线钱包的形式。使用热钱包最好在不同的平台设备上设置不同密码,且开启二次认证,以确保资产安全。</li><li>无论是冷钱包还是热钱包,只要被知道私钥,就能被转走比特币。所以谁手握私钥谁才是比特币真正的主人。<img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwtttubevgj208j06awfh.jpg" alt="1541146017612"></li></ul></li><li><p>全节点钱包、轻钱包</p><ul><li>根据区块链数据的维护方式,将钱包分为全节点钱包、轻钱包及中心化钱包。</li><li>bitcoin-core:核心钱包,需要同步所有区块链数据,占用很大的存储空间,但是可以完全实现去中心化;</li><li>轻钱包:依赖比特币网络上其他全节点,仅仅同步与自己相关的数据,基本可以实现去中心化;</li><li>中心化钱包:不依赖比特币网络,所有的数据均从自己注册的第三方中心化服务器中获得。交易效率很高,可以实时到账。用户在交易平台注册的账号就是中心化钱包。该种钱包不是P2P交易,实际上是在与注册的第三方交易平台在做交易。</li></ul></li><li><p>HD钱包(hierarchy deterministic wallet,分级确定性钱包)</p><ul><li><p>根据密钥关联性分类,钱包分为非确定性钱包和确定性钱包两种。区别在于它们包含的多个密钥是否相互关联。</p></li><li><p>第一种类型是非确定性钱包(nondeterministic wallet),其中每个密 钥都是从随机数独立生成的。密钥彼此无关。这种钱包也被称为“Just a Bunch Of Keys (一堆密钥)”,简称JBOK钱包。</p><ul><li>在最早的一批比特币客户端中(Bitcoin Core,现在称作比特币核心客户端),钱包只是随机生成的私钥集合。这种类型的钱包被称作零型非确定钱包。现在零型钱包不建议使用。</li><li>非确定性钱包现在正在被确定性钱包替换,因为它们难以管理、备份以及导入。随机密钥的缺点就是如果你生成很多私钥,你必须保存它们所有的副本。这就意味着这个钱包必须被经常性备份。每一个密钥都必须备份,否则一旦钱包不可访问时,钱包所控制的资金就付之东流。</li><li>⾮确定性钱包除了简单的测试之外,不要使⽤。 现在推荐使⽤基于⾏业标准的HD钱包,可以⽤种⼦助记词进⾏备份。</li></ul></li><li><p>第二种类型是确定性钱包(deterministic wallet),其中所有的密钥都 是从一个主密钥派生出来,这个主密钥即为种子(seed)。</p><ul><li>该类型钱包中所有密钥都相互关联,如果有原始种子,则可以再次生成全部密钥。确定性钱包中使用了许多不同的密钥推导方法。最常用的推导方法是使用树状结构,称为分级确定性钱包或HD钱包。</li><li>确定性钱包由种子衍生创造。为了便于使用,种子被编码为英文单词,也称为助记词。</li><li>HD钱包种子或根种子是一个用于为HD钱包生成主私钥和主链码所需种子的潜在简短数值。</li></ul><p>【附:HD钱包五层路径】</p><p>1)、钱包根据不同的⻆度有多种分类名称。其中⼀种是按照私钥间关联⽽划分的。分为确定性钱包和⾮确定性钱包。2)、⾮确定性钱包是早期BitcoinQT时的钱包类型,仅仅是随机⽣成的私钥的集合。很难管理和备份。</p><p>3)、2012年,BIP32提出了分级确定性钱包的意⻅。2016年合并到了BitcoinCore核⼼钱包中。所有密钥相互关联,由原始种⼦哈希后⽣成主私钥,主私钥可以派⽣海量的⼦私钥。密钥推导⽅法有很多种,最常⻅的推导⽅法是树状结构推导法,这样就形式了树状的分级确定性钱包,这就是HD钱包。</p><p>【hierarchy deterministic wallet 分级确定性钱包】4)、种⼦是⼀串很⻓的随机数,不要记忆,所以⽤算法将种⼦转化为⼀串助记词(mnemonic)。</p><p>BIP39扩展了HD钱包种⼦的⽣成算法。</p><p>5)、BIP43对BIP32的树状结构增加了⼦索引标识purpose的扩展m/purpose’/*</p><p>6)、BIP44在BIP43和BIP32的基础上增加了多币种,这样就可以同时管理主⽹和测试⽹的⽐特币。于是形成了5层路径建议。m/purpose/coin_type/account/change/address_index是BIP44中提出的五层路径。</p><p>7)、BIP44规则使HD钱包功能⾮常强⼤,⽤户只需要保存助记词,就能控制控制所有币种每个⽐特币地址的私钥。</p></li></ul></li><li><p>比特币钱包随机生成私钥的安全性</p><ul><li><p>每个用户的私钥是由比特币钱包随机生成的。可能有人会有疑问,这样随机生成的私钥安不安全,会不会我随机生成私钥跟别人的私钥恰好重复了?这个你不用过于担心,因为,比特币私钥是一串很长的文本,理论上比特币私钥的总数是:1461501637330902918203684832716283019655932542976 <img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwttu8svxoj20wg07ctay.jpg" alt="1541146344248">这是个什么概念?地球上的沙子是7.5乘以10的18次方,然后你想象一下,每粒沙子又是一个地球,这时的沙子总数是56.25乘以10的36次方,仍然远小于比特币私钥的总数。所以在这样一个庞大的地址空间下,私钥重复的概率微乎其微。 <img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwttupj0nfj20se0nmwmp.jpg" alt="1541146392742"></p><p>10的80次⽅:当前⼈类可⻅宇宙中所有原⼦数⽬的总和。</p></li><li><p>私钥的格式</p><ul><li><p>原始私钥是32字节,也就是256位2进制数字,换算成16进制数字就是64位长度;</p></li><li><p>私钥有16进制格式、WIF格式(Wallet Import Format,钱包导入格 式)、WIF-compressed格式(压缩的钱包导入格式);</p></li><li><p>WIF格式经过Base58check编码并以5作为前缀的51位数字和字母。例$D5J76sF8L5jTtzE96r66Sf8cka9y44wdpJjMwCxR3tzLh3ibVPxho</p></li><li><p>WIF-compressed格式同样经过Base58Check编码并以K或L字母为前缀。私钥常常以WIF-compressed格式来展示,展示为以K或L开始的52位长度的数字和字母。<img src="http://wx4.sinaimg.cn/large/e64a4785gy1fwttv7z6pnj20yg0a4dih.jpg" alt="1541146441687"></p><p><img src="http://wx4.sinaimg.cn/large/e64a4785gy1fwttvmbspmj20xo08h76q.jpg" alt="1541146471724"></p></li></ul></li></ul></li><li><p>椭圆曲线算法(ECC,Elliptic Curve Cryptography)</p><ul><li>椭圆曲线算法是不可逆的,很容易向一个方向计算,但是不可以向相反方向倒推。</li><li>比特币使用SECP256K1算法(椭圆曲线算法的一种),将私钥生成公钥。</li><li>SECP256K1是不可逆的,因此公钥公开暴露,也对私钥的安全性不会造成影响。</li></ul></li><li><p>Base64、Base58编码及解码</p><ul><li><p>Base64就是一种基于64个可打印字符来表示二进制数据的方法</p></li><li><p>Base64字符集:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234 56789+/</p></li><li><p>Base58是用于Bitcoin中使用的一种独特的编码方式,主要用于产生Bitcoin的钱包地址。</p></li><li><p>相比Base64, Base58不使用数字”0”,大写字母”0”,大写字母T和小写字母”I”,以及”+”和符号。目的就是去除容易混淆的字符。</p></li><li><p>Base58字符集:ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz123456789</p></li></ul><p><img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwtn3hcydmj20yp0me11f.jpg" alt="1541135465831"></p></li><li><p>Base58Check是什么?</p><ul><li><p>Base58Check就是在对数据进行Base58编码前增加了校验码,因为增加了校验码这个环节,且用到了Base58编码,所以叫做Base58Check。</p></li><li><p>在生成比特币地址以及生成WIF-compressed格式私钥的过程中都用到了Base58Check。</p></li><li><p>既然有了Base58编码,已经不会搞错0和0,1和I和I,也把大整数转换成了可读字符串,为什么还要再有Base58Check这个环节呢?</p></li><li><p>假设一种情况,你在程序中输入一个Base58编码的地址,尽管你已经不会搞错0和0,1和I和I,但是万一你不小心输错一个字符,或者少写多写一个字符,会昨样?你可能会说,没啥大不了的,错个字符而已,这不是很常见嘛,重新输入不就可以了吗?但是当用户给一个比特币地址转账,如果输入 错误,那么对方就不会收到资金,更关键的是该笔资金发给了一个根本不存 在的比特币地址,那么这笔资金也就永远不可能被交易,也就是说比特币丢失了。</p></li><li><p>使用Base58check编码格式时,程序会计算原始数据的校验码并和自带的校验码进行对比,二者若不匹配则表明有错误产生。</p></li><li><p>实际上,在比特币交易中,都会校验比特币地址是否合法,如果经过Base58Check的比特币地址被比特币钱包程序判定是无效的,当然会阻止交 易继续进行,就避免了资金损失。</p></li><li><p>比特币地址生成过程中的Base58Check的步骤如下:</p><ul><li>获取到公钥(130位16进制数值,65字节长度)</li><li>计算公钥的SHA-256哈希值(对公钥进行第一次hash256运算)</li><li>计算RIPEMD-160哈希值(对第一次hash256的结果进行ripeMD160运算)</li><li>添加版本前缀(将ripeMD160运算的结果前增加版本编号)</li><li>计算两次hash(对加上版本编号的hash值计算两次hash)</li><li>获取校验码(获取两次hash后前四个字节,作为校验码)</li><li>形成比特币地址的16进制格式(将校验码作为比特币地址的后缀,与添加版本前缀的hash值拼接)</li><li>进行Base58编码处理(对比特币地址的16进制格式进行Base58编 码,就形成了比特币地址)</li></ul><p><img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwtkwp3hh7j213e0whdso.jpg" alt="1541130876573"></p></li></ul></li><li><p>比特币地址</p><ul><li><p>可以通过以下网站生成比特币地址:<a href="https://www.bitaddress.org/" rel="external nofollow noopener noreferrer" target="_blank">https://www.bitaddress.org/</a></p></li><li><p>比特币地址(例女口:1DSrfJdB2AnWaFNgSbv3MZC2m74996JafV)是26 至34位数字和字母组成的字符串。</p></li><li><p>比特币地址是个人的比特币账户,相当于银行卡的卡号。通过比特币钱包 或在交易平台上注册,每个比特币地址都是独一无二,有地址就可以进行比 特币转账。就像别人向你的email地址发送电子邮件一样,他可以通过你的比特币地址向你发送比特币。</p></li><li><p>比特币地址其实是通过对160位二进制公钥哈希值,再进行base58check编码后的得到数据。</p><ul><li>公钥先经过SHA256计算,再经过RIPEMD160算法;</li><li>再进行Base58Check编码。</li><li>由公钥生成的比特币地址以”1”开头。<img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwttw6bgldj20fu09f0ti.jpg" alt="1541146532262"></li></ul></li></ul></li><li><p>私钥、公钥、比特币地址之间的关系</p><p><img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwttwhbdj7j21900bgtey.jpg" alt="1541146554397"></p></li></ol><p><img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwttwr13fpj20630akt93.jpg" alt="1541146582218"></p><ol start="14"><li>数字签名<ul><li>只有转账人才能生成的一段防伪造的字符串。通过验证该字符串,一方面证明该交易是转出方本人发起的,另一方面证明交易信息在传输过程中没有被更改。</li><li>数字签名由:数字摘要和非对称加密技术组成。<ul><li>数字摘要把交易信息hash成固定长度的字符串;</li><li>再用私钥对hash后的交易信息进行加密形成数字签名。</li></ul></li><li>交易中,需要将完整的交易信息和数字签名一起广播给矿工。<ul><li>矿工节点用转账人公钥对签名验证,验证成功说明该交易确实是转账人发起的;</li><li>矿工节点将交易信息进行hash后与签名中的交易信息摘要进行比对,如果一致,则说明交易信息在传输过程中没有被篡改。</li></ul></li><li>比特币系统主要用了ECDSA,也就是椭圆曲线签名算法。<img src="http://ws4.sinaimg.cn/large/e64a4785gy1fwttx43rfaj20s00m6gs1.jpg" alt="1541146715847"></li></ul></li></ol><ol start="15"><li><p>UTXO(unspent transaction outputs,未花费的交易输出)</p><ul><li>用户比特余额是用户钱包中可用的UTXO的总和。他们可能分布在数百个交易和区块中。</li><li>这些UTXO由用户所有的密钥来控制花费行为。UTXO的面值为聪,是不可分割的价值单元,一个UTXO只能在一次交易中作为整体被消耗。</li><li>也就是说每个比特币地址对应的UTXO,在交易过程中如同一张纸币一样(面额就是该比特币地址上的金额),不可以撕开使用,必须是作为一个整体来交易。</li><li>未被交易的交易索引:检查i叩uts中的交易的txn是否在未被支付交易索引中即可。</li></ul></li></ol><ol start="16"><li><p>发出交易到矿工打包需要几步?</p><ul><li>发起比特币转账,将交易广播到全网;</li><li>挖矿节点接到交易后先将其放入本地内存池,进行一些基本验证,判断是否属于UTXO。如果通过验证,则将该笔交易放入未确认交易池,等待被打包;如果未通过验证,则被认为是无效交易,直接废弃,不会被打包。 <ul><li>未确认交易池是所有交易数据的集合,这些交易已经被比特币节点验证,但未被确认。</li></ul></li><li>挖矿节点在比拼算力的同时还需要及时验证每笔交易,更新自己的“未确认 交易池”。矿工挖矿前,将从“未确认交易池”中抽取“未确认交易”进行打包。</li><li>有时交易不能被及时打包,是因为“未确认交易池”中交易太多,每个区块 能记录的交易数有限,就造成区块拥堵。</li></ul></li></ol><ol start="17"><li><p>比特币交易验证过程</p><ul><li>一笔交易就是一个地址的比特币,转移到另一个地址。由于比特币的交易记录全部都是公开的,哪个地址拥有多少比特币,都是可以查到的。因此,支付方是否拥有足够的比特币,完成这笔交易,这是可以轻易验证的。问题 出在怎么防止其他人,冒用你的名义申报交易。</li><li>比特币协议规定,申报交易的时候,除了交易金额,转出比特币的一方还必须提供以下数据。<ul><li>上一笔交易的Hash(你从哪里得到这些比特币)</li><li>本次交易双方的地址</li><li>支付方的公钥</li><li>支付方的私钥生成的数字签名</li></ul></li><li>验证这笔交易是否属实,需要三步。<ul><li>第一步,找到上一笔交易,确认支付方的比特币来源。</li><li>第二步,算出支付方公钥的指纹,确认与支付方的地址一致,从而保证公钥属实。</li><li>第三步,使用公钥去解幵数字签名,保证签名属实、私钥属实。</li><li>经过上面三步,就可以认定这笔交易是真实的。</li></ul></li></ul></li></ol><ol start="18"><li><p>比特币交易的找零机制</p><ul><li>比特币转账可以一次把多个比特币地址的余额转出,也可以一次转入到多个比特币地址。</li><li>余额转回原地址,说明这是找零地址,当然也可以是新的找零地址,也就是存放余额的地址。如果不指定余额地址,那么表示余额全部给矿工当手续费。</li></ul></li></ol><ol start="19"><li><p>双重支付(double spending,双花)</p><ul><li>双重支付是成功支付了 1次以上的情况。比特币通过对添加到区块中的每笔交易进行验证来防止双重支付,确保交易的输入没有被支付过。</li></ul></li><li><p>见证:witness</p><ul><li>密码学术语,用于支出资金的数字签名被称为见证。比特币交易中的见证 数据证明了资金真正归谁所有。</li></ul></li></ol><ol start="21"><li><p>最长链及六次交易确认</p><ul><li>某些特殊的情况下区块链可能分叉,这些情况可能是恶意的双重支付攻 击。也有可能是碰巧在同一时点,地球上两个矿工节点同时计算出了小于目标值的Hash值,并同时发起了组包记账(这种情况发生的概率极低,但确实 曾经发生过)。</li><li>分叉时,比特币系统会自动选择最长的链条,抛弃短的链条。在这种机制下,越新生成的区块约有可能被抛弃,越早生成的区块越稳定、越安全。 </li><li>在比特币网络上,有一条不成文的约定,就是只有你的交易达成并被装入区块后,后面又生成了5个新区块后(加上包含你交易的区块总共6个区块, 因此叫做六次交易确认),你的交易才是基本安全的。以每10分钟生成一个区块的时间来计算,也就是你在交易被确认后1个小时左右才能真正确认你的 交易是可靠的。<img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwttxo59btj20xk0i6dlk.jpg" alt="1541147910144"></li></ul></li></ol><h4 id="三、其他区块链相关问题"><a href="#三、其他区块链相关问题" class="headerlink" title="三、其他区块链相关问题"></a>三、其他区块链相关问题</h4><ol><li><p>中本聪:</p><ul><li>中本聪有可能是一个人或一群人的名字。中本聪是比特币的设计者,同时也创建了比特币的最初实现,比特币核心。作为实现的一部分,他们还发明了第一个区块链数据库。在这个过程中,他们是第一个为数字货币解决了双花问题的人或组织。但他们的真实身份仍然未知。</li><li>中本聪的真实身份⻓期不为外界所知,维基解密创始⼈朱利安·阿桑奇(Julian Assange)宣称中本聪是⼀位密码朋克(Cypherpunk)。另外,有⼈称“中本聪是⼀名⽆政府主义者,他的初衷并不希望数字加密货币被某国政府或中央银⾏控制,⽽是希望其成为全球⾃由流动、不受政府监管和控制的货币。”</li></ul></li><li><p>图灵完备</p><ul><li>图灵完备是对计算能力的描述。图灵完全性通常指具有无限存储能力的通用物理机器或编程语言。</li><li>一个语言是图灵完备的,意味着该语言的计算能力与一个通用图灵机(Universal Turing Machine)相当,换句话说,图灵完备意味着这种编程语言可以做到用图灵机能做到的所有事情。</li><li>一台计算机也是一个图灵机,一个图灵完备的语言能够发挥计算机的所有能力。反之,一个图灵不完备的语言,就意味着不能发挥计算机的所有能力。这个概念也就是图灵等价。</li><li>图灵完备的语言,有循环执行语句,判断分支语句等。理论上能解决所有的可计算问题。但有可能进入死循环而程序崩溃。</li><li>图灵不完备,不允许或限制循环。可以保证每段程序都不会死循环,都有运行完的时候。</li></ul></li><li><p>比特币与图灵完备性</p><ul><li>比特币的脚本系统是图灵不完备的,而其它代币的智能合约系统是图灵完备的。</li><li>比特币脚本语言包含许多操作,但都故意限定为一种重要的方式——没有循环或者复杂流控制功能以外的其他条件的流控制。这样就保证了脚本语言 的图灵非完备性,这意味着脚本的复杂性有限,交易可执行的次数也可预见。脚本并不是一种通用语言,施加的这些限制确保该语言不被用于创造无限循环或其它类型的逻辑炸弹,这样的炸弹可以植入在一笔交易中,通过引 起拒绝服务的方式攻击比特币网络。受限制的语言能防止交易激活机制被人当作薄弱环节而加以利用。</li><li>各有优缺点,图灵不完备会更安全些,图灵完备会更智能些。</li></ul></li><li><p>P2P网络</p><ul><li>Peer to Peer网络。各节点地位对等,无主从之分。去中心化。用户越多速 度越快。抗攻击。</li><li>传统的中心化服务器:CS、BS架构。客户端完全信任服务器。</li><li>会受到DDOS攻击,distributed denial of service分布式拒绝服务攻击</li></ul></li><li><p>LevelDB</p><ul><li>LevelDB是一个开源的键值对数据库。LevelDB是一个用于持久性绑定多个 平台的轻量级、单用途的库。钱包的信息就可以通过LevelDB进行保存。</li><li>mongoDB、SQLite也都是很好的轻量级的数据库存储方式。</li></ul></li><li><p>共识机制</p><ul><li>共识机制是区块链技术的灵魂。</li><li>区块链共识机制的目标是使所有的诚实节点保存一致的区块链数据,同时满足两个性质:一致性和有效性。</li><li>区块链的自信任主要体现在区块链中的用户无须信任交易的另一方,也无须信任一个中心化的机构,只需要信任区块链协议下的软件系统即可实现交易。这种自信任的前提是区块链的共识机制(consensus),即在一个互不信任的市场中,要想使各节点达成一致的充分必要条件是每个节点出于对自 身利益最大化的考虑,都会自发、诚实地遵守协议中预先设定的规则,判断 每一笔记录的真实性,最终将判断为真的记录记入区块链之中。</li><li>换句话说,如果各节点具有各自独立的利益并互相竞争,则这些节点几乎不可能合谋欺骗你,而当节点们在网络中拥有公共信誉时,这一点体现得尤 为明显。区块链技术正是运用一套基于共识的数学算法,在机器之间建立“信 任”网络,从而通过技术背书而非中心化信用机构来进行全新的信用创造。</li><li>区块链支持不同的共识机制。常用的共识机制有工作量证明机制PoW、权益证明机制PoS、股份授权证明机制DPoS等。</li><li>PoW:工作量证明机制,可以叫它“范进中举”。范进用大半辈子学习无用的八股文,如同比特币矿工用算力算题,算的题毫无意义,目的就是为了碰运气,可以有权记录他所打包的交易信息。</li><li>PoS:用户要预先放入一些利益,很像现实世界的股份制。大家用财富兑换成股份,谁的股份大,谁的话语权就大。</li><li>DPoS:像董事会,选举出代表,代表股东的利益。被选出的代表,成熟老练、阅历丰富,能快速地处理日常事务,也能很好地保护股东利益。</li><li>Paxos、Raft、PBFT很像生活中的操练队列,通过互相间的消息口令来达成一致。每排的排头作为Leader,而每排的其余人都以排头为目标。</li></ul></li><li><p>拜占庭将军问题(Byzantine Generals Problem) / 拜占庭容错(Byzantine Fault Tolerance)</p><ul><li>拜占庭将军问题也就是分布式网络一致性问题(Distributed Consensus);</li><li>拜占庭容错是莱斯利.兰伯特(Leslie Lamport)用来描述分布式系统一致性问题时,在论文中抽象出的著名的例子;</li><li>莱斯利.兰伯特是美国计算机科学家,是2013年图灵奖得主;</li><li>拜占庭将军的故事大意:<ul><li>拜占庭(古希腊城市,现今土耳其伊斯坦布尔,旧名叫做君士坦丁堡)。拜占庭帝国,即东罗马帝国。</li><li>拜占庭帝国想进攻一个强大的敌人,派10支军队包围敌人。敌人虽不比拜占庭帝国强大,但是足以抵御5支拜占庭帝国军队同时进攻。这10支 军队分开包围,任何一支单独进攻都毫无胜算,至少需要6支军队同时袭击才能得胜。</li><li>拜占庭帝国的这10支军队分散在敌国四周,依靠通信兵起码相互通信来协商进攻或者撤退。各支军队行动策略限定为进攻或撤退两种。</li><li>问题在于:<ul><li>没有叛徒情况下,一个将军提出进攻提议,其他将军同时发出了不同进攻提议。出于时间差异,不同将军收到并认可的提议就是不同的;</li><li>将军中可能出现叛徒。</li><li>拜占庭将军问题不考虑通信兵是否被截获或无法传递信息等问题,也就是认为消息传递的信道绝无问题。兰伯特已经证明了在消息可能丢失的不可靠通信上,通过消息传递方式达成一致性是不可能的。所以在研究拜占庭将军问题时,已假定信道没有问题。</li></ul></li></ul></li><li>分布式计算中,不同计算机通过通讯交换信息达成共识,从而按照同一套协作策略来行动。但是有时候系统中成员计算机可能出错而发出错误信息,使得网络中不同的成员关于全体协作的策略得出不同的结论,从而就破坏了系统的一致性;</li><li>拜占庭将军问题被认为是容错性问题中最难的问题类型之一。共识算法的核心就是解决拜占庭将军问题。</li><li>解决分布式系统一致性问题主要是兰伯特提出的Paxos算法。但是该算法仅仅适用于中心化的分布式系统,这样的系统中没有不诚实节点。</li><li>1999年,有人提出了PBFT算法(Practical Byzantine Fault Tolerance, 实用的拜占庭容错算法)。<ul><li>叛徒等于或大于三分之一,拜占庭问题无解;</li><li>当叛徒数量不到三分之一,那么忠诚将军就至少有三分之二,此时拜占庭问题有解,仍然可以达到容错。</li></ul></li><li><p>比特币系统通过PoW共识机制巧妙地解决了拜占庭容错问题。</p><ul><li>PoW增加发送信息的成本,降低了节点发送消息的速度,保证一段时间内只有一个节点广播消息,同时在广播上附上签名。这样就解决了因为时间差而导致消息传递不一致的问题;</li><li><p>对于将军做叛徒的问题,比特币系统的解决方案就是,让比特币网络中每个节点没有动机和动力做叛徒。</p><ul><li><p>PoW工作量证明机制提高了做叛徒(发布虚假区块)的成本,在工作量证明下,只有第一个完成证明的节点才能广播区块,竞争难度非常大,需要很高的算力,如果不成功其算力就白白的耗费了(算力是需要成本的),如果有这样的算力作为诚实的节点,可以获得很大的收益(这就是矿工所作的工作),这也实际就不会有做叛徒的动机,整个系统也因此而更稳定。</p></li><li><p>对于51%攻击问题,那更是提高了做叛徒的成本。拥有这么大的算力的,自然就是希望依赖比特币系统而盈利的,当然更不会造假而损坏自身利益。</p></li><li><p>当然很多人批评PoW工作量证明机制造成巨大的电力浪费,促使人们去探索新的解决一致性(共识)问题的机制:权益证明机制(POS: Proof of Stake)是一个代表。在拜占庭将军问题的角度来 看,它同样提高了做叛徒的成本,因为账户需要首先持有大量余额才能有更多的几率广播区块。如果已经拥有这么大的利益,当然更不会造假而损坏自身利益了。</p></li><li><p>总之,理性的人都是逐利的,PoW抑制了节点的恶意动机。<img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwtty8422sj21kw11ch56.jpg" alt="1541148210341"></p><p> <img src="http://wx4.sinaimg.cn/large/e64a4785gy1fwttypobxpj21ka10s4f5.jpg" alt="1541148226578"></p></li></ul></li></ul></li></ul></li><li><p>比特币扩容</p><ul><li>目前比特币区块大小是1M,每秒大约只能处理7笔交易(每笔约250字节,1M空间最多约4200笔交易,每10分钟产出一个区块,则每秒最多处理7个交易)<ul><li>比特币吉尼斯:鱼池找到交易数最大区块363270,包含交易量4509 笔,区块大小恰好1M,平均每笔交易占230字节。</li><li><a href="https://blockchain.info/block/000000000000000010ef3011e77078" rel="external nofollow noopener noreferrer" target="_blank">https://blockchain.info/block/000000000000000010ef3011e77078</a> 522451782c639ea5e22492e086ca9089c3</li></ul></li><li>比特币交易量不断增长,比特币网络已经难以迅速进行转账交易确认。比特币网络出现拥堵,最高时有上万笔交易积压,比特币转账交易费也水涨船 高高达几十美元。拥堵严重时,比特币交易设置需要花费几天才能被打包。所以提出扩容:1、提高区块大小上限;2、拿出区块内无用信息。</li><li>2017年8月,隔离见证激活,比特币单个区块信息处理能力提高至以前的 1.7 倍。</li></ul></li><li><p>隔离见证</p><ul><li>见证witness:用于支出资金的数字签名称为见证,这是密码学中术语。比特币交易中的见证数据证明了资金真正归谁所有。隔离见证是区块链扩容的一种方法,已经在比特币、莱特币成功实施。</li><li>目前区块链上的每个区块内不仅记录的每笔转账交易的具体信息,包括时间、转出方地址、收入方地址、转账金额以外,还包含每笔交易的数字签名,用来验证该交易的合法性。矿工打包区块时需要用数字签名_验证每笔交易,确认没有问题才将该交易记录在区块里。</li><li>对于普通用户来说,他们只关心每个账户有多少资产,并不需要验证每笔交易,所以对普通用户来说数字签名就是可有可无的。隔离见证就是把区块内的数字签名信息拿出去,让每个区块可以承载更多笔交易,从而达到扩容目的。<img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwttz2u0gcj20p40e0n7h.jpg" alt="1541148329486"></li></ul></li><li><p>区块链分叉</p><ul><li>中心化系统升级软件十分简单,而区块链去中心化系统中升级不简单,甚至一言不合造成区块链分叉。简单说分叉是指区块链进行升级时,发生了意见分歧,从而导致区块链分叉。</li><li>因为没有中心化机构,比特币每次代码升级都需要获得比特币社区一致认可。如果比特币社区无法达成一致,区块链很可能形成分叉。</li><li>2017年7月,为解决比特币区块链拥堵问题,一些比特币爱好者提出了 bitcoin cash分叉方案,导致比特币区块链一分为二。根据分叉后的区块链是否能兼容旧的区块链,又分为硬分叉和软分叉。</li><li>硬分叉指比特币代码发生改变后,旧的节点拒绝接受由新节点创造的区块,不符合原来规则的区块将被忽略。矿工会按照原来规则在他们最后验证合格的区块之后创建新的区块。</li><li>软分叉则指旧的节点并不会意识到比特币代码发生改变,并继续接受由新节点创造的区块,矿工们可能会在他们没有完全理解的区块上进行工作。</li><li>软分叉和硬分叉都是向后兼容,这样才能保证新节点可以从头验证区块链。向后兼容指新软件接受由旧的软件所产生的数据或代码。</li><li>软分叉还可以向前兼容。向前兼容指旧的软件可以接受由新软件所产生数据以及代码。<img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwttzbawkqj20ke0bktbe.jpg" alt="1541148377515"></li></ul></li><li><p>零知识证明(Zero-Knowledge Proof)</p><ul><li>指证明者能够在不向验证者提供信息本身内容的情况下,使验证者相信某个论断是真实可信的一种技术。</li><li>零知识证明可以在不泄露信息本身内容的情况下,证明自己知道这个秘密,可以有效解决许多验证的问题。</li><li>举例说明如下:<ul><li>A要向B证明自己拥有某个房间的钥匙,假设该房间只能用钥匙打开锁, 而其他任何方法都打不开。这时有2个方法:<ul><li>1)A把钥匙出示给B,B用这把钥匙打开该房间的锁,从而证明A拥有该 房间的正确的钥匙。</li><li>2)B确定该房间内有某一物体,A用自己拥有的钥匙打开该房间的门, 然后把物体拿出来出示给B,从而证明自己确实拥有该房间的钥匙。</li><li>方法 2)属于零知识证明。它的好处在于,在整个证明的过程中,B始终不能看到钥匙的样子,从而避免了钥匙的泄露。</li></ul></li><li>A拥有B的公钥,A没有见过B,而B见过A的照片,偶然一天两个人见面了,B认出了A,但A不能确定面前的人是否是B,这时B要向A证明自己是B,也有2个方法:<ul><li>1)B把自己的私钥给A,A用这个私钥对某个数据加密,然后用B的公钥 解密,如果正确,则证明对方确实是B。</li><li>2)A给出一个随机值,并使用B的公钥对其加密,然后将加密后的数据交给B,B用自己的私钥解密并展示给A,如果与A给出的随机值相同,则证明对方是B。</li><li>后面方法 2)属于零知识证明。</li></ul></li><li>有一个缺口环形的长廊,出口和入口距离非常近(在目距之内),但走廊中间某处有一道只能用钥匙打开的门,A要向B证明自己拥有该门的钥匙。采用零知识证明,则B看着A从入口进入走廊,然后又从出口走出走廊,这时B没有得到任何关于这个钥匙的信息,但是完全可以证明A拥有钥匙。 </li></ul></li><li>零知识证明在密码学中非常有用。目前匿名性非常突出的数字资产ZCash(零币,ZEC)的匿名交易就是依靠零知识证明实现的。</li><li>相对于ZCash来说,比特币的转账并不是完全匿名的,只要知道了一个比特币地址,任何人都可以通过区块链浏览器网站,查到这个地址的所有“消费”行为和关联。比如给谁转了账,又从谁那里收到过转账,都会在“账 本”上“本本份份”地记录着。</li><li>而ZCash则利用一条“公有链”作为“混合容器”,经过这条公有链一系列的“混币”过程,就使得包括交易地址和具体金额在内的交易信息变得无从考证了。</li><li>虽然ZCash以其匿名性使其市场热度一度很高,但其仍面临诸多问题。首先,要实现匿名性,其所需要的证明信息所花费的计算资源就非常多,带来了大量的资源浪费。另外,匿名性会带来大量的额外监管问题,将会给追踪与监管带来非常大的挑战。</li></ul></li><li><p>ICO 与 IPO</p><ul><li>ICO: Olnitial Coin Offering缩写),叫做“首次币发行”。<ul><li>ICO是比特币诞生后不久,众筹在与代币结合后诞生的产物。</li><li>ICO是区块链行业术语,他是一种金融行为,源自股票市场的首次公开发行(IPO)概念。</li></ul></li><li>IPO(英文简称Initial Public Offering)首次公开发行。指股份公司首次向社会公众公开招股的发行方式。</li><li>ICO与IPO相比,他们有共同点,更有区别。<ul><li>共同点:<ul><li>都是筹措资金的过程,都有潜在投资者为了潜在的巨大收益而冒险参与。</li></ul></li><li>不同点:<ul><li>ICO的融资是在早起阶段;IPO融资则在企业发展的成熟期;</li><li>ICO融资获得的是代币,没有公司股权;IPO可以获得公司股权;</li><li>ICO关注产品本身;IPO关注财务数据+现金流;</li><li>ICO上市交易的是代币;IPO上市交易的是股份;</li><li>ICO的大部分支持者是项目爱好者或不专业的投资者。ICO不需要注册经营牌照。ICO平台是第三方中立平台,投资者自担风险,ICO风险极大。目前中国已经禁止ICO融资;</li><li>初创公司到上市的融资路程,一般会经历:种子轮——>天使轮——>ABC等X轮——>IPO——>二级市场。最少要经历几轮融资之后才能进入到IPO阶段。IPO属于公司上市之路的成熟期的融资,此时投资银行 介入,该阶段主要看持续盈利的能力。此时融资基本是零风险、稳 赚不赔,风险极小;</li><li>ICO是刚有⽩⽪书,就跳过所有过程,直接进⼊⼆级市场融资。投资对象都是散户,融资⾦额量巨⼤,从数千万到上亿。因此泡沫多,⻛险⾮常巨⼤。有的⽩⽪书根本⽆法解决⾏业痛点;</li></ul></li></ul></li><li>国家对ICO的态度<ul><li>2017年9月4日,人民银行、网信办、工信部、工商总局、银监会、证 监会、保监会七部委联合颁布:<ul><li>IC0是一种未经批准的非法公开融资的行为;</li><li>已完成代币发行融资的组织和个人应该做出清退;</li><li>代币融资交易平台不得从事法币与代币兑换业务;</li><li>代币融资交易平台不得从事法币与代币兑换业务;</li></ul></li></ul></li></ul></li><li><p>初创公司到上市的融资路程</p><ul><li>整体经历:种子轮——>天使轮——>ABC等X轮——>IPO——>二级市场</li><li>种子轮<ul><li>被戏称为3F轮(family、friend、foolish)</li><li>创业者刚有idea,或仅仅将idea做成PPT,创业刚起步需要资金</li><li>项目风险非常大,成功率低于1%</li><li>但是投资越早,投资回报率越高</li><li>种子轮项目投资金额,大约初始资金在50至500万RMB.</li></ul></li><li>天使轮<ul><li>目有了原型,产品刚上线,也有了少量初级用户,此时资金短缺需要融资</li><li>天使轮投资金额都在500万RMB以内</li></ul></li><li>pre-A 轮<ul><li>该阶段VC、PE进场</li><li>VC: Venture Capital Investment,风险投资</li><li>PE: Private Equity,私募股权投资</li><li>一般VC都在PE之前投资。但是目前投资机构越来越多,VC、PE的差别越来越不明显</li><li>VC—般在pre-A轮投资,具有一定风险性</li><li>PE多投资在C轮、D轮,以及IPO阶段。这些阶段风险小,基本上投资的企业中30%-40%能成功上市。</li></ul></li><li><p>IPO</p><ul><li>此时投资银行介入。基本零风险</li></ul></li><li>二级市场<ul><li>VC、PE投资的阶段属于一级市场。</li><li>割韭菜</li></ul></li></ul></li><li><p>判断ICO项目是否靠谱的标准</p><ul><li>免费送币的直接认定为不靠谱;</li><li>白皮书的语言表达是否简单易懂,模式是否清晰;</li><li>解决了什么问题,是否解决行业痛点、用户痛点,该项目使用区块链是否必要;</li><li>发行代币有无必要,项目中是否消耗代币。如果没有必要使用代币,那么投资就毫无意义;</li><li>能否快速上交易所,是否有交易所背书;</li><li>项目代码是否开源,Github代码更新频率和数量。发行代币的代码务必要开源;</li><li>创始团队的背景(学历、工作经历),技术团队是否有区块链开发经验;</li><li>站台的早起投资人有哪些,是否有相关领域专家。</li></ul></li><li><p>BIP</p><ul><li>“BIP”是Bitcoin Improvement Proposal的单词字母缩写,意思是“比特币改 进建议”,是用于引入特征信息的比特币设计文档。由于比特币没有正式的结构,BIP成为传达想法的标准方式。通过BIP向比特币社区提供信息的设计文档,或描述比特币或其流程或环境的新功能。简单来说BIP就像是一个提案。</li></ul></li><li><p>IPFS (星际文件系统)</p><ul><li>IPFS的中文名是星际文件系统,由Juan Benet在2014年5月份发起。 </li><li>IPFS本质上是一种内容可寻址、版本化、点对点超媒体的分布式存储、传输协议,目标是补充甚至取代过去20年里使用的超文本媒体传输协议 (HTTP),希望构建更快、更安全、更自由的互联网时代。</li><li>IPFS想打造一个点对点的网络拓扑,相当于颠覆HTTP所代表的分布关系,它具有内容可寻址的特点,通过文件内容生成唯一的哈希标识,一定程度上节约了空间开销的成本。</li></ul></li><li><p>什么是加密货币?</p><ul><li>加密货币(cryptocurrency),是一种基于点对点网络(P2P网络)、没有发行机构、总量基本固定的加密电子通货,或数字货币。</li><li>加密货币具有以下特点:<ul><li>P2P网络:</li><li>没有发行机构:不是哪个公司、银行或国家控制发行的。加密货币要防止通货膨胀,为防止通胀,加密货币使用了复杂的共识机制来实现。</li><li>总量基本固定:这是保证加密货币价值的一种策略。这与网络社区的积分是有区别的,积分对应的虚拟币没有固定数量,可以无限释放。</li><li>加密:对每个产生电子货币本身的交易与传输都使用加密技术,从而保证交易安全性。</li><li>电子通货:加密货币就是货币,货币也称为通货,被称为一般等价物,是可以与任何商家交换,可以购买任何货物。加密货币与黄金类似,只不过它是数字形式而已。</li></ul></li><li>加密货币与积分虚拟币的区别:<ul><li>加密货币总量稳定、可交易、可流转、有议价空间;</li><li>积分虚拟币可以无限发行,不具有流通交易的功能。积分类虚拟币并非货币,只能在网站内部使用。</li><li>加密货币高便携、高安全防伪。而积分仅仅是一串数字,网站管理员可以修改、冻结积分使用权限。</li></ul></li></ul></li><li><p>加密数字货币安全性</p><ul><li>P2P网络是加密货币的交易环境,实现无障碍交易;</li><li>密码算法是加密货币的安全保障。加密货币的安全级别是目前最高的; </li><li>区块链是加密货币的信用保障。区块链具有公开透明、不可篡改等特点,它实现了机器信任,解决了信任和价值传递;</li><li>共识机制是加密货币的运行规则。这样众多的节点在共同商讨问题、集体决策时就达成了统一的原则和规矩。</li><li>以上这些技术相互配合、相互支撑,通过共识机制成为一个整体,保证加密货币在支付和交易上的绝对安全。</li></ul></li><li><p>对区块链存在的误解</p><ul><li>区块链是一种颠覆性的新技术<ul><li>区块链不是新技术,而是一系列技术的组合。核心技术:P2P网络、密码学、共识机制、智能合约等。中本聪将这些技术巧妙的组合在一起,在此基础上引入完善的激励机制,用经济学原理解决了传统技术无法解决的问题。</li><li>这些技术组合虽然有独到的创新之处,但是并非颠覆性技术,而是现有技术的有力补充。</li><li>这些技术组合,并非颠覆现有业务,而是引入了新的思想,去改善和改造现有业务模式,从而为大众提供更好的普惠服务。</li></ul></li><li>区块链就是去中心化<ul><li>很多人认为Decentralized是区块链的核心特征,将其翻译为“去中心化”,而这个国内币圈翻译的词不够准确。软件系统的网络架构一般有三 种模式:单中心、多中心、分布式。所以Decentralized确切说是弱中心或分散式的,而不是去中心化的。</li><li>中本聪整篇论文并没有提到Decentralized,而只有peer-to-peer (P2P)。</li><li>完全去中心化是不可行的。The DAO这个基于以太坊公有链上的史上最大的众筹项目,由于其智能合约漏洞,被黑客转移走价值6000万美元的数字货币。最后不得不通过集中式的方式,强制以太坊硬分叉完成交易回滚。这也导致了以太坊社区产生了ETH和ETC这两种同源却不同价格的数字货币。</li></ul></li><li>区块链交易存在很大的延迟<ul><li>比特币每10分钟才能完成一次支付确认,且通常需要6个区块的确认,这样就至少需要1个小时的确认时间。通常银行网银支付和第三方支付,秒级完成。与此下个NB陈,区块链的比特币支付太慢。</li><li>但跨境支付,通常需要3-5个工作日,对方才能收到相应的款项。而使用比特币跨境汇款,仅仅需要一个小时就能收到汇款,如此比较,比特币支付非常快了。</li></ul></li></ul></li><li><p>区块链有哪些分类</p><ul><li>区块链按准入机制分三类:公有链、联盟链、私有链<ul><li>公有链:公开透明,开放生态的交易网络。世界上任何个体或团队都可以在公有链发送交易,且交易能获得该区块链有效确认。每个人都可以竞争记账权。公有链可以为行业链和私有链提供全球交易网络。典型代表:比特币、以太坊。</li><li>联盟链:半封闭生态的交易网络,存在对等的不信任节点。是某个群里或组织内部使用的区块链,需要预先指定几个节点为记账人。每个区块的生成由所有预选记账人共同决定,其他节点可以交易,但是没有记账权。如房地产行业A、B、 C、D公司。</li><li>私有链:完全封闭生态的存储网络,仅仅采用区块链技术进行记账,但是所有节点都是可信任的。记账权并不公开,且只记录内部的交易,由公司或个人独享。如某大型集团内部多数公司。</li><li>目前这三类区块链,还存在很多发展中的障碍<ul><li>主流金融机构难以接纳公有链</li><li>私有链与公有链架构差异大</li><li>私有链和联盟链还很不成熟</li></ul></li></ul></li></ul></li><li><p>以太坊平台与DApp的区别</p><ul><li>以太坊平台如同淘宝</li><li>DApp就是淘宝上的商家</li></ul></li></ol><ol start="22"><li><p>什么是区块链生态系?</p><ul><li>目前区块链生态系统主要分为三类,一类是比特币生态系,一类是以太坊生态系,而另外一种就是石墨烯生态系。</li><li>比特币生态包括BTC以及其数量众多的分叉币,BTC是加密数字货币的开山鼻祖,拥有最为广泛的共识。</li><li>以太坊生态系又叫做ERC20 Token, CoinMarketCap上绝大多数的Token都是基于以太坊ERC20。以太坊生态提供的智能合约,可以极为简便的发行Token,项目再利用ICO的方式进行快速融资。</li><li>石墨烯生态的代表有BTS,Steem和EOS。石墨烯采用的是DPOS的共识机制,出快速度大约为1.5s,石墨烯技术使得区块链应用更高的交易吞吐量,BTS可以处理十万级别的TPS,而EOS则是宣称百万级别的TPSO同时石墨烯技术高并发处理能力也是比特币和ETH无法做到的。</li></ul><p>参考资料:<a href="httpS://dbarobin.com/2018/01/31/blockchain-graphene/" rel="external nofollow noopener noreferrer" target="_blank">httpS://dbarobin.com/2018/01/31/blockchain-graphene/</a></p></li></ol><ol start="23"><li><p>区块链与编程语言的关系?</p><ul><li>区块链是一种编程思想,使用任何一种编程语言都可以实现。比如:C++、 Java、javascript, python、Go都可以实现开发区块链。</li><li>比特币系统使用C++开发。学习比特币系统仅仅用于学习区块链原理,很难在比特币系统上进行继续开发。学习比特币原理时可以使用Java、javascript, python、Go任何一种语言。</li><li>以太坊系统,官方推出了C++开发版本和Go开发版本。要在以太坊平台上开发智能合约,官方建议使用Solididy语言,该语言类似Javascript。如果开发 DApp,可以采用C++、Go、Python、Java开发。</li><li>超级账本中的Fabric系统是用Go语言开发的。学习Fabric开发,可以使用Go和Java语言。</li></ul><p>综上所述,学习区块链开发建议建立在Go语言和javascript基础上。而Go语言的学习难度比Java略低。</p></li></ol><ol start="24"><li>GO编程语言的发展前景?<ul><li>Go语言由Unix之父肯.汤普森牵头开发,而肯.汤普森在电脑工业史上具有极高的地位;</li><li>Go语言在2007年9月才正式命名为Go,2012年3月才发布第一个正式版本。是一门非常新的语言;</li><li>Go语言短短五年时间,已经成为2016年年度编程语言。在2018年5月的TIOBE语言排行榜上挤入前15名,上升至第14位;</li><li>Go语言是为了解决分布式计算,是云计算领域的新兴语言。而区块链是典型的分布式数据存储系统,使用Go语言是绝配;</li><li>Go语言的编译和运行速度在众多编程语言中遥遥领先。Go语言中提供的丰富的标准库,让学习成本低于Java;</li><li>Go语⾔被预测会成为未来编程语⾔的前三甲(Java、C++、Go)。</li></ul></li></ol><ol start="25"><li>Go语言能开发什么?<ul><li>服务器编程,以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。</li><li>分布式系统、数据库代理器等,例如Etcd。</li><li>网络编程,这一块目前应用最广,包括Web应用、API应用、下载应用,而且Go内置net/http包基本上把我们平常用到的网络功能都实现了。</li><li>数据库操作。</li><li>开发云平台,目前国外很多云平台在采用Go开发。</li></ul></li></ol><ol start="26"><li>Go语言设计的初衷<ul><li>针对其他语言的痛点进行;</li><li>加入并发编程;</li><li>为大数据、微服务、并发而生的通用编程语言。</li></ul></li></ol><ol start="27"><li>Go语言的优势<ul><li>学习曲线:它包含了类C语法、GC内置和工程工具。这一点非常重要,因为Go语言容易学习,所以一个普通的大学生花一个星期就能写出来可以上手的、高性能的应用。在国内大家都追求快,这也是为什么国内Go流行的原因之一。 <img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwttzpnwcvj20x00mk42w.jpg" alt="1541149015204"></li><li>效率:Go拥有接近C的运行效率和接近Python、PHP的开发效率,这就很有利的支撑了上面大家追求快速的需求。<img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwtu0126maj20zo0iytcw.jpg" alt="1541149035325"></li><li>出身名门、血统纯正:之所以说Go出身名门,是因为我们知道G◦语言出自Google公司,这个公司在业界 的知名度和实力自然不用多说。Google公司聚集了一批牛人,在各种编程语言称 雄争霸的局面下推出新的编程语言,自然有它的战略考虑。而且从Go语言的发展 态势来看,Google对它这个新的宠儿还是很看重的,Go自然有一个良好的发展前途。我们看看Go语言的主要创造者,血统纯正这点就可见端倪了。</li><li>自由高效:组合的思想、无侵入式的接口。Go语言可以说是开发效率和运行效率二者的完美融合,天生的并发编程支持。Go语言支持当前所有的编程范式,包括过程式编程、面向对象编程以及函数式编程。程序员们可以各取所需、自由组合、想怎么玩就怎么玩。</li><li>强大的标准库:这包括互联网应用、系统编程和网络编程。Go里面的标准库基本上已经是非常稳定了,特别是我这里提到的三个,网络层、系统层的库非常实用。</li><li>部署方便:二进制文件、Copy部署:我相信这一点是很多人选择Go的最大理由,因为部署太方便了,所以现在也有很 多人用Go开发运维程序。</li><li>简单的并发:它包含了降低心智的并发和简易的数据同步,这是Go最大的特色。之所以写正确 的并发、容错和可扩展的程序如此之难,是因为我们用了错误的工具和错误的抽象,Go可以说这一块做的相当简单。</li><li>稳定性:Go拥有强大的编译检查、严格的编码规范和完整的软件生命周期工具,具有很强的稳定性,稳定压倒一切。那么为什么Go相比于其他程序会更稳定呢?这是因为Go提供了软件生命周期(开发、测试、部署、维护等等)的各个环节的工具,如 go tool、gofmt、go test。</li><li>所以,Go语言是目前项目转型首选的语言,也是软件工程师转型首选的语言,是添加技术栈的首选语言。Go常常是一种为转型而量身定制的语言,所以最好需要有其他语言的基础。(C++、Java、PHP、Python、Javascript等) </li></ul></li></ol><ol start="28"><li>知名编程语⾔优势对⽐:<ul><li>Java:作为编程语⾔中的⼤腕。具有最⼤的知名度和⽤户群。⽆论⻛起云涌,我⾃巍然不动。他强任他强,清⻛拂⼭岗;他横由他横,明⽉照⼤江。</li><li>C/C++: 现存编程语⾔中的⽼祖,其他语⾔皆由此⽽⽣。执⾏效率⽆⼈能及。</li><li>Javascript:编程语⾔中特⽴独⾏的傲娇美⼥。前端处理能⼒是其它语⾔⽆法⽐拟。发展中的js后端处理能⼒也是卓越不凡。前后端通吃,舍我其谁?</li><li>Python:代码简洁、开发速度快⽆⼈能⽐。</li><li>Go:编程界的⼩鲜⾁。⾼并发能⼒⽆⼈能及。即具有像Python⼀样的简洁代码、开发速度,⼜具有C语⾔⼀样的执⾏效率。优势突出,被区块链开发推荐为⾸选语⾔。</li></ul></li></ol>]]></content>
<categories>
<category> 区块链 </category>
</categories>
<tags>
<tag> 比特币 </tag>
<tag> blockchain </tag>
</tags>
</entry>
<entry>
<title>初识区块链家族</title>
<link href="/posts/24d6384d.html"/>
<url>/posts/24d6384d.html</url>
<content type="html"><![CDATA[<h1 id="初识区块链家族"><a href="#初识区块链家族" class="headerlink" title="初识区块链家族"></a>初识区块链家族</h1><p>区块链有一个伟大的家族</p><p><img src="http://ws4.sinaimg.cn/large/e64a4785gy1fwp6pe3nhbj20qa0vqn0d.jpg" alt="1540794240835"></p><h2 id="一-区块链的父亲————去中心化"><a href="#一-区块链的父亲————去中心化" class="headerlink" title="一.区块链的父亲————去中心化"></a>一.区块链的父亲————去中心化</h2><ol><li><p>去中心化基本概念</p><ul><li>中心化(Centralization, [ sentrelai’zei J n])和去中心化(Decentralization, [ diisentralai’zei J n])就是集权与分权;</li><li>从天文学的角度来看去中心化是指宇宙没有中心,就是一片无边界的物质 组成,没有中心点;</li><li>去中心化在宗教方面的体现,比如基督教,基督教原来是以教会为核心的,去中心化结合基督教之后,每个人都可以直接跟上帝发生关联,而不一定要通过教会;</li><li>去中心化结合政治,于是产生了民主制度,从此每个人都能发表自己的见解;</li><li>去中心化是一种哲学思想。这种思想在人类出现的时候就已经存在,主旨是弱化中心,然后实现人与人之间直接沟通、直接交易、直接传播的一种方式;</li><li>去中心化,并非不要中心,而是由节点来自由选择中心、自由决定中心。 所以将Decentralization翻译成“去中心化”不够准确,确切点说应该是“弱中 心化”。比如在金融活动中,简单地区中心,会被误读为既想从事金融活动,又不愿意接受金融监督。目前业界已经慎重使用Decentralization,更多地使 用P2P或者Serverless(无服务器的);</li><li>简单地说,中心化的意思,是中心决定节点。节点必须依赖中心,节点离 开了中心就无法生存。在去中心化系统中,任何人都是一个节点,任何人也都可以成为一个中心。任何中心都不是永久的,而是阶段性的,任何中心对 节点都不具有强制性;</li><li>中心化和去中心化是相辅相成的关系。未来的技术肯定是不断的调整中心化和去中心化的平衡,以取得相应场景的最高效率。绝对的中心化和去中心 化都没有意义。向一个方向倾斜时会带来相应好处,同时也会带来相应的弊端。</li></ul></li><li><p>互联网中的去中心化</p><ul><li><p>去中心化在互联网上,人们习惯叫他P2P,P2P具有极大的影响力;</p><ul><li>P2P是Peer-to-Peer(peer,地位同等,对等的意思)的简称。在互联网中P2P被称为“对等联网”;</li><li>P2P是Point - to - Point (点对点);</li><li>P2P是person-to-person的简写,意思是个人对个人;</li><li>对等联网是只读网络的终结(Peer-to-peer is the end of the read only Web);</li><li>对等联网使你重新参与互联网(Peer-to-peer allows you to participate in the Internet again);</li><li>对等联网使网络远离电视(Peer-to-peer steering the Internet away from TV);</li><li>P2P就是一种思想,有着改变整个互联网基础的潜能的思想。而P2P并非一个新思想,从某些角度看它其实才是最初创建互联网的基本思想。</li></ul></li><li><p>去中心化的表现就是多样化。在网络世界不再是有几个门户网站说了算, 各种各样的网站开始有了自己的声音,表达不同的选择,不同的爱好,这些网站分布在网络世界的各个角落里张扬着个性;</p><ul><li>通俗地讲,中心化是几个经过认证的嘉宾在‘讲话’,所有其他人在听,类似上课;去中心化是每个人都可以‘讲话’,每个人都可以选择讲或者听,如同英语角。中心化的典型例子是门户网站,去中心化的典型例子是blog、社交媒体等。</li></ul></li><li><p>互联网去中心化发展过程</p><ul><li>互联网发展的层面来看,去中心化是相对于“中心化”而言的新型网络 内容的生产过程;</li><li>早期的互联网Web1.0时代,网络内容是由专业网站或特定人群所产生的,这就是“中心化”;</li><li>自网络Web2.0开始,出现了新型的网络内容生产过程。网络内容由全 体网民共同参与、共同创造。任何人都可以在网络上表达自己的观点或 发表原创内容。网络从缺乏互动的个别人建站变成了以圈子的形式来聚 合人才共同贡献智慧,这是一个巨大的变革;</li><li>Web2.0兴起后,Wikipedia (维基百科,网络百科全书)、Flickr(雅虎旗下图片分享网站)、Blogger(博客,网络日志)等网络服务商所提 供的服务都是去中心化的,任何参与者都可提交内容。之后更简单易用 的去中心化产品出现了,例如Twitter (推特,微博)、Facebook(脸书)、QQ、微信这些当今最流行的P2P应用的出现,使得普通网民为互 联网贡献内容更加简便、更加多元化,也更加积极。最终使得每一个网 民都成为了一个微小且独立的信息提供者,使得互联网更加扁平、内容生产更加多元化。</li></ul></li><li><p>很多人对去中心化有一些误解,比如说Facebook. Twitter、QQ、微信等正在成为更集中的中心。去中心化不是说今后不再有大网站,也不是说大网站就一定是中心化的,去中心化主要是指技术对普通用户的赋权。另外,去中心化也不是人人绝对平等的意思,总会有人更善于利用技术赋予的可能 性,有人则不善用或不在乎。</p><p><img src="http://wx4.sinaimg.cn/large/e64a4785gy1fwp6q0c0vtj20po0gq45g.jpg" alt="1540802427979"></p></li></ul></li><li><p>去中心化的经典案例</p><p>Github是去中心化的一个很好的例子。Github就是让所有人在互联网上分享 和贡献代码,在Github里,没有所谓的中心化公司,所有的交互都是人与人之间产生。在区块链的世界里,所有事物都是去中心化的:从一个应用,到一家公司,都必须通过每个人来贡献,大家遵守共同制定的规则。</p><p><img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwp6tmoindj20yb0jf138.jpg" alt="1540802757425"></p></li></ol><h2 id="二-区块链的母亲一互联网"><a href="#二-区块链的母亲一互联网" class="headerlink" title="二.区块链的母亲一互联网"></a>二.区块链的母亲一互联网</h2><ul><li><p>区块链的母亲就是互联网;</p></li><li><p>互联网是一个没有中心化节点的网络结构。每一个点,从本质上来说,在整个互联网上都是同等重要的存在。所以去中心化与网络是天作之合;</p></li><li><p>去中心化与网络结合后,诞生了延续了去中心化基因,并且对整个世界产生巨大影响的8个孩子,按照排行分别是:P2P下载、CDN、分布式计算、社交媒体、P2P借货、众筹(众筹与代币结合后诞生了ICO)、区块链(区块链 的儿子是比特币)、DAO自组织。</p><p><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwp6xzrboqj20uf0hkqh1.jpg" alt="1540803011138"></p></li></ul><h2 id="三-区块链的大哥一P2P下载"><a href="#三-区块链的大哥一P2P下载" class="headerlink" title="三.区块链的大哥一P2P下载"></a>三.区块链的大哥一P2P下载</h2><ol><li><p>P2P下载的发展史</p><ul><li>去中心化的第一个产物就是P2P下载。P2P下载是其父亲的姓氏+其自身名字“下载”的合称;</li><li>早在1998年,美国东北波士顿大学的一年级新生——18岁的Shawn Fanning(肖恩•范宁,他也是Facebook最早的顾问、投资人和股东之一)为了能够解决他的室友的一个问题——如何在网上找到音乐而编写的一个简单的程序,这个程序能够搜索音乐文件并提供检索,把所有的音乐文件地址存 放在一个集中的服务器中,这样使用者就能够方便地过滤上百个地址而找到自己需要的MP3文件;</li><li><p>到了1999年,令他们没有想到的是,这个叫做Napster的mp3音乐分享网 站成为了人们争相转告的“杀手程序”——它令无数散布在互联网上的音乐爱好者美梦成真,无数人在一夜之内开始使用Napster。1999年5月,Napster公司宣告成立,这是一个非同意义的起始,也正是从这天起,P2P开始了它曲折但极富生命力的发展。在最高峰时Napster网络有8000万的注册用户,这是一个让众多网络平台望尘莫及的数字。这大概可以作为P2P软件成功进入人们生活的一个标志;</p></li><li><p>Napster,能让大家自由下载MP3,但是这个mp3文件,并不是放在Napster网站的硬盘上的。要想把整个互联网上的音乐都放在一起也是不可相 像的。Shawn是将每个人电脑上的mp3汇集成一张目录。如果你想下载mp3,那么Napster就会找到那些有这个mp3的电脑,同时去从这些电脑中下载一个个小小的碎片,然后在你的电脑上拼成这个mp3。所以Napster本身并 不拥有MP3,他只是帮助那些拥有mp3的人互相分享,这就是“点对点分 享”;</p></li><li><p>Napster并非一帆风顺,因为P2P下载对版权保护的冲击很大,美国后来禁止用这种方式来分享MP3, Napster也于2002年宣告破产。但是这个逻辑,一直存续了下来。尤其在中国P2P下载风景这边独好。</p><p><img src="http://ws4.sinaimg.cn/large/e64a4785gy1fwp781zcbwj20a309jq5q.jpg" alt="1540803601649"></p></li></ul></li><li><p>P2P下载的知名产品简介</p><ul><li><p>P2P作为一种网络技术,依赖网络中参与者的计算能力和带宽,而不是把依赖都聚集在较少的几台服务器上;</p></li><li><p>P2P下载的本质,是一种硬盘的共享,是把每个人电脑上的一部分硬盘拿出来与其他人共享;</p></li><li><p>BT下载:说到P2P,就不能不提BT,这个被人戏称为“变态”的词几乎在大多数人感觉中与P2P成了对等的一组概念,而它也将P2P技术发展到了近乎完美的地步。</p><ul><li><p>实际上BitTorrent(torrent [‘torrent]山洪;洪流;激流;爆发。中文名称比特流,简称BT),原先是指是一个多点下载的P2P软件。它不象FTP那样只有一个发送源,BT有多个发送点,当你在下载时,同时也在上传,使大家都处在同步传送的状态。应该说,BT是当今P2P最为成功的一个应用;</p></li><li><p>BT用的是BT专用协议,在BT网络中都有一个种子文件,下载者都是从 这个种子文件开始下载,然后每个下载者之间再互传。例如:客户端甲从服务器上随机下载了第N部分,客户端乙从服务器上随机下载了第M部分。这样甲的BT就会根据情况到乙的电脑上去拿乙已经下载好的第M部 分,乙的BT就会根据情况去到甲的电脑上去拿甲已经下载好的第N部 分。BT下载从理论上讲是下载的同时必需上传给其它人分享。这种下载方式,人越多时下载速度越快;</p></li><li><p>有一句话可以作为BT最为形象的解释就是:“我为人人,人人为我”。最初听到此概念时,有人担心使用BT会损坏硬盘!因为在执行P2P下载曰寸,电脑硬盘在高速执行读与写的操作,同时对电脑内存占用也较多, 会影响整机速度。但是没有贡献怎么会有获取,这就是BT下载传输的精髓。工具软件BTJoy,将BT技术以软件的形式完美呈现起来,BTJoy诞 生仅一年内就已经迅速火遍整个网络。对于BT下载的爱好者来说,BTJoy的存在让多大的硬盘都可以被迅速塞满;</p></li><li><p>迅雷(Thunder)下载:迅雷智能下载软件,它拥有比目前用户常用的下载软 件快7—10倍的下载速度。迅雷就是P2P下载,它的逻辑是把电影文件放到每个不同的电脑上,然后彼此分享,这个模式极大地节省了资源;</p></li><li><p>酷狗(KuGoo)音乐:酷狗是基于中文平台专业的P2P音乐传输软件。通过KuGoo,用户可以方便、快捷、安全地实现中国国内最大的音乐搜索查找。</p><p><img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwp7fclz56j20g807qaei.jpg" alt="1540803999555"></p><p><img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwp7gvllh6j20g80avwhb.jpg" alt="1540804105736"></p><p><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwp7hslpwhj20g80b1q68.jpg" alt="1540804163466"></p></li></ul></li></ul></li></ol><h2 id="四-区块链的二哥一CDN"><a href="#四-区块链的二哥一CDN" class="headerlink" title="四.区块链的二哥一CDN"></a>四.区块链的二哥一CDN</h2><ol><li><p>CDN</p><ul><li>去中心化与互联网结合后的第二个产物就是CDN;</li><li>CDN的全称是Content Delivery Network,即内容分发网络。<ul><li>CDN的基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定;</li><li>例如:在互联网上看电影,有一个问题。在上海通过视频网站看一部电影,因为电影是存放在北京的服务器上,在上海看就会很慢,如果在深圳去看这个电影,反应会更慢。那怎么办?有一个办法就是把这个电影放在很多不同地区的服务器,看电影时找最近的服务器来访问,这就是CDN;</li><li>CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布 到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。最终降低网络拥塞,提高用户访问响应速度 和命中率;</li><li>CDN包括分布式存储、负载均衡、网络请求的重定向和内容管理4个要件,而内容管理和全局的网络流量管理是CDN的核心所在。通过用户就近性和服务器负载的判断,CDN确保内容以一种极为高效的方式为用户的请求提供服务;</li><li>CDN目前广泛应用于视频云行业的内容分发加速。</li></ul></li></ul></li><li><p>P-CDN</p><ul><li><p>P-CDN:就是P2P内容分发网络(英文名:P2PCDN,简称P-CDN),是以 P2P技术为基础,通过挖掘利用边缘网络的海量碎片化闲置资源而构建的低成 本高品质的内容分发网络服务。接入该服务后能获得高于CDN的分发质量,同时显著降低分发成本。适用于视频点播、直播、大文件下载等业务场景;</p></li><li><p>阿里云PCDN是基于P2P技术的CDN产品,两者实现完美结合,更适合大流量分发。PCDN产品相对于CDN拥有成本更低、质量更好两方面的核心优势;</p></li><li><p>关于P-CDN的落地,要感谢迅雷。迅雷很早就开始用P-CDN,它出售给会员一种商品,当年叫赚钱宝,后来叫玩客币。玩客币是迅雷旗下智能硬件“玩 客云”用户激励的虚拟数字资产,其实都是让会员用家里面的网络,来访问彼 此网络带宽的一种设备。迅雷通过这一硬件设备,将用户的闲置带宽充分利用,以极低的代价扩充自身CDN,获得更大的云储备空间与带宽,而对于用户来说,可以在带宽闲置时贡献带宽从而获得收益;</p><ul><li>玩客币每天产量固定,第一年每天产量每天约164万个,每365天减半 一次。这种以区块链技术为基础,通过挖矿获取,总量有限且产量随时 间逐步递减的模式在很大程度上都与比特币相似。</li></ul></li><li><p>如果说P2P下载实现了硬盘的分享,而P-CDN实现的是网络资源带宽的分享。</p><p><img src="http://wx4.sinaimg.cn/large/e64a4785gy1fwp7ospf4dj20ie0a476n.jpg" alt="1540804609647"></p></li></ul></li></ol><h2 id="五-区块链的三哥一分布式计算"><a href="#五-区块链的三哥一分布式计算" class="headerlink" title="五.区块链的三哥一分布式计算"></a>五.区块链的三哥一分布式计算</h2><ol><li><p>分布式计算概述</p><ul><li>去中心化与互联网结合后诞生了分布式计算,而分布式计算的出现,轰动了全世界;</li><li>广义上讲,分布式计算是一门计算机科学,它研究如何把一个需要非常巨大的计算能力才能解决的问题分成许多小的部分,然后把这些部分分配给许多计算机进行处理,最后把这些计算结果综合起来得到最终的结果;</li><li>具体来讲,分布式计算是一种计算方法,和集中式计算是相对的。随着计 算技术的发展,有些应用需要非常巨大的计算能力才能完成,如果采用集中式计算,需要耗费相当长的时间来完成。分布式计算将该应用分解成许多小的部分,分配给多台计算机进行处理。这样可以节约整体计算时间,大大提 高计算效率。<ul><li>过去我们破译一个算法或者密码,我们用一个东西:超级计算机。就是在机房里有个特别厉害的计算机,它的运算速度,比全世界任何一台计算机都要快。这就是中心化的计算。</li><li>那什么是分布式计算呢?就把需要大量计算的工作,比如说,破译密码,或者计算一个DNA序列,分解成无数的小块。分成小块后,再扔给全世界一个个小的计算机,比如你家里的个人电脑。当全世界几千、几万甚至几十万台个人电脑的CPU,同时计算的时候,再怎么样,计算速度都会比一个超级计算机要快。</li><li>一些人类以前解决不了的问题,比如需要大量计算的基因学、密码学的问题,在分布式计算面前也能被轻而易举地解决。最近的分布式计算项目被用于使用世界各地成千上万位志愿者的计算机的闲置计算能力, 通过因特网,分析来自外太空的电讯号,寻找隐蔽的黑洞,探索可能存在的外星智慧生命。</li><li>使用多台电脑一起来运算,而如果这么多台电脑都处在互联网上,它们如何相互链接?如何传递消息和通信?如何协调各自的任务和分工?这些问题就是分布式计算系统要解决的事。</li><li>世界上很多非常复杂的科学问题,就是通过分布式计算来完成的。比特币就是其中之一。</li></ul></li></ul></li><li><p>边缘计算与Hadoop</p><ul><li><p>P2P下载是用来共享硬盘的;CDN是共享网络帯宽的;分布式计算则共享计算机CPU资源。三种技术联合在一起叫做“边缘计算”;</p></li><li><p>云计算,可以算是区块链家族的一个远房亲戚。云计算是通过互联网的方式来给大家提供一台巨大的、远的云端计算机。但是云计算依然是用云端来提供的一个中心化的计算资源;</p></li><li><p>边缘计算,是不用云端来提供一个中心化的计算资源,而是把每台计算机的硬盘资源、网络资源、CPU资源都拿出来共享,这样全世界的计算机,加 在一起就变成一台虚拟的超级计算机。这被称之为分布式云计算,由全网计算机一起提供云计算的服务,然后由边缘计算技术来统一协调。</p></li><li><p>Hadoop是一个能够对海量数据进行分布式计算的软件框架。</p></li><li><p>Hadoop框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数 据提供了存储,则MapReduce为海量的数据提供了计算。</p></li><li><p>HDFS是Hadoop分布式文件系统(Hadoop Distributed File System)的缩写,为分布式存储提供了底层支持。</p></li><li><p>MapReduce从它名字上来看就大致可以看出个缘由,两个动词Map和Reduce, “Map (展开)”就是将一个任务分解成为多个任务,“Reduce”就是将分解后多任务处理的结果汇总起来,得出最后的分析结果。MapReduce总体说就是“任务分解与结果汇总”。</p><p><img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwp7w1uvo2j20hs0a60v6.jpg" alt="1540804975680"></p></li></ul></li></ol><h2 id="六-区块链的四姐一社交媒体"><a href="#六-区块链的四姐一社交媒体" class="headerlink" title="六.区块链的四姐一社交媒体"></a>六.区块链的四姐一社交媒体</h2><ol><li><p>社交媒体是去中心化与互联网结合后的其中一个产物;</p></li><li><p>过去媒体是中心化的,在全世界范围之内,发言权是集中在少数人手上的;</p></li><li><p>社交媒体诞生后,她让每个人都有公平发言的机会,每个人的声音都能被别人听到,整个世界就立刻变得非常感性,每个人都能够说出自己有创意的、有感情的想法;</p></li><li><p>社交媒体是人们彼此之间用来分享意见、见解、经验和观点的工具和平台,现阶段最知名的社交媒体就是Facebook.Twitter,在中国则是新浪微博、腾讯QQ、微信等等;</p></li><li><p>社交媒体传播的信息已成为人们浏览互联网的重要内容,不仅制造了人们社交生活中争相讨论的热门话题,更进而吸引传统媒体争相跟进;</p></li><li><p>社交媒体已经不仅仅是个人信息发布的平台,更是企业营销的最佳渠道。</p><p><img src="http://wx3.sinaimg.cn/large/e64a4785gy1fwp7za5mm4j20ha0a1qa0.jpg" alt="1540805167758"></p></li></ol><h2 id="七-区块链的五哥一P2P借货"><a href="#七-区块链的五哥一P2P借货" class="headerlink" title="七.区块链的五哥一P2P借货"></a>七.区块链的五哥一P2P借货</h2><ol><li><p>P2P借贷是去中心化与网络结合后,在金融领域诞生的第一个孩子;</p></li><li><p>P2P借贷是什么意思呢?就是今天我需要钱,我不去银行,而是直接去找有钱人借。一般需要借助电子商务专业网络平台帮助借货双方确立借货关系并 完成相关交易手续。借款者可自行发布借款信息,包括金额、利息、还款方式和时间,实现自助式借款;借出者根据借款人发布的信息,自行决定借出金额,实现自助式借货。</p></li><li><p>举例说明:MB月光宝盒平台</p><ul><li>A有借款的需求,却找不到合适的人来借,在平台上发布了这个需求。</li><li>B有多余的闲钱,想要有更好的收益,于是通过平台进行投资。</li><li>平台所做的就是通过A的需求,B的需求,最终把俩人匹配了起来,由B借给A,平台做担保。A要承担一定的借款利息,B可以收益一定的借款利息。这就是P2P借货。</li></ul></li><li><p>归根结底,电商卖家、小微企业很难从银行获得贷款的原因,就是因为卡在了信用审批这一环节上。客观地说,电商卖家、小微企业并非没有信用,只不过各大银行很难客观公正地评估中小企业的信用。在这种市场环境下,P2P货款平台的出现,为小微企业提供了融资渠道,解决了发展过程中的一大难题。</p></li><li><p>P2P网货平台由于没有货款牌照,还属于民间借贷,借货资金的进出往往要 通过网站创始人的个人账户或公司账户进行,一般较大的P2P平台每天的资金 沉淀多达三五百万元,这就为平台私自挪用用户资金乃至携款潜逃埋下了隐患。大部分P2P平台都选择和第三方支付平台合作。</p></li><li><p>为了借货安全应该引入第三方资金托管,才能降低P2P借货资金流转中的风险。</p><p><img src="http://wx2.sinaimg.cn/large/e64a4785gy1fwp86igpnaj20ew09egqv.jpg" alt="1540805572816"></p></li></ol><h2 id="八-区块链的六哥一众筹"><a href="#八-区块链的六哥一众筹" class="headerlink" title="八.区块链的六哥一众筹"></a>八.区块链的六哥一众筹</h2><ol><li><p>众筹的鼻祖AngelList</p><ul><li><p>在金融领域诞生P2P借货之后,很快又诞生了众筹;</p></li><li><p>2003年,纳瓦尔(Naval)创办了一家企业,由于不懂风险投资行业潜规则」,被投资人骗得血本无归。这让Naval对资本的恶意、创业的艰辛深有体会。他决定以一种特殊的方式,帮助初创企业——创办AngelList (天使名单的意思)。</p></li><li><p>AngelList是一家专门连接初创企业和投资者的融资平台和社交网络。他是 股权众筹的鼻袓。AngelList®覆了传统风投业,聚合了大量的巨无霸型投融资平台。AngelList从初创公司成长为投融资航母级企业,他们只用了三年。AngelList模式在全世界范围内被广泛地传播和复制,也包括中国。</p></li><li><p>AngelList对自己白勺定位:AngelList is where the world meets startups.<br>(AngelList是让世界认识初创企业的地方)</p><p><img src="http://wx1.sinaimg.cn/large/e64a4785gy1fwp8athwajj20ga07d0w1.jpg" alt="1540805832605"></p></li></ul></li><li><p>众筹概述</p><ul><li><p>众筹,英文是crowdfunding0即大众筹资或群众筹资,香港译作“群众集资”,台湾译作“群众募资”。由发起人、跟投人、平台构成。具有低门槛、多样性、依靠大众力量、注重创意的特征,一种向群众募资,以支持发起的个人或组织的行为。一般而言是通过网络上的平台连结起赞助者与提案者。群众募资被用来支持各种活动,包含灾害重建、民间集资、竞选活动、创业募资、艺术创作、自由软件、设计发明、科学研究以及公共专案等。</p></li><li><p>过去我们融资都是去找风险投资,或者去上市,这些都是中心化融资的方法。其实机构或者股市的钱也是无数投资人给的,那么一个企业如果需要钱,能不能直接去找这些零散的投资人借呢?</p></li><li><p>今天的金融世界里是有监管的,因为世界上有很多不合格的投资人,就是那些对风险没有识别能力和承受能力的人,拿他们的钱,会有金融风险。</p></li><li><p>在中国超过200人叫非法集资,那么我们能不能在200人之内,找到对风险 有识别能力和承受能力的人,拿他们的钱,而不需要通过中间机构呢?我们把这种方式叫做众筹。</p></li><li><p>众筹依然会让全世界觉得头疼,因为还是涉及到金融风险。但是他让很多优秀的创业者拿到了投资,让他们能够有机会去改变这个世界。</p></li><li><p>美国打车软件Uber,这家在全世界引起巨大反响的公司,他们的第一笔钱,就是从angelList通过众筹的方式拿到的。</p><p><img src="http://ws1.sinaimg.cn/large/e64a4785gy1fwp8feib8rj20g70a6458.jpg" alt="1540806094096"></p></li></ul></li></ol><h2 id="九-区块链家族的老七一区块链"><a href="#九-区块链家族的老七一区块链" class="headerlink" title="九.区块链家族的老七一区块链"></a>九.区块链家族的老七一区块链</h2><p><img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwp8h3rmisj20gt0a40za.jpg" alt="1540806194244"></p><ol><li><p>区块链的起源:区块链(Blockchain)的概念最早可以追溯到2008年末,笔名“中本聪”的人在论坛中发表了一篇论文《比特币:一种点对点的电子现金系统》,首次提出了区块链的概念。随后,区块链成为了比特币的核心组成部分,核心作用是作为所有交易的公共账簿。区块链成为第一个解决数字货币重复消费问题的技术。</p></li><li><p>区块链的概念:</p><ul><li>狭义来讲,区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码学方式保证的不可篡改和不可伪造的分布式公共账本。</li><li>广义来讲,区块链技术是利用链式数据结构来验证与存储数据、利用分布式节点共识算法来生成和更新数据、利用密码学的方式保证数据传输和访问的安全、利用由自动化脚本代码组成的智能合约来编程和操作数据的一种全新的分布式基础架构与计算方式。</li></ul></li><li><p>区块链的本质:</p><ul><li>区块链的本质,其实就是一个去中心化的数据库,全民集体在维护这个可靠的数据库。传统情况下,无论系统多大多小,其背后都有一个数据库,谁维护系统谁就管理数据库,其他使用者无权参与。区块链则颠覆传统,让系统中每个用户参与其中。</li><li>通俗一点说,区块链技术是一种全民参与记账的方式。<ul><li>区块链就是一个分布式的公共账本,每一个点都可以在上面记账。传统的记账系统,记账权只掌握在中心服务器手中。比如QQ、微信上的信息,只能由腾讯的服务器来记账;淘宝、天猫的信息,只能由阿里的服 务器来记账。但在区块链系统,每台计算机是一个节点,任何一个节点都可以记账,中间无需第三方服务器。</li><li>当任意两个账号的资金互转,这笔加密的交易会广播到其他所有节点,也就是说通知到其他所有用户。举例说明,在一个100人的村子,张三买了李四家一头牛,向他支付1万元。普通的做法是,他可以找到中间人村会计王五(总记账人),将自己账下1万元转到李四账下。但在区块链系统里,张三无需再通过总记账人王五,而是直接将自己账本的1万元 记到李四账本;同时将这笔交易信息广播给全村听到(即整个区块链系统)。当村里其他人知道并确认了这笔交易,交易才算最终完成。因为这笔交易被加密处理,只有李四才能收到这1万元,而其他98人只能在账户内看到有这笔交易信息,但无法看到这笔信息是转给谁的。此外系统可以完整记录交易过程,整个交易可以溯源。</li><li>区块链防止了交易双方篡改交易信息,这使得区块链彻彻底底的透明。区块链中没有中心总账本,而是通过所有参与者的独立账本分布式记账,每个人都持有完整的账本。这些节点分布在互联网的任意角落,让具有足够多节点的区块链很难被攻击或篡改。所以区块链被认为是世界上有史以来最安全的数据管理方式。</li></ul></li></ul></li><li><p>区块链模型:</p><ul><li><p>区块链模型:一般说来,区块链系统由数据层、网络层、共识层、激励层、合约层和应用层等六层组成。</p><ul><li><p>数据层封装了底层数据区块以及相关的数据加密和时间戳等基础数据和基本算法;</p></li><li><p>网络层则包括分布式组网机制、数据传播机制和数据验证机制等;</p></li><li><p>共识层主要封装网络节点的各类共识算法;</p></li><li><p>激励层将经济因素集成到区块链技术体系中来,主要包括经济激励的发行机制和分配机制等;</p></li><li><p>合约层主要封装各类脚本、算法和智能合约,是区块链可编程特性的基础;</p></li><li><p>应用层则封装了区块链的各种应用场景和案例;</p></li><li><p>该模型中,基于时间戳的链式区块结构、分布式节点的共识机制、基于共识算力的经济激励和灵活可编程的智能合约是区块链技术最具代表性的创新点。</p><p><img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwp8os22ohj20f90kwq5z.jpg" alt="1540806631902"></p></li></ul></li></ul></li><li><p>区块链的分类:</p><ul><li><p>区块链目前分为三类:公有区块链(PublicBlockChains)、联合区块链<br>(ConsortiumBlockChains)、私有区块链(privateBlockChains)。其中联合区块链和私有区块链认为是广义的私链。公有区块链是最早的区块链,也是目前应用最广泛的区块链,各大bitcoins系列的虚拟数字货币均基于公有区块链。目前传统金融也开始尝试私有区块链,私链的应用产品还在摸索当中。 </p></li><li><p>区块链的本质是解决信任。公有区块链解决人类不可信,联合区块链解决组织不可信,私有区块链解决队友不可信。</p></li><li><p>区块链出生后,中本聪基于区块链技术推出了比特币。</p></li></ul></li></ol><h2 id="十-区块链的儿子——比特币"><a href="#十-区块链的儿子——比特币" class="headerlink" title="十.区块链的儿子——比特币"></a>十.区块链的儿子——比特币</h2><ol><li><p>区块链的孩子叫做比特币(BitCoin)。比特币的概念最初由中本聪在2009年提出,是基于分布式记账技术的一种数字现金;</p></li><li><p>与大多数货币不同,比特币不依靠特定货币机构发行,它依据特定算法, 通过大量的计算产生,比特币使用整个网络构成的分布式数据库来确认并记录所有的交易行为,并使用密码学的设计来确保货币流通各个环节安全性。</p></li><li><p>基于密码学的设计可以使比特币只能被真实的拥有者转移或支付。这确保了货币所有权与流通交易的匿名性。</p></li><li><p>比特币与其他虚拟货币最大的不同,是其总数量非常有限,具有极强的稀缺性。比特币是模拟黄金来发行的,每4年开采量就会减半,之后的总数量将被永久限制在2100万个。</p></li><li><p>比特币的本质:其实就是一堆复杂算法所生成的特解。</p><ul><li>特解是指方程组所能得到无限个(其实比特币是有限个)解中的一组。而每一个特解都能解开方程并且是唯一的。</li><li>以人民币来比喻的话,比特币就是人民币的序列号,你知道了某张钞票上的序列号,你就拥有了这张钞票。</li><li>而挖矿的过程就是通过庞大的计算量不断的去寻求这个方程组的特解,这个方程组被设计成了只有2100万个特解,所以比特币的上限就是2100万。</li></ul></li><li><p>比特币可以用来兑现,可以兑换成大多数国家的货币。使用者可以用比特币购买一些虚拟物品,只要有人接受,也可以使用比特币购买现实生活当中的物品。</p><p><img src="http://wx3.sinaimg.cn/large/e64a4785gy1fwp947h6qfj20gb09lqfa.jpg" alt="1540807486479"></p></li><li><p>兑换利率</p><ul><li><p>SHA:安全哈希算法(Secure Hash Algorithm,缩写为SHA),能计算出一个数字消息所对应到的长度固定的字符串(又称消息摘要)的算法。</p></li><li><p>SHA家族的五个算法,分别是SHA-1、SHA-224. SHA-256. SHA-384, 和SHA-512,由美国国家安全局(NSA)所设计,并由美国国家标准与技术 研究院(NIST)发布,是美国的政府标准。后四者并称为SHA-2。</p><p>SHA-1在许多安全协定中广为使用,曾被视为是MD5的后继者。但SHA-1的安全性如今被密码学家严重质疑;SHA-2的算法跟SHA-1基本上相似,但是至今尚未出现对SHA-2有效的攻击。</p></li></ul></li></ol><h2 id="十一-区块链的侄子一一ICO"><a href="#十一-区块链的侄子一一ICO" class="headerlink" title="十一.区块链的侄子一一ICO"></a>十一.区块链的侄子一一ICO</h2><ol><li><p>比特币诞生后不久,众筹在与代币结合,然后生下ico。众筹的太太叫代币,代币是比特币的原型,比特币的逻辑;</p></li><li><p>ICO Olnitial Coin Offering缩写),叫做“首次币发行”。ICO是区块链行业术语,他是一种金融行为,源自股票市场的首次公开发行(IPO)概念;</p><ul><li>IPO(英文简称Initial Public Offering)首次公开发行。指股份公司首次向社会公众公开招股的发行方式。与ICO相比,他们有共同点也有区别。</li><li>共同点:都有通过出售股份来筹措资金;都有潜在投资者为了潜在的巨大收益而冒险参与;</li><li>不同点:ICO的大部分支持者是项目爱好者或不专业的投资者;ICO不需要注册经营牌照;ICO平台是第三方中立平台,投资者自担风险。 </li></ul></li><li><p>ICO是一种为加密数字货币筹措资金的常用方式。早期参与者可以从中获得初始产生的加密数字货币作为回报。由于代币具有市场价值,可以兑换成法币,从而支持项目的开发成本。ICO所发行的代币,可以基于不同的区块链。 常见的是基于以太坊(ETH)和比特股(BTS)区块链发行,由区块链提供记账服务和价值共识,实现全球发行和流通;</p></li><li><p>ICO参与者对于一个项目的成功非常重要,他们会在社区里为该区块链项目进行宣传,使它产生的代币在开始交易前就获得流动性。但ICO的参与者最看重的依然是由项目发展或代币发行后价格升值带来的潜在收益;</p></li><li><p>ICO给全世界和区块链家族,造成了特别大的困扰,就是他能够在没有任何 的实际项目执行的情况下,很快就融到一大笔比特币、以太币,或者其他代币。所以缺乏监管体系,缺乏风险管理。</p><p><img src="http://ws2.sinaimg.cn/large/e64a4785gy1fwp91v2339j20gh099k31.jpg" alt="1540807376924"></p></li></ol><h2 id="十二-区块链未来的八弟——DAO"><a href="#十二-区块链未来的八弟——DAO" class="headerlink" title="十二.区块链未来的八弟——DAO"></a>十二.区块链未来的八弟——DAO</h2><ol><li>区块链未来的弟弟,他的名字叫Decentralized autonomous organizations,简称DAO,就是去中心化的组织,或者叫做分布式自治组织;</li><li>过去人类的组织形态,都是有管理者的层级组织。比如一个公司有CEO,再往下是高层、中层,一直到员工。这个组织形态,其实很好用,但是也有问题,就是它的沟通效率低;</li><li>DAO设想让每个组织里面不再有一个所谓的管理层,而是自我沟通,通过效率的方式直接连接,就很有可能会提高全人类的组织效率。</li></ol>]]></content>
<categories>
<category> 区块链 </category>
</categories>
<tags>
<tag> blockchain </tag>
</tags>
</entry>
<entry>
<title>Go语言发展历史</title>
<link href="/posts/d8c1eece.html"/>
<url>/posts/d8c1eece.html</url>
<content type="html"><![CDATA[<h2 id="一-Go语言发展历史"><a href="#一-Go语言发展历史" class="headerlink" title="一. Go语言发展历史"></a>一. Go语言发展历史</h2><h4 id="一-知名编程语⾔言或系统的发展简史"><a href="#一-知名编程语⾔言或系统的发展简史" class="headerlink" title="(一). 知名编程语⾔言或系统的发展简史"></a>(一). 知名编程语⾔言或系统的发展简史</h4><ol><li><p>B语言之父:Ken Thompson(肯.汤普森)。该语言得名于汤姆森的妻子Bonnie,一门剑桥于60年代中期开发的语言。</p></li><li><p>C语言之父:美国著名计算机专家、C语言发明人、UNIX之父Dennis Ritchie(丹尼斯·里奇)在1969-1973年期间发明了了C语言和Unix操作系统。</p><p><img src="http://i68.tinypic.com/dfk0uw.png" alt=""></p></li><li><p>Unix之父:Dennis Ritchie(丹尼斯·里奇)及Ken Thompson(肯.汤普森)在73年左右发明了Unix操作系统。两人因此获得1983年图灵奖。</p></li><li><p>C++之父:Bjarne Stroustrup(本贾尼·斯特劳斯特卢普)。1982年,美国贝尔实验室Bjarne Stroustrup博士在C语言的基础上引入并扩充了了面向对象的概念,发明了—种新的程序语言。为了表达该语言与c语言的渊源关系,它被命名为C++。</p></li><li><p>Python之父:Guido von Rossum(吉多.范.罗苏姆)。1989年,为了打发圣诞节假期,Guido开始写Python语言的编译/解释器。1994年发布1.0版本。1995年9月发布了Python3.5版。</p></li><li><p>Java:James Gosling(詹姆斯.高斯林)。1991年开发Oak,1994年更名为Java。1995年5月正式发布。</p></li><li><p>Javascript:Brendan Eich(布兰登.艾奇)。艾奇对Java⼀一点兴趣也没有,为了应付公司安排的任务,他于1995年5月只用10天时间就把Javascript设计出来了。</p></li><li><p>Go语言:Go的三个作者分别是:Robert Griesemer(罗伯特.格利茨默),Rob Pike(罗伯派克) 和 Ken Thompson(肯.汤普森)。</p><ul><li><p>Robert在开发Go之前是Google V8、Chubby和HotSpot JVM的主要贡献者;</p></li><li><p>Rob主要是Unix、UTF-8、plan9的作者</p></li><li><p>Ken主要是B语言、C语言的作者、Unix之父。</p><p><img src="http://i67.tinypic.com/1qijab.png" alt=""> </p></li></ul></li></ol><h4 id="二-Go语⾔言主要发展过程"><a href="#二-Go语⾔言主要发展过程" class="headerlink" title="(二). Go语⾔言主要发展过程"></a>(二). Go语⾔言主要发展过程</h4><ol><li><p>2007年9月,Rob Pike(罗伯.派克) 正式命名为Go;</p></li><li><p>2008年5月,Google全力支持该项⽬目;</p></li><li><p>2009年11月,Go将代码全部开源,它获得了当年的年度语言</p></li><li><p>2012年3月28日,Go发布第⼀一个正式的稳定版本。</p><ul><li><p>Go稳定版发布时,Go Team承诺后续的版本都会兼容之前的版本。这对于开发者来说非常重要,Go后续的版本也⼀一直在提升内功,从⽽而可以让用户无缝的升级Go版本。</p><p><img src="http://i66.tinypic.com/34s341w.png" alt=""> </p><p><img src="http://i63.tinypic.com/nyejk9.png" alt=""> </p></li></ul></li></ol><h2 id="二-Go语⾔言的特点及优势"><a href="#二-Go语⾔言的特点及优势" class="headerlink" title="二. Go语⾔言的特点及优势"></a>二. Go语⾔言的特点及优势</h2><h4 id="一-Go语⾔言设计初衷(为什什么会设计Go语⾔言?)"><a href="#一-Go语⾔言设计初衷(为什什么会设计Go语⾔言?)" class="headerlink" title="(一). Go语⾔言设计初衷(为什什么会设计Go语⾔言?)"></a>(一). Go语⾔言设计初衷(为什什么会设计Go语⾔言?)</h4><ol><li><p>设计Go语⾔是为了解决当时Google开发遇到的问题:</p><p>♥ ⼤量的C++代码,同时⼜引⼊了Java和Python</p><p>♥ 成千上万的⼯程师</p><p>♥ 数以万计⾏的代码</p><p>♥ 分布式的编译系统</p><p>♥ 数百万的服务器</p></li><li><p>Google开发中的痛点:</p><p>♠ 编译慢</p><p>♠ 失控的依赖</p><p>♠ 每个⼯程师只是⽤了⼀个语⾔⾥⾯的⼀部分</p><p>♠ 程序难以维护(可读性差、⽂档不清晰等)</p><p>♠ 更新的花费越来越⻓</p><p>♠ 交叉编译困难</p></li><li><p>如何解决当前的问题和痛点?</p><p>♣ Go希望成为互联⽹时代的C语⾔。多数系统级语⾔(包括Java和C#)的根本编程哲学来源于C++,将C++的⾯向对象进⼀步发扬光⼤。但是Go语⾔的设计者却有不同的看法,他们认为值得学习的是C语⾔。C语⾔经久不衰的根源是它⾜够简单。因此,Go语⾔也是⾜够简单。</p><p>♣ 所以,他们当时设计Go的⽬标是为了消除各种缓慢和笨重、改进各种低效和扩展性。Go是由那些开发⼤型系统的⼈设计的,同时也是为了这些⼈服务的;它是为了解决⼯程上的问题,不是为了研究语⾔设计;它还是为了让我们的编程变得更舒适和⽅便。</p><p>♣ 但是结合Google当时内部的⼀些现实情况,如很多⼯程师都是C系的,所以新设计的语⾔⼀定要易学习,最好是类似C的语⾔;20年没有出新的语⾔<br>了,所以新设计的语⾔必须是现代化的(例如内置GC)等情况。最后根据实战经验,他们向着⽬标设计了Go这个语⾔。</p></li><li><p>Go语⾔的特⾊:</p><p>♥ 没有继承多态的⾯向对象</p><p>♥ 强⼀致类型</p><p>♥ interface不需要显式声明(Duck Typing)</p><p>♥ 没有异常处理(Error is value)</p><p>♥ 基于⾸字⺟的可访问特性</p><p>♥ 不⽤的import或者变量引起编译错误</p><p>♥ 完整⽽卓越的标准库包</p><p>♥ Go内置runtime(作⽤是性能监控、垃圾回收等)</p></li></ol><h4 id="二-Go语⾔的优势"><a href="#二-Go语⾔的优势" class="headerlink" title="(二). Go语⾔的优势"></a>(二). Go语⾔的优势</h4><ol><li><p>学习曲线容易</p><p>Go语⾔语法简单,包含了类C语法。因为Go语⾔容易学习,所以⼀个普通的⼤学⽣花⼏个星期就能写出来可以上⼿的、⾼性能的应⽤。在国内⼤家都追求快,这也是为什么国内Go流⾏的原因之⼀。</p></li><li><p>效率:</p><p>快速的编译时间,开发效率和运⾏效率⾼开发过程中相较于 Java 和 C++呆滞的编译速度,Go 的快速编译时间是⼀个主要的效率优势。Go拥有接近C的运⾏效率和接近PHP的开发效率。</p></li><li><p>出身名⻔、⾎统纯正</p><p>之所以说Go出身名⻔,从Go语⾔的创造者就可⻅端倪,Go语⾔绝对⾎统纯正。其次Go语⾔出⾃Google公司,Google在业界的知名度和实⼒⾃然不⽤多说。Google公司聚集了⼀批⽜⼈,在各种编程语⾔称雄争霸的局⾯下推出新的编程语⾔,⾃然有它的战略考虑。⽽且从Go语⾔的发展态势来看,Google对它这个新的宠⼉还是很看重的,Go⾃然有⼀个良好的发展前途。</p></li><li><p>⾃由⾼效:组合的思想、⽆侵⼊式的接⼝</p><p>Go语⾔可以说是开发效率和运⾏效率⼆者的完美融合,天⽣的并发编程⽀持。Go语⾔⽀持当前所有的编程范式,包括过程式编程、⾯向对象编程、⾯向接⼝编程、函数式编程。程序员们可以各取所需、⾃由组合、想怎么玩就怎么玩。</p></li><li><p>强⼤的标准库</p><p>这包括互联⽹应⽤、系统编程和⽹络编程。Go⾥⾯的标准库基本上已经是⾮常稳定了,特别是我这⾥提到的三个,⽹络层、系统层的库⾮常实⽤。</p></li><li><p>部署⽅便:⼆进制⽂件,Copy部署</p><p>这⼀点是很多⼈选择Go的最⼤理由,因为部署太⽅便了,所以现在也有很多⼈⽤Go开发运维程序。</p></li><li><p>简单的并发</p><p>Go 是⼀种⾮常⾼效的语⾔,⾼度⽀持并发性。Go是为⼤数据、微服务、并发⽽⽣的⼀种编程语⾔。</p><p>Go 作为⼀⻔语⾔致⼒于使事情简单化。它并未引⼊很多新概念,⽽是聚焦于打造⼀⻔简单的语⾔,它使⽤起来异常快速并且简单。其唯⼀的创新之处是 goroutines 和通道。Goroutines 是 Go ⾯向线程的轻量级⽅法,⽽通道是 goroutines 之间通信的优先⽅式。</p><p>创建 Goroutines 的成本很低,只需⼏千个字节的额外内存,正由于此,才使得同时运⾏数百个甚⾄数千个 goroutines 成为可能。可以借助通道实现 goroutines 之间的通信。Goroutines 以及基于通道的并发性⽅法使其⾮常容易使⽤所有可⽤的 CPU 内核,并处理并发的 IO。相较于Python/Java,在⼀个 goroutine 上运⾏⼀个函数需要最⼩的代码。</p></li><li><p>稳定性</p><p>Go拥有强⼤的编译检查、严格的编码规范和完整的软件⽣命周期⼯具,具<br>有很强的稳定性,稳定压倒⼀切。那么为什么Go相⽐于其他程序会更稳定呢?这是因为Go提供了软件⽣命周期(开发、测试、部署、维护等等)的各个环节的⼯具,如go tool、gofmt、go test。</p></li></ol><h4 id="三-Go语⾔的核⼼特性和优势"><a href="#三-Go语⾔的核⼼特性和优势" class="headerlink" title="(三). Go语⾔的核⼼特性和优势"></a>(三). Go语⾔的核⼼特性和优势</h4><ul><li>Go主要有静态语⾔、函数多返回值、天⽣并发、内置GC(⾃动垃圾回收)、安全性⾼、语法简单、编译快速这⼏个⽅⾯的特性。这些特性决定了Go的三个⾼富帅特性:运⾏快、开发快和部署快。<ul><li>静态类型语⾔是指在编译时变量的数据类型即可确定的语⾔,要求在使⽤变量之前必须声明数据类型(具有类型推导能⼒的现代语⾔可能能够部分减轻这个要求);</li><li>动态类型语⾔是在运⾏时确定数据类型的语⾔,变量使⽤之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。</li><li>Go语⾔是⽬前项⽬转型⾸选的语⾔,也是软件⼯程师转型⾸选的语⾔,是添加技术栈的⾸选语⾔。Go常常是⼀种为转型⽽量身定制的语⾔。</li></ul></li></ul><h4 id="四-Go语⾔能开发什么?"><a href="#四-Go语⾔能开发什么?" class="headerlink" title="(四). Go语⾔能开发什么?"></a>(四). Go语⾔能开发什么?</h4><ol><li>服务器编程,以前你如果使⽤C或者C++做的那些事情,⽤Go来做很合适,例如处理⽇志、数据打包、虚拟机处理、⽂件系统等。</li><li>分布式系统、数据库代理器、中间件等,例如Etcd。</li><li>⽹络编程,这⼀块⽬前应⽤最⼴,包括Web应⽤、API应⽤、下载应⽤,⽽且Go内置的net/http包基本上把我们平常⽤到的⽹络功能都实现了。</li><li>数据库操作</li><li>开发云平台,⽬前国外很多云平台在采⽤Go开发</li></ol><h4 id="五-采⽤Go语⾔的国内外知名企业"><a href="#五-采⽤Go语⾔的国内外知名企业" class="headerlink" title="(五). 采⽤Go语⾔的国内外知名企业"></a>(五). 采⽤Go语⾔的国内外知名企业</h4><ol><li>Go发布之后,很多公司特别是云计算公司开始⽤Go重构他们的基础架构,很多都是直接采⽤Go进⾏了开发,最近热⽕朝天的Docker就是采⽤Go开发的;</li><li>采⽤Go的⼀些国外公司,如Google、Docker、Apple、Cloud FoundryCloudFlare、Couchbase、CoreOS、Dropbox、MongoDB、AWS等公司;</li><li>采⽤Go开发的国内企业:如阿⾥云CDN、百度、⼩⽶、七⽜、PingCAP、华为、⾦⼭软件、猎豹移动、饿了么等公司。</li></ol><h2 id="三-Go开发⽂档"><a href="#三-Go开发⽂档" class="headerlink" title="三. Go开发⽂档"></a>三. Go开发⽂档</h2><p><a href="https://www.studygolang.com/pkgdoc" rel="external nofollow noopener noreferrer" target="_blank">https://www.studygolang.com/pkgdoc</a></p><p><img src="http://ws3.sinaimg.cn/large/e64a4785gy1fwu32h87p7j21sg146gvf.jpg" alt="1541168562456"></p>]]></content>
<categories>
<category> 后端 </category>
</categories>
<tags>
<tag> GoLang </tag>
</tags>
</entry>
<entry>
<title>IRIS-Web框架</title>
<link href="/posts/166128a5.html"/>
<url>/posts/166128a5.html</url>
<content type="html"><![CDATA[<blockquote><p> HelloWord</p></blockquote><p>Iris的理念是为HTTP提供强大的工具,使其成为单页面应用程序,网站,混合或公共HTTP API的理想解决方案。请注意,到目前为止,虹膜是有史以来在性能方面创建的最快的Web框架。<br>Iris不会强迫您使用任何特定的ORM或模板引擎。通过支持最常用的模板引擎,您可以快速制作出完美的应用程序。</p><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main<span class="token keyword">import</span> <span class="token punctuation">(</span> <span class="token string">"github.com/kataras/iris"</span><span class="token punctuation">)</span><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> app <span class="token operator">:=</span> iris<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//app.Use(logger.New())</span> htmlEngine <span class="token operator">:=</span> iris<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span><span class="token string">"./"</span><span class="token punctuation">,</span> <span class="token string">".html"</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//htmlEngine.Reload(false)</span> app<span class="token punctuation">.</span><span class="token function">RegisterView</span><span class="token punctuation">(</span>htmlEngine<span class="token punctuation">)</span> app<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>ctx iris<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span> ctx<span class="token punctuation">.</span><span class="token function">WriteString</span><span class="token punctuation">(</span><span class="token string">"Hello world! -- from iris."</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> app<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"/hello"</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>ctx iris<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span> ctx<span class="token punctuation">.</span><span class="token function">ViewData</span><span class="token punctuation">(</span><span class="token string">"Title"</span><span class="token punctuation">,</span> <span class="token string">"测试页面"</span><span class="token punctuation">)</span> ctx<span class="token punctuation">.</span><span class="token function">ViewData</span><span class="token punctuation">(</span><span class="token string">"Content"</span><span class="token punctuation">,</span> <span class="token string">"Hello world! -- from template"</span><span class="token punctuation">)</span> ctx<span class="token punctuation">.</span><span class="token function">View</span><span class="token punctuation">(</span><span class="token string">"hello.html"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> app<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span>iris<span class="token punctuation">.</span><span class="token function">Addr</span><span class="token punctuation">(</span><span class="token string">":8080"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> iris<span class="token punctuation">.</span><span class="token function">WithCharset</span><span class="token punctuation">(</span><span class="token string">"UTF-8"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span></code></pre><blockquote><p> <strong>Xorm</strong></p></blockquote><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main<span class="token keyword">import</span> <span class="token punctuation">(</span> <span class="token string">"log"</span> <span class="token string">"fmt"</span> <span class="token string">"github.com/go-xorm/xorm"</span> <span class="token boolean">_</span> <span class="token string">"github.com/go-sql-driver/mysql"</span> <span class="token string">"time"</span><span class="token punctuation">)</span><span class="token keyword">const</span> DriverName <span class="token operator">=</span> <span class="token string">"mysql"</span><span class="token keyword">const</span> MasterDataSourceName <span class="token operator">=</span> <span class="token string">"root:root@tcp(127.0.0.1:3306)/dbiris?charset=utf8"</span><span class="token comment" spellcheck="true">/**CREATE TABLE `user_info` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', `name` varchar(50) NOT NULL DEFAULT '' COMMENT '中文名', `sys_created` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', `sys_updated` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最后修改时间', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; */</span> <span class="token keyword">type</span> UserInfo <span class="token keyword">struct</span> <span class="token punctuation">{</span> Id <span class="token builtin">int</span> <span class="token string">`xorm:"not null pk autoincr"`</span> Name <span class="token builtin">string</span> SysCreated <span class="token builtin">int</span> SysUpdated <span class="token builtin">int</span><span class="token punctuation">}</span><span class="token keyword">var</span> engine <span class="token operator">*</span>xorm<span class="token punctuation">.</span>Engine<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> engine <span class="token operator">=</span> <span class="token function">newEngin</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//execute()</span> <span class="token comment" spellcheck="true">//ormInsert()</span> <span class="token comment" spellcheck="true">//query()</span> <span class="token comment" spellcheck="true">//ormGet()</span> <span class="token comment" spellcheck="true">//ormGetCols()</span> <span class="token comment" spellcheck="true">//ormCount()</span> <span class="token function">ormFindRows</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//ormUpdate()</span> <span class="token comment" spellcheck="true">//ormOmitUpdate()</span> <span class="token comment" spellcheck="true">//ormMustColsUpdate()</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 连接到数据库</span><span class="token keyword">func</span> <span class="token function">newEngin</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span>xorm<span class="token punctuation">.</span>Engine <span class="token punctuation">{</span> engine<span class="token punctuation">,</span> err <span class="token operator">:=</span> xorm<span class="token punctuation">.</span><span class="token function">NewEngine</span><span class="token punctuation">(</span>DriverName<span class="token punctuation">,</span> MasterDataSourceName<span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>newEngin<span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">// Debug模式,打印全部的SQL语句,帮助对比,看ORM与SQL执行的对照关系</span> engine<span class="token punctuation">.</span><span class="token function">ShowSQL</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token keyword">return</span> engine<span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 通过query方法查询</span><span class="token keyword">func</span> <span class="token function">query</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sql <span class="token operator">:=</span> <span class="token string">"SELECT * FROM user_info"</span> <span class="token comment" spellcheck="true">//results, err := engine.Query(sql)</span> <span class="token comment" spellcheck="true">//results, err := engine.QueryInterface(sql)</span> results<span class="token punctuation">,</span> err <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">QueryString</span><span class="token punctuation">(</span>sql<span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span><span class="token string">"query"</span><span class="token punctuation">,</span> sql<span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> total <span class="token operator">:=</span> <span class="token function">len</span><span class="token punctuation">(</span>results<span class="token punctuation">)</span> <span class="token keyword">if</span> total <span class="token operator">==</span> <span class="token number">0</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"没有任何数据"</span><span class="token punctuation">,</span> sql<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> i<span class="token punctuation">,</span> data <span class="token operator">:=</span> <span class="token keyword">range</span> results <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"%d = %v\n"</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span> data<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 通过execute方法执行更新</span><span class="token keyword">func</span> <span class="token function">execute</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sql <span class="token operator">:=</span> <span class="token string">`INSERT INTO user_info values(NULL, 'name', 0, 0)`</span> affected<span class="token punctuation">,</span> err <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">Exec</span><span class="token punctuation">(</span>sql<span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span><span class="token string">"execute error"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> id<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> affected<span class="token punctuation">.</span><span class="token function">LastInsertId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> rows<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> affected<span class="token punctuation">.</span><span class="token function">RowsAffected</span><span class="token punctuation">(</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"execute id="</span><span class="token punctuation">,</span> id<span class="token punctuation">,</span> <span class="token string">", rows="</span><span class="token punctuation">,</span> rows<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 根据models的结构映射数据表</span><span class="token keyword">func</span> <span class="token function">ormInsert</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> UserInfo <span class="token operator">:=</span> <span class="token operator">&</span>UserInfo<span class="token punctuation">{</span> Id<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> Name<span class="token punctuation">:</span> <span class="token string">"梅西"</span><span class="token punctuation">,</span> SysCreated<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> SysUpdated<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> id<span class="token punctuation">,</span> err <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">Insert</span><span class="token punctuation">(</span>UserInfo<span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span><span class="token string">"ormInsert error"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"ormInsert id="</span><span class="token punctuation">,</span> id<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"%v\n"</span><span class="token punctuation">,</span> <span class="token operator">*</span>UserInfo<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 根据models的结构读取数据</span><span class="token keyword">func</span> <span class="token function">ormGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> UserInfo <span class="token operator">:=</span> <span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>Id<span class="token punctuation">:</span><span class="token number">2</span><span class="token punctuation">}</span> ok<span class="token punctuation">,</span> err <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>UserInfo<span class="token punctuation">)</span> <span class="token keyword">if</span> ok <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"%v\n"</span><span class="token punctuation">,</span> <span class="token operator">*</span>UserInfo<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span><span class="token string">"ormGet error"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"orgGet empty id="</span><span class="token punctuation">,</span> UserInfo<span class="token punctuation">.</span>Id<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 获取指定的字段</span><span class="token keyword">func</span> <span class="token function">ormGetCols</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> UserInfo <span class="token operator">:=</span> <span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>Id<span class="token punctuation">:</span><span class="token number">2</span><span class="token punctuation">}</span> ok<span class="token punctuation">,</span> err <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">Cols</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>UserInfo<span class="token punctuation">)</span> <span class="token keyword">if</span> ok <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"%v\n"</span><span class="token punctuation">,</span> UserInfo<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span><span class="token string">"ormGetCols error"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"ormGetCols empty id=2"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 统计</span><span class="token keyword">func</span> <span class="token function">ormCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">//count, err := engine.Count(&UserInfo{})</span> <span class="token comment" spellcheck="true">//count, err := engine.Where("name_zh=?", "梅西").Count(&UserInfo{})</span> count<span class="token punctuation">,</span> err <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">Count</span><span class="token punctuation">(</span><span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>Name<span class="token punctuation">:</span><span class="token string">"梅西"</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"count=%v\n"</span><span class="token punctuation">,</span> count<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span><span class="token string">"ormCount error"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 查找多行数据</span><span class="token keyword">func</span> <span class="token function">ormFindRows</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> list <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span>UserInfo<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//list := make(map[int]UserInfo)</span> <span class="token comment" spellcheck="true">//err := engine.Find(&list)</span> <span class="token comment" spellcheck="true">//err := engine.Where("id>?", 1).Limit(100, 0).Find(&list)</span> err <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">Cols</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Where</span><span class="token punctuation">(</span><span class="token string">"id>?"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">.</span> <span class="token function">Limit</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Asc</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">,</span> <span class="token string">"sys_created"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Find</span><span class="token punctuation">(</span><span class="token operator">&</span>list<span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//list := make([]map[string]string, 0)</span> <span class="token comment" spellcheck="true">//err := engine.Table("star_info").Cols("id", "name_zh", "name_en").</span> <span class="token comment" spellcheck="true">// Where("id>?", 1).Find(&list)</span> <span class="token keyword">if</span> err <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"%v\n"</span><span class="token punctuation">,</span> list<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span><span class="token string">"ormFindRows error"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 更新一个数据</span><span class="token keyword">func</span> <span class="token function">ormUpdate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">// 全部更新</span> <span class="token comment" spellcheck="true">//UserInfo := &UserInfo{NameZh:"测试名"}</span> <span class="token comment" spellcheck="true">//ok, err := engine.Update(UserInfo)</span> <span class="token comment" spellcheck="true">// 指定ID更新</span> UserInfo <span class="token operator">:=</span> <span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>Name<span class="token punctuation">:</span><span class="token string">"梅西"</span><span class="token punctuation">}</span> ok<span class="token punctuation">,</span> err <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">ID</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Update</span><span class="token punctuation">(</span>UserInfo<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>ok<span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 排除某字段</span><span class="token keyword">func</span> <span class="token function">ormOmitUpdate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> info <span class="token operator">:=</span> <span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>Id<span class="token punctuation">:</span><span class="token number">1</span><span class="token punctuation">}</span> ok<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>info<span class="token punctuation">)</span> <span class="token keyword">if</span> ok <span class="token punctuation">{</span> <span class="token keyword">if</span> info<span class="token punctuation">.</span>SysCreated <span class="token operator">></span> <span class="token number">0</span> <span class="token punctuation">{</span> ok<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">ID</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>Id<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Omit</span><span class="token punctuation">(</span><span class="token string">"sys_created"</span><span class="token punctuation">)</span><span class="token punctuation">.</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>SysCreated<span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">,</span> SysUpdated<span class="token punctuation">:</span><span class="token function">int</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Unix</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"ormOmitUpdate, rows=%d, "</span> <span class="token operator">+</span> <span class="token string">"sys_created=%d\n"</span><span class="token punctuation">,</span> ok<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> ok<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">ID</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>Id<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Omit</span><span class="token punctuation">(</span><span class="token string">"sys_created"</span><span class="token punctuation">)</span><span class="token punctuation">.</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>SysCreated<span class="token punctuation">:</span><span class="token number">1</span><span class="token punctuation">,</span> SysUpdated<span class="token punctuation">:</span><span class="token function">int</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Unix</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"ormOmitUpdate, rows=%d, "</span> <span class="token operator">+</span> <span class="token string">"sys_created=%d\n"</span><span class="token punctuation">,</span> ok<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 字段为空也可以更新(0, 空字符串等)</span><span class="token keyword">func</span> <span class="token function">ormMustColsUpdate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> info <span class="token operator">:=</span> <span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>Id<span class="token punctuation">:</span><span class="token number">1</span><span class="token punctuation">}</span> ok<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>info<span class="token punctuation">)</span> <span class="token keyword">if</span> ok <span class="token punctuation">{</span> <span class="token keyword">if</span> info<span class="token punctuation">.</span>SysCreated <span class="token operator">></span> <span class="token number">0</span> <span class="token punctuation">{</span> ok<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">ID</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>Id<span class="token punctuation">)</span><span class="token punctuation">.</span> <span class="token function">MustCols</span><span class="token punctuation">(</span><span class="token string">"sys_created"</span><span class="token punctuation">)</span><span class="token punctuation">.</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>SysCreated<span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">,</span> SysUpdated<span class="token punctuation">:</span><span class="token function">int</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Unix</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"ormMustColsUpdate, rows=%d, "</span> <span class="token operator">+</span> <span class="token string">"sys_created=%d\n"</span><span class="token punctuation">,</span> ok<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> ok<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> engine<span class="token punctuation">.</span><span class="token function">ID</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>Id<span class="token punctuation">)</span><span class="token punctuation">.</span> <span class="token function">MustCols</span><span class="token punctuation">(</span><span class="token string">"sys_created"</span><span class="token punctuation">)</span><span class="token punctuation">.</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token operator">&</span>UserInfo<span class="token punctuation">{</span>SysCreated<span class="token punctuation">:</span><span class="token number">1</span><span class="token punctuation">,</span> SysUpdated<span class="token punctuation">:</span><span class="token function">int</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Unix</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"ormMustColsUpdate, rows=%d, "</span> <span class="token operator">+</span> <span class="token string">"sys_created=%d\n"</span><span class="token punctuation">,</span> ok<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre>]]></content>
<categories>
<category> 后端 </category>
</categories>
<tags>
<tag> GoLang </tag>
<tag> IRIS </tag>
</tags>
</entry>
<entry>
<title>Go实现加密算法</title>
<link href="/posts/6b392a9d.html"/>
<url>/posts/6b392a9d.html</url>
<content type="html"><![CDATA[<blockquote><p>Go语⾔实现加密算法</p></blockquote><h4 id="⼀、哈希算法"><a href="#⼀、哈希算法" class="headerlink" title="⼀、哈希算法"></a>⼀、哈希算法</h4><h5 id="(⼀)、Hash的定义"><a href="#(⼀)、Hash的定义" class="headerlink" title="(⼀)、Hash的定义"></a>(⼀)、Hash的定义</h5><p>1、hash的单词意思<br> n.剁碎的⻝⾷食物; 蔬菜⾁丁<br> vt.把…弄乱; 切碎;<br>2、hash(哈希或散列)算法是信息技术领域⾮常基础也⾮常重要的技术。它能任意长度的⼆进制值(明⽂)映射为较短的固定长度的⼆进制值(Hash值), 并且不同的明⽂很难映射为相同的Hash值。hash值在应⽤中⼜被称为数字指纹(fingerprint)或数字摘要(digest)、消息摘要。<br> 例如计算⼀段话“hello blockchain”的 MD5 hash 值为 78e6a8bcdef7a4a254c16054b082c783<br> 这意味着我们只要对某⽂件进⾏ MD5 Hash 计算,得到结果为 78e6a8bcdef7a4a254c16054b082c783,这就说明⽂件内容极⼤概率上就 是 “hello blockchain”。可见,Hash的核⼼思想⼗分类似于基于内容的编址 或命名。<br>3、⼀个优秀的hash算法,将能实现:<br> 正向快速:给定明⽂和hash算法,在有限时间和有限资源内能计算出hash值。<br> 逆向困难:给定(若⼲)hash值,在有限时间内很难(基本不可能)逆推出明⽂。<br> 输⼊敏感:原始输⼊信息修改⼀点信息,产⽣的hash值看起来应该都有很⼤不同。<br> 抗冲突:对不同的关键字可能得到同⼀散列地址,或者说两段内容不同的明⽂,它们的hash值可能⼀致。这种现象称冲突或者碰撞。具有相同函数值的关键字对该散列函数来说称做同义词。 抗冲突⼜称为“抗碰撞性”或冲突避免。哈希函数抗冲突就是不同的输⼊不能产⽣相同的输出。 抗冲突并不是不会有冲突,只不过找到有冲突的两个输⼊的代价⾮常 ⼤。就好像暴⼒破解⼀个有效期为20年的密码,整个破解过程或许⻓长达30年。这样虽然最后密码被破解了,但是也失去意义了。</p><h5 id="(⼆)、流⾏的哈希算法"><a href="#(⼆)、流⾏的哈希算法" class="headerlink" title="(⼆)、流⾏的哈希算法"></a>(⼆)、流⾏的哈希算法</h5><p> <code>⽬前流⾏的 Hash 算法包括 MD5、SHA-1 和 SHA-2系列(SHA-224、 SHA-256、SHA-384,和 SHA-512 )。</code></p><p>1、MD4 MD4(RFC 1320)是MIT (Massachusetts Institute of Technology , 麻州理⼯⼤学)的Ronald L. Rivest(荣获2002年图灵奖)在1990年设计的,MD是Message Digest的缩写。其输出为128位。<br>2、MD5<br> MD5(RFC 1321)是 Rivest 于1991年对 MD4 的改进版本。其输出是128位。MD5 ⽐ MD4 复杂,并且计算速度要慢⼀点,更安全⼀些。MD5 已被证明不具备“强抗碰撞性”。<br> MD5 是⼀个经典的 hash 算法,其和SHA-1 算法都已被证明安全性不⾜应⽤于商业场景。</p><p><img src="https://wx1.sinaimg.cn/large/e64a4785gy1fxq0oyl00kj20z00gmdp0.jpg" alt=""></p><p>3、SHA<br> SHA (Secure Hash Algorithm, [sɪ’kjʊǝ(r)][‘ælɡǝrɪðǝm] ,加密哈希算法)是⼀个Hash函数族,由 NIST(National Institute of Standards and Technology , 美国国家标准技术研究所)于 1993 年发布第⼀个算法。 SHA-1 在 1995 年⾯世,它的输出为⻓长度 160 位的 hash 值,SHA-1 设计时 基于和 MD4 相同原理,SHA-1 已被证明不具备“强抗碰撞性”。为了提⾼安全性,NIST 还设计出了 SHA-224、SHA-256、SHA-384, 和 SHA-512 算法(统称为 SHA-2),跟 SHA-1 算法原理类似。⽬前,⼀般认为 MD5 和 SHA1 已经不够安全,推荐⾄少使⽤ SHA-256 算法。</p><p>4、RIPEMD-160(RACE Integrity Primitives Evaluation Message Digest 160 , RACE完整的原始评估信息摘要 ) 是⼀个160位的加密哈希函数,旨在替代128位哈希函数MD4、MD5。</p><p>5、各种hash算法后的⻓长度<br> md5(‘1’) ,128位⻓长度,16字节 c4ca4238a0b923820dcc509a6f75849b //32位16进制数字<br> SHA1(‘1’) ,160位⻓长度,20字节<br> 356a192b7913b04c54574d18c28d46e6395428ab //40位16进制数字<br> RIPEMD-160(‘1’) ,160位⻓长度,20字节<br> c47907abd2a80492ca9388b05c0e382518ff3960 //40位16进制数字<br> SHA256(‘1’) ,256位⻓长度,32字节<br> 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b //64位16进制数字<br> SHA512(‘1’) ,512位⻓长度,64字节<br> 4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a2 80433ed6fa46510a //128位16进制数字</p>]]></content>
<categories>
<category> 密码学 </category>
</categories>
<tags>
<tag> GoLang </tag>
<tag> 加密算法 </tag>
</tags>
</entry>
<entry>
<title>Go—运算符</title>
<link href="/posts/d3d8daef.html"/>
<url>/posts/d3d8daef.html</url>
<content type="html"><![CDATA[<blockquote><p> <strong>Go</strong>语⾔基本语法<strong>——</strong>运算符</p></blockquote><h4 id="⼀、Go-语⾔运算符"><a href="#⼀、Go-语⾔运算符" class="headerlink" title="⼀、Go 语⾔运算符"></a>⼀、Go 语⾔运算符</h4><h5 id="(⼀)、算术运算符-(Arithmetic-operator)"><a href="#(⼀)、算术运算符-(Arithmetic-operator)" class="headerlink" title="(⼀)、算术运算符 (Arithmetic operator)"></a>(⼀)、算术运算符 (Arithmetic operator)</h5><p> 下表列出了所有Go语⾔的算术运算符。假定 A 值为 10,B 值为 20。<img src="https://wx1.sinaimg.cn/large/e64a4785gy1fxpxrglbsnj20uw0kwju0.jpg" alt=""></p><p> 以下实例演示了各个算术运算符的⽤法:</p><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main<span class="token keyword">import</span> <span class="token string">"fmt"</span><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> a <span class="token builtin">int</span> <span class="token operator">=</span> <span class="token number">21</span> <span class="token keyword">var</span> b <span class="token builtin">int</span> <span class="token operator">=</span> <span class="token number">10</span> <span class="token keyword">var</span> c <span class="token builtin">int</span> c <span class="token operator">=</span> a <span class="token operator">+</span> b fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第⼀⾏ - c 的值为 %d\n"</span><span class="token punctuation">,</span> c <span class="token punctuation">)</span> c <span class="token operator">=</span> a <span class="token operator">-</span> b fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第二⾏ - c 的值为 %d\n"</span><span class="token punctuation">,</span> c <span class="token punctuation">)</span> c <span class="token operator">=</span> a <span class="token operator">*</span> b fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第三⾏ - c 的值为 %d\n"</span><span class="token punctuation">,</span> c <span class="token punctuation">)</span> c <span class="token operator">=</span> a <span class="token operator">/</span> b fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第四⾏ - c 的值为 %d\n"</span><span class="token punctuation">,</span> c <span class="token punctuation">)</span> c <span class="token operator">=</span> a <span class="token operator">%</span> b fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第五⾏ - c 的值为 %d\n"</span><span class="token punctuation">,</span> c <span class="token punctuation">)</span> a<span class="token operator">++</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第六⾏ - c 的值为 %d\n"</span><span class="token punctuation">,</span> a <span class="token punctuation">)</span> a <span class="token operator">=</span> <span class="token number">21</span> <span class="token comment" spellcheck="true">// 为了⽅便测试,a 这⾥重新赋值为 21</span> a<span class="token operator">--</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第七⾏ - c 的值为 %d\n"</span><span class="token punctuation">,</span> a <span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token comment" spellcheck="true">//以上实例运⾏结果:31 11 210 2 1 22 20</span></code></pre><h5 id="(⼆)、关系运算符(Relational-operator)"><a href="#(⼆)、关系运算符(Relational-operator)" class="headerlink" title="(⼆)、关系运算符(Relational operator)"></a>(⼆)、关系运算符(<strong>Relational</strong> <strong>operator</strong>)</h5><p> 下表列出了所有Go语⾔的关系运算符。假定 A 值为 10,B 值为 20。<img src="https://wx3.sinaimg.cn/large/e64a4785gy1fxpxtdosi7j20ww0ien18.jpg" alt=""></p><p> 以下实例演示了关系运算符的⽤法:</p><p> </p><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main<span class="token keyword">import</span> <span class="token string">"fmt"</span><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> a <span class="token builtin">int</span> <span class="token operator">=</span> <span class="token number">21</span> <span class="token keyword">var</span> b <span class="token builtin">int</span> <span class="token operator">=</span> <span class="token number">10</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> a <span class="token operator">==</span> b <span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第⼀⾏ - a 等于 b\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第⼀⾏ - a 不等于 b\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> a <span class="token operator"><</span> b <span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第⼆⾏ - a ⼩于 b\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第⼆⾏ - a 不⼩于 b\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> a <span class="token operator">></span> b <span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第三⾏ - a ⼤于 b\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第三⾏ - a 不⼤于 b\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">/* Lets change value of a and b */</span> a <span class="token operator">=</span> <span class="token number">5</span> b <span class="token operator">=</span> <span class="token number">20</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> a <span class="token operator"><=</span> b <span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第四⾏ - a ⼩于等于 b\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> b <span class="token operator">>=</span> a <span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"第五⾏ - b ⼤于等于 a\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//以上实例运⾏结果:a不等于b a不小于b a 大于b a小于等于b. b大于等于a</span></code></pre><h5 id="(三)、逻辑运算符(Logical-operator)"><a href="#(三)、逻辑运算符(Logical-operator)" class="headerlink" title="(三)、逻辑运算符(Logical operator)"></a>(三)、逻辑运算符(Logical operator)</h5><p> 下表列出了所有Go语⾔的逻辑运算符。假定 A 值为 True,B 值为 False。</p><p> </p><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main<span class="token keyword">import</span> <span class="token string">"fmt"</span><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">var</span> a <span class="token builtin">bool</span> <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token keyword">var</span> b <span class="token builtin">bool</span> <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> a <span class="token operator">&&</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第一行 - 条件为true\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> a <span class="token operator">||</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第二行 - 条件为true\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">//修改 a 和 b 的值</span> a <span class="token operator">=</span> <span class="token boolean">false</span> b <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> a <span class="token operator">&&</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第三行 - 条件为true\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第三行 - 条件为false\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span><span class="token punctuation">(</span>a <span class="token operator">&&</span> b<span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第四行 - 条件为true\n"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">//以上实例运行结果:第二行 true 第三行 false 第四行 true</span><span class="token punctuation">}</span></code></pre><h5 id="(四)、位运算符(Bitwise-operator)"><a href="#(四)、位运算符(Bitwise-operator)" class="headerlink" title="(四)、位运算符(Bitwise operator)"></a>(四)、位运算符(Bitwise operator)</h5><p> 位运算符对整数在内存中的⼆进制位进⾏操作。位运算符⽐⼀般的算术运算符速度要快,⽽且可以实现⼀些算术运算符不能实现的功能。如果要开发⾼效率程序,位运算符是必不可少的。位运算符⽤来对⼆进 制位进⾏操作,包括:按位与(&)、按位或(|)、按位异或(^)、按位左移 (<<)、按位右移(>>)。</p><p> 假定 A = 60; B = 13;</p><p> A = 0011 1100</p><p> B = 0000 1101</p><p> A&B = 0000 1100</p><p> A|B = 0011 1101</p><p> A^B = 0011 0001</p><ol><li><p>按位与(&):对两个数进⾏操作,然后返回⼀个新的数,这个数的每个 位都需要两个输⼊数的同⼀位都为1 时才为1。简单说就是:同⼀位同时为1 则为1。</p></li><li><p>按位或(|):⽐较两个数,然后返回⼀个新的数,这个数的每⼀位设置1 的条件是任意⼀个数的同⼀位为1 则为1。简单说就是:同⼀位其中⼀个为1 则为1。</p></li><li><p>按位异或(^):⽐较两个数,然后返回⼀个数,这个数的每个位设为1 的 条件是两个输⼊数的同⼀位不同则为1,如果相同就设为0。简单说就是同⼀ 位不相同则为1。</p></li><li><p>左移运算符(<<)</p><ul><li>按⼆进制形式把所有的数字向左移动对应的位数,⾼位移出(舍弃),低位 的空位补零。</li><li>语法格式: <ul><li>需要移位的数字 << 移位的次数 </li><li>例如: 3 << 4,则是将数字3左移4位 </li></ul></li><li><p>计算过程:</p><ul><li>3 << 4</li><li>⾸先把3转换为⼆进制数字0000 0000 0000 0000 0000 0000 0000 0011,然后把该数字⾼位(左侧)的两个零移出,其他的数字都朝左平移4 位,最后在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0011 0000,则转换为⼗进制是48。</li></ul></li><li><p>数学意义:</p><ul><li>在数字没有溢出的前提下,对于正数和负数,左移⼀位都相当于乘以2的1次⽅,左移n位就相当于乘以2的n次⽅。<img src="https://ws2.sinaimg.cn/large/e64a4785gy1fxpynqzk3rj20me07s75j.jpg" alt=""></li></ul><p>以下实例演示了位运算符的⽤法:</p><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main<span class="token keyword">import</span> <span class="token string">"fmt"</span><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> a <span class="token builtin">uint</span> <span class="token operator">=</span> <span class="token number">60</span> <span class="token comment" spellcheck="true">//60 = 0011 1100</span> <span class="token keyword">var</span> b <span class="token builtin">uint</span> <span class="token operator">=</span> <span class="token number">13</span> <span class="token comment" spellcheck="true">//13 =0000 1101</span> <span class="token keyword">var</span> c <span class="token builtin">uint</span> <span class="token operator">=</span> <span class="token number">0</span> c <span class="token operator">=</span> a <span class="token operator">&</span> b <span class="token comment" spellcheck="true">//12 = 0000 1100</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第一行 - c 的值为 %d\n"</span><span class="token punctuation">,</span> c<span class="token punctuation">)</span> c <span class="token operator">=</span> a <span class="token operator">|</span> b <span class="token comment" spellcheck="true">//61 = 0011 1101</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第二行 - c 的值为 %d\n"</span><span class="token punctuation">,</span> c<span class="token punctuation">)</span> c <span class="token operator">=</span> a <span class="token operator">^</span> b <span class="token comment" spellcheck="true">//49 = 0011 0001</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第三行 - c 的值为 %d\n"</span><span class="token punctuation">,</span> c<span class="token punctuation">)</span> c <span class="token operator">=</span> a <span class="token operator"><<</span> <span class="token number">2</span> <span class="token comment" spellcheck="true">//240 = 1111 0000</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第四行 - c 的值为 %d\n"</span><span class="token punctuation">,</span> c<span class="token punctuation">)</span> c <span class="token operator">=</span> a <span class="token operator">>></span> <span class="token number">2</span> <span class="token comment" spellcheck="true">//15 = 0000 1111</span> fmt<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span><span class="token string">"第五行 - c 的值为 %d\n"</span><span class="token punctuation">,</span> c<span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//以上实例运行结果:12 61 49 240 15</span><span class="token punctuation">}</span></code></pre><p> </p><p></p><p></p><p></p><p>1、左移运算符(<<)规则 </p><p>按⼆进制形式把所有的数字向左移动对应的位数,⾼位移出(舍弃),低位 的空位补零。</p><p>1)、语法格式:</p><p>需要移位的数字 << 移位的次数 例如: 3 << 2,则是将数字3左移2位 </p><p>2)、计算过程:</p><p>3 << 2 </p><p>⾸先把3转换为⼆进制数字0000 0000 0000 0000 0000 0000 00000011,然后把该数字⾼位(左侧)的两个零移出,其他的数字都朝左平移2 位,最后在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,则转换为⼗进制是12。</p><p>3)、数学意义:</p><p>在数字没有溢出的前提下,对于正数和负数,左移⼀位都相当于乘以2的1 次⽅,左移n位就相当于乘以2的n次⽅。</p><p>2、右移运算符(>>)规则:</p><p>按⼆进制形式把所有的数字向右移动对应位移位数,低位移出(舍弃),⾼ 位的空位补符号位,即正数补零,负数补1。</p><p>1)、语法格式:</p><p>需要移位的数字 >> 移位的次数</p><p>例如11 >> 2,则是将数字11右移2位</p><p>2)、计算过程:</p><p>11的⼆进制形式为:0000 0000 0000 0000 0000 0000 0000 1011,然后把低位的最后两个数字移出,因为该数字是正数,所以在⾼位补零。则得 到的最终结果是0000 0000 0000 0000 0000 0000 0000 0010。转换为⼗进制是2。</p><p>3)、数学意义:</p><p>右移⼀位相当于除2,右移n位相当于除以2的n次⽅。</p></li></ul></li></ol>]]></content>
<categories>
<category> 后端 </category>
</categories>
<tags>
<tag> GoLang </tag>
</tags>
</entry>
<entry>
<title>Go—变量量及常量量</title>
<link href="/posts/251c8c15.html"/>
<url>/posts/251c8c15.html</url>
<content type="html"><![CDATA[<blockquote><p> Go语⾔基本语法——变量及常量</p></blockquote><h4 id="⼀、变量"><a href="#⼀、变量" class="headerlink" title="⼀、变量"></a>⼀、变量</h4><h5 id="(⼀)、变量的概念"><a href="#(⼀)、变量的概念" class="headerlink" title="(⼀)、变量的概念"></a>(⼀)、变量的概念</h5><ul><li>变量是计算机语⾔中储存数据的抽象概念。变量的功能是存储数据。变量通过变量名访问;</li><li>变量的本质是计算机分配的⼀⼩块内存,专⻔门⽤于存放指定数据,在程序运⾏过程中该数值可以发⽣改变;</li><li>变量的存储往往具有瞬时性,或者说是临时存储,当程序运⾏结束,存放该数据的内存就会释放,⽽该变量就会消失;</li><li>Go 语⾔的变量名由字⺟、数字、下划线组成,⾸个字符不能为数字;</li><li>Go语法规定,定义的局部变量若没有被调⽤则编译错误。</li><li>命名 : camelCasing⻛风格,不建议⽤下划线连接多个单词。</li></ul><h5 id="(⼆)、声明变量"><a href="#(⼆)、声明变量" class="headerlink" title="(⼆)、声明变量"></a>(⼆)、声明变量</h5><p> <code>变量声明有多种形式</code></p><ol><li><p>未初始化的标准格式</p><ul><li>var 变量名变量类型</li></ul></li><li><p>未初始化的批量格式</p><ul><li>不⽤每⾏都⽤var申明</li></ul><pre class=" language-go"><code class="language-go"><span class="token keyword">var</span> <span class="token punctuation">(</span> a <span class="token builtin">int</span> b <span class="token builtin">string</span> c <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">float32</span> d <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> e <span class="token keyword">struct</span> <span class="token punctuation">{</span> x <span class="token builtin">int</span> y <span class="token builtin">string</span> <span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre><ul><li>未初始化变量的默认值:<ul><li>整形和浮点型变量默认值:0</li><li>字符串默认值为空字符串</li><li>布尔型默认值为false</li><li>函数、指针变量初始值为nil</li></ul></li></ul></li><li><p>初始化变量的标准格式</p><ul><li>var 变量名 类型 = 表达式</li></ul></li><li><p>初始化变量的编译器⾃动推断类型格式</p><ul><li>var 变量名 = 表达式</li></ul></li><li><p>初始化变量的简短声明格式(短变量声明格式)</p><ul><li>变量名 := 表达式</li><li>使⽤ := 赋值操作符,:= 可以⾼效地创建⼀个新的变量,称之为初始化声明。</li><li>声明语句省略了var 关键字</li><li>变量类型将由编译器⾃动推断</li><li>这是声明变量的⾸选形式,但是它只能被⽤在函数体内,⽽不可以⽤于全局变量的声明与赋值</li><li>该变量名必须是没有定义过的变量,若定义过,将发⽣编译错误</li><li>在多个短变量声明和赋值中,⾄少有⼀个新声明的变量出现在左侧中,那么即便有其它变量名可能是重复声明的,编译器也不会报错。</li></ul></li></ol><h5 id="(三)、变量多重赋值(多个变量同时赋值)"><a href="#(三)、变量多重赋值(多个变量同时赋值)" class="headerlink" title="(三)、变量多重赋值(多个变量同时赋值)"></a>(三)、变量多重赋值(多个变量同时赋值)</h5><ul><li>Go语法中,变量初始化和变量赋值是两个不同的概念。Go语⾔的变量赋值与其他语⾔⼀样,但是Go提供了其他程序员期待已久的多重赋值功能, 可以实现变量交换。多重赋值让Go语⾔⽐其他语⾔减少了代码量。</li></ul><h5 id="(四)、匿名变量"><a href="#(四)、匿名变量" class="headerlink" title="(四)、匿名变量"></a>(四)、匿名变量</h5><ul><li>Go语⾔的函数可以返回多个值,⽽事实上我们并不是对所有的返回值都⽤得上。那么就可以使⽤匿名变量,⽤“_”下划线替换即可。</li><li>匿名变量不占⽤命名空间,不会分配内存。</li></ul><h4 id="⼆、数据类型"><a href="#⼆、数据类型" class="headerlink" title="⼆、数据类型"></a>⼆、数据类型</h4><p><code>基本数据类型(原⽣数据类型):整型、浮点型、布尔型、字符串、字节 byte和字符rune</code></p><p><code>复合数据类型(派⽣数据类型):指针(pointer)、数组(array)、切 ⽚(slice)、映射(map)、函数(function)、结构体(struct)、通道 (channel)</code></p><h5 id="(⼀)、整型"><a href="#(⼀)、整型" class="headerlink" title="(⼀)、整型"></a>(⼀)、整型</h5><ul><li>整型分两⼤类<ul><li>按⻓长度分:int8、int16、int32、int64、int</li><li>⽆符号整型:uint8、uint16、uint32、uint64、uint</li><li>其中uint8就是byte型,int16对应C语⾔的short型,int64对应C语⾔ 的long型。<img src="https://ws3.sinaimg.cn/large/e64a4785gy1fxpuu0vkq5j210c10ejy5.jpg" alt=""></li></ul></li></ul><h5 id="(⼆)、浮点型"><a href="#(⼆)、浮点型" class="headerlink" title="(⼆)、浮点型"></a>(⼆)、浮点型</h5><ul><li><p>Go语⾔⽀持4种浮点型数:float32、float64、complex64(32 位实数和 虚数)、complex128(64 位实数和虚数)</p><p>float32的最⼤范围是3.4e38,⽤常量定义是:math.MaxFloat32</p><p> float64的最⼤范围是1.8e308,⽤常量定义是:math.MaxFloat64</p></li></ul><h5 id="(三)、布尔型"><a href="#(三)、布尔型" class="headerlink" title="(三)、布尔型"></a>(三)、布尔型</h5><ul><li>声明⽅式:var flag bool</li><li>布尔型⽆法参与数值运算,也⽆法与其他类型进⾏转换。</li></ul><h5 id="(四)、字符串"><a href="#(四)、字符串" class="headerlink" title="(四)、字符串"></a>(四)、字符串</h5><ul><li>字符串在Go语⾔中是以基本数据类型出现的,使⽤字符串就像使⽤其他原⽣基本数据类型int、float32、float64、bool⼀样。</li><li><p>字符串中可以使⽤转移符</p><ul><li>\r 回⻋车符return,返回⾏⾸</li><li>\n 换⾏符new line,直接跳到下⼀⾏的同列位置</li><li>\t 制表符TAB</li><li>\’ 单引号</li><li>\” 双引号</li><li>\ 反斜杠</li></ul></li><li><p>定义多⾏字符串</p><ul><li>双引号书写字符串被称为字符串字⾯量(string literal),这种字⾯量不能跨⾏;</li><li>多⾏字符串需要使⽤“<strong>`</strong>”反引号,多⽤于内嵌源码和内嵌数据;</li><li>在反引号中的所有代码不会被编译器识别,⽽只是作为字符串的⼀部分。</li></ul></li></ul><h5 id="(五)、字符"><a href="#(五)、字符" class="headerlink" title="(五)、字符"></a>(五)、字符</h5><p><code>字符串中的每⼀个元素叫做“字符”,定义字符时使⽤单引号。Go语⾔的字 符有两种:</code></p><ol><li>byte型:其实是uint8的别名。代表了⼀个ASCII码的⼀个字符</li><li>rune型:其实就是int32。代表⼀个UTF-8字符。当需要处理中⽂等unicode字符集时需要⽤到rune类型。<ul><li>var a byte = ‘a’</li><li>var a byte = ‘a’</li></ul></li></ol><h4 id="三、打印格式化"><a href="#三、打印格式化" class="headerlink" title="三、打印格式化"></a>三、打印格式化</h4><h5 id="(⼀)、通⽤"><a href="#(⼀)、通⽤" class="headerlink" title="(⼀)、通⽤"></a>(⼀)、通⽤</h5><ul><li>%v 值的默认格式表示 value</li><li>%+v 类似%v,但输出结构体时会添加字段名</li><li>%#v 值的Go语法表示</li><li>%T 值的类型的Go语法表示 type</li></ul><h5 id="(⼆)、布尔值"><a href="#(⼆)、布尔值" class="headerlink" title="(⼆)、布尔值"></a>(⼆)、布尔值</h5><ul><li>%t 单词true或false true</li></ul><h5 id="(三)整数"><a href="#(三)整数" class="headerlink" title="(三)整数"></a>(三)整数</h5><ul><li>%b 表示为⼆进制 binary</li><li>%c 该值对应的unicode码值 char</li><li>%d 表示为⼗进制 digital</li><li>%8d 表示该整型⻓长度是8,不⾜8则在数值前补空格。如果超出8,则以 实际为准。</li><li>%08d 数字⻓长度是8,不⾜8位的,在数字前补0。如果超出8,则以实际 为准。</li><li>%o 表示为⼋进制 octal</li><li>%q 该值对应的单引号括起来的go语法字符字⾯值,必要时会采⽤安全的转义表示 quotation</li><li>%x 表示为⼗六进制,使⽤a-f hex</li><li>%X 表示为⼗六进制,使⽤A-F</li><li>%U 表示为Unicode格式:U+1234,等价于”U+%04X” unicode</li></ul><h5 id="(四)、浮点数与复数的两个组分"><a href="#(四)、浮点数与复数的两个组分" class="headerlink" title="(四)、浮点数与复数的两个组分"></a>(四)、浮点数与复数的两个组分</h5><ul><li>%b ⽆⼩数部分、⼆进制指数的科学计数法,如-123456p-78;参⻅见 strconv.FormatFloat</li><li>%e (=%.6e)有6位⼩数部分的科学计数法,如-1234.456e+78</li><li>%E 科学计数法,如-1234.456E+78</li><li>%f (=%.6f)有6位⼩数部分,如123.456123 float</li><li>%F 等价于%f</li><li>%g 根据实际情况采⽤%e或%f格式(以获得更简洁、准确的输出)</li><li>%G 根据实际情况采⽤%E或%F格式(以获得更简洁、准确的输出)</li></ul><h5 id="(五)、字符串和-byte"><a href="#(五)、字符串和-byte" class="headerlink" title="(五)、字符串和[]byte"></a>(五)、字符串和[]byte</h5><ul><li>%s 直接输出字符串或者[]byte string</li><li>%q 该值对应的双引号括起来的go语法字符串字⾯值,必要时会采⽤ 安全的转义表示</li><li>%x 每个字节⽤两字符⼗六进制数表示(使⽤a-f)</li><li>%X 每个字节⽤两字符⼗六进制数表示(使⽤A-F)</li></ul><h5 id="(六)、指针"><a href="#(六)、指针" class="headerlink" title="(六)、指针"></a>(六)、指针</h5><ul><li>%p 表示为⼗六进制,并加上前导的0x pointer</li><li>没有%u。整数如果是⽆符号类型⾃然输出也是⽆符号的。类似的,也没有必要指定操作数的尺⼨(int8,int64)。</li><li>宽度通过⼀个紧跟在百分号后⾯的⼗进制数指定,如果未指定宽度,则表示值时除必需之外不作填充。精度通过(可选的)宽度后跟点号后跟的⼗进 制数指定。如果未指定精度,会使⽤默认精度;如果点号后没有跟数字,表 示精度为0。举例如下:</li><li>%f: 默认宽度,默认精度</li><li>%9f 宽度9,默认精度</li><li>%.2f 默认宽度,精度2</li><li>%9.2f 宽度9,精度2</li><li>%9.f 宽度9,精度0</li></ul><h5 id="(七)、其它flag"><a href="#(七)、其它flag" class="headerlink" title="(七)、其它flag"></a>(七)、其它flag</h5><ul><li>‘+’ 总是输出数值的正负号;对%q(%+q)会⽣成全部是ASCII字符的输出(通过转义);</li><li>‘ ‘对数值,正数前加空格⽽负数前加负号;</li><li>‘-‘ 在输出右边填充空⽩⽽不是默认的左边(即从默认的右对⻬齐切换为左对齐);</li><li>‘#’ 切换格式:</li><li>⼋进制数前加0(%#o),⼗六进制数前加0x(%#x)或0X(%#X), 指针去掉前⾯的0x(%#p);</li><li>对%q(%#q),如果strconv.CanBackquote返回真会输出反引号括起来的未转义字符串;</li><li>对%U(%#U),输出Unicode格式后,如字符可打印,还会输出空格和单引号括起来的go字⾯值;</li></ul><h4 id="四、数据类型转换"><a href="#四、数据类型转换" class="headerlink" title="四、数据类型转换"></a>四、数据类型转换</h4><h5 id="(⼀)、数据类型转换的格式"><a href="#(⼀)、数据类型转换的格式" class="headerlink" title="(⼀)、数据类型转换的格式"></a>(⼀)、数据类型转换的格式</h5><ol><li><p>T(表达式)</p><ul><li>采⽤数据类型前置加括号的⽅式进⾏类型转换。T表示要转换的类型;表 达式包括变量、数值、函数返回值等。</li><li>类型转换时,需要考虑两种类型之间的关系和范围,是否会发⽣数值截断。</li><li>布尔型⽆法与其他类型进⾏转换。</li></ul></li><li><p>float与int之间转换</p><ul><li>需要注意float转int时精度的损失</li></ul></li><li><p>int转string</p><ul><li>其实相当于是byte或rune转string。</li><li>该int数值是ASCII码的编号或Unicode字符集的编号。转成string就是将根据字符集,将对应编号的字符查找出来。</li><li>当该数值超出Unicode编号范围,则转成的字符串显示为乱码。</li><li>例如19968转string,就是“⼀”。</li></ul><blockquote><p> ASCII字符集中数字的10进制范围是[30 - 39]</p><p> ASCII字符集中⼤写字⺟的10进制范围是[65 - 90]</p><p> ASCII字符集中⼩写字⺟的10进制范围是[97 - 122]</p><p> Unicode字符集中汉字的范围是[4e00-9fa5],10进制范围是 [19968 - 40869]</p></blockquote></li></ol><p>4、string转int</p><p> 不允许字符串转int(cannot convert 变量 (type string) to type int)<img src="https://wx2.sinaimg.cn/large/e64a4785gy1fxpve114vyj21620r8e81.jpg" alt=""></p><h4 id="五、常量"><a href="#五、常量" class="headerlink" title="五、常量"></a>五、常量</h4><h5 id="⼀-、声明⽅式"><a href="#⼀-、声明⽅式" class="headerlink" title="(⼀)、声明⽅式"></a>(⼀)、声明⽅式</h5><ol><li>相对于变量,常量是恒定不变的值,例如圆周率。<ul><li>常量是⼀个简单值的标识符,在程序运⾏时,不会被修改。</li></ul></li><li>常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字 符串型。</li><li>常量的定义格式:<ul><li>const 标识符 [类型] = 值</li><li>可以省略类型说明符 [type],因为编译器可以根据变量的值来⾃动推断其类型。<ul><li>显式类型定义: const B string = “michel”</li><li>隐式类型定义: const C = “michel”</li></ul></li></ul></li><li>多个相同类型的声明可以简写为:</li><li>常量定义后未被使⽤,不会在编译时出错。</li></ol><h5 id="⼆-、常量⽤于枚举(常量组)"><a href="#⼆-、常量⽤于枚举(常量组)" class="headerlink" title="(⼆)、常量⽤于枚举(常量组)"></a>(⼆)、常量⽤于枚举(常量组)</h5><p>例如以下格式:</p><pre class=" language-go"><code class="language-go"><span class="token keyword">const</span> <span class="token punctuation">(</span> Unknown <span class="token operator">=</span> <span class="token number">0</span> Female <span class="token operator">=</span> <span class="token number">1</span> Male <span class="token operator">=</span> <span class="token number">2</span> <span class="token punctuation">)</span></code></pre><p>数字 0、1 和 2 分别代表未知性别、⼥性和男性。</p><p>常量组中如果不指定类型和初始值,则与上⼀⾏⾮空常量的值相同。</p><pre class=" language-go"><code class="language-go"><span class="token keyword">const</span> <span class="token punctuation">(</span> a <span class="token operator">=</span> <span class="token number">10</span> b c <span class="token punctuation">)</span></code></pre><p>打印a、b、c,输出:10 10 10</p><h5 id="三-、iota"><a href="#三-、iota" class="headerlink" title="(三)、iota"></a>(三)、iota</h5><ol><li><p>iota,特殊常量值,是⼀个系统定义的可以被编译器修改的常量值。iota只能 ⽤在常量赋值中。</p></li><li><p>在每⼀个const关键字出现时,被重置为0,然后每出现⼀个常量,iota所代</p><p>表的数值会⾃动增加1。iota可以理解成常量组中常量的计数器,不论该常量的值 是什么,只要有⼀个常量,那么iota就加1。</p></li><li><p>iota 可以被⽤作枚举值:</p></li></ol><pre class=" language-go"><code class="language-go"><span class="token keyword">const</span> <span class="token punctuation">(</span> a <span class="token operator">=</span> <span class="token boolean">iota</span> b <span class="token operator">=</span> <span class="token boolean">iota</span> c <span class="token operator">=</span> <span class="token boolean">iota</span><span class="token punctuation">)</span><span class="token function">println</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> c<span class="token punctuation">)</span><span class="token comment" spellcheck="true">//打印输出:0 1 2</span><span class="token comment" spellcheck="true">//第⼀个 iota 等于 0,每当 iota 在新的⼀⾏被使⽤时,它的值都会⾃动加 1;所以 a=0, b=1, c=2</span></code></pre><ol start="4"><li>常量组中如果不指定类型和初始值,则与上⼀⾏⾮空常量的值相同。所以上述的枚举可以简写为如下形式:</li></ol><pre class=" language-go"><code class="language-go"><span class="token keyword">const</span> <span class="token punctuation">(</span> a <span class="token operator">=</span> <span class="token boolean">iota</span> b c <span class="token punctuation">)</span> <span class="token function">println</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> c<span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//打印输出:0 1 2</span></code></pre><ol start="5"><li>示例⼀</li></ol><pre class=" language-go"><code class="language-go"><span class="token keyword">const</span> <span class="token punctuation">(</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token operator"><<</span><span class="token boolean">iota</span> j <span class="token operator">=</span> <span class="token number">3</span><span class="token operator"><<</span><span class="token boolean">iota</span> k l<span class="token punctuation">)</span><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"i="</span><span class="token punctuation">,</span>i<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"j="</span><span class="token punctuation">,</span>j<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"k="</span><span class="token punctuation">,</span>k<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"l="</span><span class="token punctuation">,</span>l<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">//打印输出结果:i= 1 j= 6 k= 12 l= 24</span></code></pre><ol start="6"><li>示例⼆</li></ol><pre class=" language-go"><code class="language-go"><span class="token keyword">const</span> <span class="token punctuation">(</span> a1 <span class="token operator">=</span> <span class="token string">'⼀'</span> b1 c1 <span class="token operator">=</span> <span class="token boolean">iota</span> d1 <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>a1<span class="token punctuation">,</span> b1<span class="token punctuation">,</span> c1<span class="token punctuation">,</span> d1<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">//打印输出结果:19968 19968 2 3</span></code></pre><h4 id="六、类型别名(Type-Alias)"><a href="#六、类型别名(Type-Alias)" class="headerlink" title="六、类型别名(Type Alias)"></a>六、类型别名(<strong>Type</strong> <strong>Alias</strong>)</h4><h5 id="(⼀)、概要"><a href="#(⼀)、概要" class="headerlink" title="(⼀)、概要"></a>(⼀)、概要</h5><p> 类型别名是Go1.9版本添加的新功能。主要⽤于代码升级、迁移中类型的兼容性 问题。在Go1.9版本前内建类型定义的代码是:</p><ul><li><p>type byte uint8</p></li><li><p>type rune int32</p><p>⽽在Go1.9版本之后变更为:type byte = uint8 type rune = int32</p></li></ul><h5 id="(⼆)、类型别名与类型定义"><a href="#(⼆)、类型别名与类型定义" class="headerlink" title="(⼆)、类型别名与类型定义"></a>(⼆)、类型别名与类型定义</h5><ol><li><p>类型别名的语法格式:</p><ul><li>type 类型别名 = 类型</li></ul></li><li><p>定义类型的语法格式:</p><ul><li><p>type 新的类型名 类型</p><p>例如:</p><ul><li>type NewString string</li></ul><p>该语句是将NewString定义为string类型。通过type关键字,NewString会形 成⼀种新的类型。NewString本身依然具备string的特性。</p><ul><li>type StringAlias = string</li></ul><p>该语句是将StringAlias定义为string的⼀个别名。使⽤StringAlias与string等效。别名类型只会在代码中存在,编译完成时,不会有别名类型。</p></li></ul></li></ol><h5 id="(三)、⾮本地类型不能定义⽅法"><a href="#(三)、⾮本地类型不能定义⽅法" class="headerlink" title="(三)、⾮本地类型不能定义⽅法"></a>(三)、⾮本地类型不能定义⽅法</h5><p><code>不能为不在同⼀个包中的类型定义⽅法。package main improt "time"</code></p><h4 id="七、出于性能考虑的最佳实践和建议"><a href="#七、出于性能考虑的最佳实践和建议" class="headerlink" title="七、出于性能考虑的最佳实践和建议"></a>七、出于性能考虑的最佳实践和建议</h4><ol><li>尽可能的使⽤ := 去初始化声明⼀个变量(在函数内部);</li><li>尽可能的使⽤字符代替字符串;</li><li>尽可能的使⽤切⽚代替数组;</li><li>尽可能的使⽤数组和切⽚代替map;</li><li>如果只想获取切⽚中某项值,不需要值的索引,尽可能的使⽤for range去遍历切⽚,这⽐必须查询切⽚中的每个元素要快⼀些;</li><li>当数组元素是稀疏的(例如有很多0值或者空值nil),使⽤map会降低内存消耗;</li><li>初始化map时指定其容量;</li><li>当定义⼀个⽅法时,使⽤指针类型作为⽅法的接收者;</li><li>在代码中使⽤常量或者标志提取常量的值;</li><li>尽可能在需要分配⼤量内存时使⽤缓存;</li><li>使⽤缓存模板。</li></ol><h5 id=""><a href="#" class="headerlink" title=" "></a> </h5>]]></content>
<categories>
<category> 后端 </category>
</categories>
<tags>
<tag> GoLang </tag>
</tags>
</entry>
<entry>
<title>Golang安装和配置</title>
<link href="/posts/883f59cd.html"/>
<url>/posts/883f59cd.html</url>
<content type="html"><![CDATA[<blockquote><p><strong>Golang</strong>安装和配置</p></blockquote><h4 id="⼀、Golang安装"><a href="#⼀、Golang安装" class="headerlink" title="⼀、Golang安装"></a>⼀、<strong>Golang</strong>安装</h4><h5 id="(⼀)、下载"><a href="#(⼀)、下载" class="headerlink" title="(⼀)、下载"></a>(⼀)、下载</h5><p> 在Mac、Windows和Linux三个平台上都⽀持Golang。您可以从<a href="https://golang.org/dl/下载相应平台的⼆进制⽂件。该⽹站在国内不容易访问," rel="external nofollow noopener noreferrer" target="_blank">https://golang.org/dl/下载相应平台的⼆进制⽂件。该⽹站在国内不容易访问,</a> 所以可以访问<a href="https://www.studygolang.com/dl" rel="external nofollow noopener noreferrer" target="_blank">https://www.studygolang.com/dl</a> 进⾏安装软件的下载。</p><p><img src="https://wx4.sinaimg.cn/large/e64a4785gy1fxoof8rth4j21lw0qe7ag.jpg" alt=""></p><p><img src="https://ws4.sinaimg.cn/large/e64a4785gy1fxoofpgaxaj21lo0rw0zc.jpg" alt=""> </p><ul><li>Mac OS 从<a href="https://golang.org/dl/下载osx安装程序。双击启动安装。按照" rel="external nofollow noopener noreferrer" target="_blank">https://golang.org/dl/下载osx安装程序。双击启动安装。按照</a> 提示,这应该在/usr/local/go中安装了Golang,并且还会将⽂件夹/usr/local/go/bin添加到您的PATH环境变量中。</li><li>Windows 从<a href="https://golang.org/dl/下载MSI安装程序。双击启动安装并遵" rel="external nofollow noopener noreferrer" target="_blank">https://golang.org/dl/下载MSI安装程序。双击启动安装并遵</a> 循提示。这将在位置c中安装Golang:\Go,并且还将添加⽬录c:\Go\bin到您 的path环境变量。</li><li>Linux 从<a href="https://golang.org/dl/下载tar⽂件,并将其解压到/usr/local。" rel="external nofollow noopener noreferrer" target="_blank">https://golang.org/dl/下载tar⽂件,并将其解压到/usr/local。</a> 将/usr/local/go/bin添加到PATH环境变量中。这应该安装在linux中。</li></ul><h4 id="⼆、-windows系统下安装和配置环境变量"><a href="#⼆、-windows系统下安装和配置环境变量" class="headerlink" title="⼆、 windows系统下安装和配置环境变量"></a>⼆、 <strong>windows</strong>系统下安装和配置环境变量</h4><h5 id="(⼀)、安装步骤⾮常简单,⼀路到底"><a href="#(⼀)、安装步骤⾮常简单,⼀路到底" class="headerlink" title="(⼀)、安装步骤⾮常简单,⼀路到底"></a>(⼀)、安装步骤⾮常简单,⼀路到底</h5><h5 id="(⼆)、配置环境变量"><a href="#(⼆)、配置环境变量" class="headerlink" title="(⼆)、配置环境变量"></a>(⼆)、配置环境变量</h5><ol><li>配置环境变量. </li></ol><p>注意:如果是msi安装⽂件,Go语⾔的环境变量会⾃动设置好。我的电脑——右键“属性”——“⾼级系统设置”——“环境变量”——“系统变量”假设GO安装于C盘根⽬录新建:</p><ul><li>GOROOT:Go安装路径(例:C:\Go)</li><li>GOPATH:Go⼯程的路径(例:E:\go)。如果有多个,就以分号分隔添 加</li></ul><p><img src="https://ws3.sinaimg.cn/large/e64a4785gy1fxoolu8m1fj20bf0bxtbc.jpg" alt=""> </p><p>修改:</p><pre><code> * Path:在path中增加:C:\Go\bin;%GOPATH%\bin; 需要把GOPATH中的可执⾏⽬录也配置到环境变量中, 否则你⾃⾏下载的第 三⽅go⼯具就⽆法使⽤了</code></pre><p><img src="https://ws3.sinaimg.cn/large/e64a4785gy1fxoon98qwsj20cf0ctn0l.jpg" alt=""> </p><pre><code> * ⼯作⽬录就是我们⽤来存放开发的源代码的地⽅,对应的也是Go⾥的GOPATH这个环境变量。这个环境变量指定之后,我们编译源代码等⽣成的 ⽂件都会放到这个⽬录下,GOPATH环境变量的配置参考上⾯的安装Go,配 置到Windows下的系统变量⾥。 * GOPATH之下主要包含三个⽬录: bin、pkg、src。bin⽬录主要存放可执⾏⽂件; pkg⽬录存放编译好的库⽂件, 主要是*.a⽂件; src⽬录下主要存放go 的源⽂件</code></pre><ol start="2"><li><p>查看是否安装配置成功</p><p>使⽤快捷键win+R键,输⼊cmd,打开命令⾏提示符,在命令⾏中输⼊ go env # 查看得到go的配置信息</p><p>go version # 查看go的版本号</p></li></ol><h4 id="三、mac系统安装并配置"><a href="#三、mac系统安装并配置" class="headerlink" title="三、mac系统安装并配置"></a>三、<strong>mac</strong>系统安装并配置</h4><h5 id="(⼀)、安装"><a href="#(⼀)、安装" class="headerlink" title="(⼀)、安装"></a>(⼀)、安装</h5><p> 双击pkg包,顺着指引,即可安装成功。 在命令⾏输⼊ go version,获取到go的 版本号,则代表安装成功。</p><h5 id="(⼆)、配置环境变量-1"><a href="#(⼆)、配置环境变量-1" class="headerlink" title="(⼆)、配置环境变量"></a>(⼆)、配置环境变量</h5><pre><code> 1. 打开终端输⼊cd ~进⼊⽤户主⽬录; 2. 输⼊ls -all命令查看是否存在.bash_profile 3. 存在既使⽤vim .bash_profile 打开⽂件; 4. 输⼊ i 进⼊vim编辑模式; 5. 输⼊下⾯代码, 其中 GOPATH: ⽇常开发的根⽬录。GOBIN:是GOPATH下的 bin⽬录。 * export GOPATH=/Users/steven/Documents/go_projec * export GOROOT= /Usr/local/go * export GOBIN=$GOROOT/bin * export PATH=$PATH:$GOBIN 6. 点击ESC,并输⼊ :wq 保存并退出编辑。可输⼊vim .bash_profile 查看是否 保存成功。 7. 输⼊source ~/.bash_profile 完成对golang环境变量的配置,配置成功没有提 示。 8. 输⼊go env 查看配置结果</code></pre>]]></content>
<categories>
<category> 后端 </category>
</categories>
<tags>
<tag> 开发环境 </tag>
<tag> Golang </tag>
</tags>
</entry>
<entry>
<title>Goland安装和配置</title>
<link href="/posts/a1f7ed3f.html"/>
<url>/posts/a1f7ed3f.html</url>
<content type="html"><![CDATA[<blockquote><p><strong>Goland</strong>安装和配置</p></blockquote><ul><li><h4 id="⼀、安装Goland开发⼯具"><a href="#⼀、安装Goland开发⼯具" class="headerlink" title="⼀、安装Goland开发⼯具"></a>⼀、安装<strong>Goland</strong>开发⼯具</h4><ul><li><h5 id="(⼀)、介绍"><a href="#(⼀)、介绍" class="headerlink" title="(⼀)、介绍"></a>(⼀)、介绍</h5><p> Goland是由JetBrains公司旨在为go开发者提供的⼀个符合⼈体⼯程学的新的商业IDE。这个IDE整合了IntelliJ平台的有关go语⾔的编码辅助功能和⼯具集成 特点。它具有以下特点:</p><ul><li>编码辅助功能</li><li>符合⼈体⼯程学的设计</li><li>⼯具的集成</li><li>IntelliJ插件⽣态系统</li></ul></li><li><h5 id="(⼆)、下载及安装"><a href="#(⼆)、下载及安装" class="headerlink" title="(⼆)、下载及安装"></a>(⼆)、下载及安装</h5><ol><li><p>官⽹下载地址:<a href="https://www.jetbrains.com/go/download/。下载完成后,在" rel="external nofollow noopener noreferrer" target="_blank">https://www.jetbrains.com/go/download/。下载完成后,在</a> 本地执⾏解压,安装。<img src="https://ws1.sinaimg.cn/large/e64a4785gy1fxorvzqo7oj224q146n6b.jpg" alt=""></p></li><li><p>安装过程</p><p> 点击“next”按钮,选择要安装的路径,然后点击“next”,会出现安装选项。根据你⾃⼰电脑的型号,选择合适的版本后点击“next”按钮。接着保持默认的程 序启动⽬录,点击“install”进⾏安装。整个安装过程很快,⼏乎⼀路next到底。</p></li></ol></li><li><h5 id="(三)、使⽤Goland"><a href="#(三)、使⽤Goland" class="headerlink" title="(三)、使⽤Goland"></a>(三)、使⽤Goland</h5><ol><li>打开Goland⼯具<img src="https://ws4.sinaimg.cn/large/e64a4785gy1fxos14du57j21de0x0n15.jpg" alt=""></li><li>创建项⽬:<img src="https://ws2.sinaimg.cn/large/e64a4785gy1fxos4xaemlj21620mo75g.jpg" alt=""></li></ol></li></ul></li></ul><ul><li><h4 id="⼆、第⼀个程序:HelloWorld"><a href="#⼆、第⼀个程序:HelloWorld" class="headerlink" title="⼆、第⼀个程序:HelloWorld"></a>⼆、第⼀个程序:<strong>HelloWorld</strong></h4><ul><li><h5 id="(⼀)、编写第⼀个程序"><a href="#(⼀)、编写第⼀个程序" class="headerlink" title="(⼀)、编写第⼀个程序"></a>(⼀)、编写第⼀个程序</h5><ol><li>打开编辑器创建⼀个新的helloworld.go⽂件,并输⼊以下内容:</li><li>执⾏go程序 <code>执⾏go程序由⼏种⽅式</code><ul><li>⽅式⼀:使⽤go run命令<ul><li>tep1:使⽤快捷键win+R,输⼊cmd打开命令⾏提示符</li><li>step2:进⼊helloworld.go所在的⽬录</li><li>step3:输⼊go run helloworld.go命令并观察运⾏结果。</li></ul></li><li>⽅式⼆:使⽤go build命令<ul><li>step1:使⽤快捷键win+R,输⼊cmd打开命令⾏提示符</li><li>step2:进⼊helloworld.go所在的⽬录</li><li>step3:输⼊go build helloworld.go命令进⾏编译,产⽣同名的helloworld.exe⽂件</li><li>tep4:输⼊helloworld.exe,执⾏</li></ul></li><li>⽅式三:使⽤ go playground<ul><li>step1:打开⼀下⽹址<a href="https://play.golang.org/" rel="external nofollow noopener noreferrer" target="_blank">https://play.golang.org/</a></li></ul></li></ul></li></ol></li></ul></li></ul><pre class=" language-go"><code class="language-go"> <span class="token keyword">package</span> main <span class="token keyword">import</span> <span class="token string">"fmt"</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">/* 输出 */</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Hello, World!"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span></code></pre><ul><li><h4 id="三、Goland常⽤快捷键"><a href="#三、Goland常⽤快捷键" class="headerlink" title="三、Goland常⽤快捷键"></a>三、<strong>Goland</strong>常⽤快捷键</h4><ul><li><h5 id="(⼀)、⽂件相关快捷键:"><a href="#(⼀)、⽂件相关快捷键:" class="headerlink" title="(⼀)、⽂件相关快捷键:"></a>(⼀)、⽂件相关快捷键:</h5><ol><li>TRL+E,打开最近浏览过的⽂件。</li><li>CTRL+SHIFT+E,打开最近更改的⽂件。</li><li>CTRL+N,可以快速打开struct结构体。</li><li>CTRL+SHIFT+N,可以快速打开⽂件。</li></ol></li><li><h5 id="(⼆)、代码格式化:"><a href="#(⼆)、代码格式化:" class="headerlink" title="(⼆)、代码格式化:"></a>(⼆)、代码格式化:</h5><ol><li>CTRL+ALT+T,可以把代码包在⼀个块内,例如if{…}else{…}。</li><li>CTRL+ALT+L,格式化代码。</li><li>CTRL+空格,代码提示。</li><li>CTRL+/,单⾏注释。CTRL+SHIFT+/,进⾏多⾏注释。</li><li>CTRL+B,快速打开光标处的结构体或⽅法(跳转到定义处)。</li><li>CTRL+“+/-”,可以将当前⽅法进⾏展开或折叠。</li></ol></li><li><h5 id="(三)、查找和定位"><a href="#(三)、查找和定位" class="headerlink" title="(三)、查找和定位"></a>(三)、查找和定位</h5><ol><li>CTRL+R,替换⽂本。</li><li>CTRL+F,查找⽂本。</li><li>TRL+SHIFT+F,进⾏全局查找。</li><li>CTRL+G,快速定位到某⾏。</li></ol></li><li><h5 id="(四)、代码编辑"><a href="#(四)、代码编辑" class="headerlink" title="(四)、代码编辑"></a>(四)、代码编辑</h5><ol><li>ALT+Q,可以看到当前⽅法的声明。</li><li>SHIFT+ENTER,可以向下插⼊新⾏,即使光标在当前⾏的中间。</li><li>CTRL+Backspace,按单词进⾏删除或删除光标所在⾏。</li><li>TRL+X,剪切当前光标所在⾏。</li><li>CTRL+D,复制当前光标所在⾏。</li><li>ALT+SHIFT+UP/DOWN,可以将光标所在⾏的代码上下移动。</li><li>CTRL+SHIFT+U,可以将选中内容进⾏⼤⼩写转化。</li></ol></li></ul></li></ul>]]></content>
<categories>
<category> 后端 </category>
</categories>
<tags>
<tag> Goland </tag>
<tag> 开发工具 </tag>
</tags>
</entry>
<entry>
<title>字符集和字符编码问题</title>
<link href="/posts/ef82378d.html"/>
<url>/posts/ef82378d.html</url>
<content type="html"><![CDATA[<blockquote><p>字符集和字符编码问题</p></blockquote><h4 id="一、字符集及字符编码概述"><a href="#一、字符集及字符编码概述" class="headerlink" title="一、字符集及字符编码概述"></a>一、字符集及字符编码概述</h4><h5 id="一-、字符编码的重要性"><a href="#一-、字符编码的重要性" class="headerlink" title="(一)、字符编码的重要性"></a>(一)、字符编码的重要性</h5><p> <code>只要有中文的地方就会出现编码问题。</code></p><p> 编码问题是学习编程中非常重要的⼀一个问题,如果对编码和字符集不能透彻理理解,那么就如同⾏走在沼泽,随时会让程序员深陷其中、无法⾃自拔。字符编码这个知识如此重要,但现实是,很多公司里即便从事多年开发的程序员也常常对此一知半解。遇到问题时大多连蒙带猜地解决,不求甚解。 </p><h5 id="二-、工作中最常出现编码问题的地方"><a href="#二-、工作中最常出现编码问题的地方" class="headerlink" title="(二)、工作中最常出现编码问题的地方"></a>(二)、工作中最常出现编码问题的地方</h5><p>1.⽆论前端开发、java开发、PHP开发、移动开发还是Python开发,任何⼀种计算机语⾔都会遇到字符编码问题;</p><p>2.表单提交数据到服务器时,容易出现数据传输错误;</p><p>3.只要涉及到⽹络传输中⽂数据,极其出现编码问题;</p><p>4.当⽤到Ajax技术时,经常出现乱码问题;</p><p>5.⾮编程⼈员⽇常⽣活中也常出现编码问题。⽐如打开⽂件后显示乱码,如果 理解字符编码,只需要换⼀种打开⽅式,或许问题就迎刃⽽解。</p><p> 总之,字符编码问题很重要,不掌握将后患⽆穷。</p><h5 id="(三)、基本概念"><a href="#(三)、基本概念" class="headerlink" title="(三)、基本概念"></a>(三)、基本概念</h5><ol><li><p>⾸先介绍:字符、字符集、字符编码三者的含义。</p><ul><li>字符:是关于⽂字和符号的总称,包括各个国家的⽂字、标点符号、图形符号、数字等等。例如:⼀个汉字,⼀个标点符号逗号,⼀个英⽂ 字⺟,⼀个数字,这都是字符。</li><li>字符集:是多个字符的集合。我们可以理解成就是⼀本⼤字典。字符集种类很多,每个字符集包含的字符个数也不同,常⻅的字符集有: ASCII字符集,Unicode字符集,GB2312字符集 ISO-8859-1字符集等等。</li><li>字符编码:计算机只能识别⼆进制代码1和0。字符集中的字符,计 算机是不能直接识别的,所以要将字符转化为计算机可以识别的⼆进制码, 计算机才能认识,这个转化过程就是编码,⽽字符编码就是将⼆进制码与字 符集中的字符对应起来的⼀套规则。<ul><li>各个国家和地区在制定编码标准的时候,字符集和编码规则都是同时 制定的。因此,平常我们所说的字符集,如ASCII、GB2312、GBK、 Unicode等,除了有字符集合的含义外,同时也包含字符编码的含义;</li><li>⼀般来说,每种字符集都有相应的⼀种字符编码规则,如ASCII码、 GB2312字符集等都只有⼀种编码⽅式,分别是ASCII编码、GB2312编 码;</li><li>但有的字符集有多种编码⽅式,⽐如,Unicode字符集有UTF-8、 UTF-16、UTF-32等多种字符编码⽅式。</li></ul></li></ul></li><li><p>其次介绍字符与字节的含义。</p><ul><li><p>不要将字符与字节搞混。字符是⽂化符号,⽽字节是⽂件的⻓度单位。 </p><p> ⽐如有⼀个⽂件,内容如下:</p><p>“ABC123”<br><br>在这个⽂件中,我们输⼊的是“半⻆”的“ABC123”,⼀共包含6个字符。但是这个⽂件有多⼤, 占⼏个字节呢?<br><br>答案是:6字节、9字节、12字节、14字节、24字节、28字节<br><br>怎么会有这么多种答案呢?其实只要掌握了字符集及字符编码就明⽩了。不同的字符集、不同 的编码⽅式,都会导致⽂件的⼤⼩不同。</p></li></ul></li></ol><h5 id="(四)、回顾计算机基本原理"><a href="#(四)、回顾计算机基本原理" class="headerlink" title="(四)、回顾计算机基本原理"></a>(四)、回顾计算机基本原理</h5><pre><code> 1. 计算机最基本的硬件是半导体芯⽚,每块芯⽚集成了数万到数百万个晶体管; 2. 计算机最基本的物理元件是晶体管,每⼀个晶体管具有开和关两种状态; 3. 七个晶体管组合在⼀起就可以组合出128种不同的状态(=2的7次⽅); 4. ⼋个晶体管组合在⼀起就可以组合出256种不同的状态(=2的8次⽅)。</code></pre><p><img src="https://wx4.sinaimg.cn/large/e64a4785gy1fxnshr4ecpj20pk0kiao3.jpg" alt=""></p><h4 id="⼆、ASCII码"><a href="#⼆、ASCII码" class="headerlink" title="⼆、ASCII码"></a>⼆、ASCII码</h4><h5 id="(⼀)、ASCII码的由来"><a href="#(⼀)、ASCII码的由来" class="headerlink" title="(⼀)、ASCII码的由来"></a>(⼀)、ASCII码的由来</h5><ol><li>ASCII码(American Standard Code for Information Interchange),它是“美国标准信息互换码”; <ul><li>ASCII码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,标准的单字节字符编码⽅案,⽤于基于⽂本的数据。起始于50年代后期,在1967年定案。它最初是美国国家标准,供不同计算机在相互通信时⽤作共同遵守的西⽂字符编码标准,它已被国标准化组织(International Organization for Standardization, ISO)定为国标准,称为ISO646标准。适⽤于所有拉丁⽂字⺟。</li><li>美国国家标准学会(American National Standards Institute:ANSI)。美国国家标准学会成⽴于1918年。当时,美国的许多企业和专业技术团体,已开始了标准化⼯作,但因彼此间没有协调,存在不少⽭盾和问题。为了进⼀步提⾼效率,数百个科技学会、协会组织和团体,均认为有必要成⽴⼀个专门的标准化机构,并制订统⼀的通⽤标准。</li></ul></li><li>计算机每个晶体管可以存储的两种状态,构成了计算机最⼩的存储单位:位(bit,⽐特);</li><li>七个晶体管组合出的128种不同的状态,每种状态保存⼀个字节,这就构 成了“标准的7位ASCII码”;128种状态⾜够保存美国所有的⽂化符号(⼤写26个字⺟、⼩写26个字⺟、0-9阿拉伯数字、所有的英⽂标点符号、数学运算符号、其他特殊符号以及控制码;ASCII码中编号0~31是⾮打印字符,⽤于控制字符的换⾏回⻋删除等。也统称为”控制码”;32~126 是打印字符,可以通过键盘输⼊并且能够显示出来。<ul><li>编号48⾄57,保存的是数字0到9;</li><li>编号65⾄90,保存的是⼤写字⺟A到Z;</li><li>编号97⾄122,保存的是⼩写字⺟a到z;</li><li>其它位置保存的是标点符号、数学运算符号及特殊符号。</li></ul></li><li>⼋个晶体管可以组合256种不同的状态,这就是“扩展ASCII码”;<ul><li>计算机起初是美国⽤于军事⽽发明的产物,后来更多国家开始使⽤计 算机,这些国家的字⺟是ASCII码中没有的;</li><li>后来IBM公司在此基础上进⾏了扩展,⽤8bit来表示⼀个字符,总共可以表示256个字符。当第⼀位是0时仍然表示7位ASCII码的字符,当第⼀位为1时就表示新补充的字符。</li><li>编号128到编号255的字符集被称为“扩展ASCII码”。</li></ul></li></ol><h5 id="(⼆)、ASCII码的编号及对应字符"><a href="#(⼆)、ASCII码的编号及对应字符" class="headerlink" title="(⼆)、ASCII码的编号及对应字符"></a>(⼆)、ASCII码的编号及对应字符</h5><p><img src="https://wx1.sinaimg.cn/large/e64a4785gy1fxnsxc5fo7j21620r8b29.jpg" alt=""></p><p><img src="https://ws2.sinaimg.cn/large/e64a4785gy1fxnsyoikxlj20r00hlqsg.jpg" alt=""></p><p><img src="https://ws4.sinaimg.cn/large/e64a4785gy1fxnsz6omimj20jf0hs4gx.jpg" alt=""></p><p><img src="https://ws2.sinaimg.cn/large/e64a4785gy1fxnszwn6vej20jv0dkgy6.jpg" alt=""></p><p><code>备注:</code></p><ul><li><code>⼆进制 binary</code></li><li><code>八进制。octet(8位字节)</code></li><li><code>十进制。decimal</code></li><li><code>十六进制。hexadecimal</code> </li></ul><h4 id="三、中文字符集"><a href="#三、中文字符集" class="headerlink" title="三、中文字符集"></a>三、中文字符集</h4><h5 id="(⼀)、GB2312字符集"><a href="#(⼀)、GB2312字符集" class="headerlink" title="(⼀)、GB2312字符集"></a>(⼀)、GB2312字符集</h5><ol><li><p>中国⼈们得到计算机时,已经没有可以利⽤的字节状态来表示汉字,况且 中⽂常⽤字就有6000多个;</p></li><li><p>GB2312字符集中依然保留了前128个ASCII码的字符。⽽把编号在127号之后的符号们全部去掉。</p><ul><li>规定:⼀个⼩于127的字符的意义与原来相同,但两个⼤于127的字符连在⼀起时,就表示⼀个汉字,这就是“GB2312字符集”,这是由中国国家标准总局1980年发布的;</li><li>GB2312 是对 ASCII 编码的中⽂扩展,ASCII码是典型的单字节编码,⼀个字符就占⼀个字节⻓长度。因此GB2312字符集中,前128个字符是单字节的,编号在127之后的GB2312编码则是双字节的,也就是⼀个字符是两个字节⻓长度。</li><li>GB2312字符集只⽀持6763个简体汉字。</li></ul></li><li><p>GB2312字符集,除汉字外还把数学符号、罗⻢马字⺟、希腊字⺟、⽇⽂假 名都编进去了。此外还将 ASCII ⾥本来就有的⼤⼩写英⽂字⺟、阿拉伯数字、标点符号重新编了⼀套两个字节⻓长的编码,这就是“全⻆角”字符,⽽原来 在127号以下的那些就叫“半⻆角”字符了。全⻆角和半⻆角只针对于字⺟、数字和 标点⽽⾔的,对于中⽂字是⽆所谓全⻆角和半⻆角区分的。</p><ul><li><p>“全⻆角”字符是双字节编码,⽽“半⻆角”字符是单字节编码,因此⻓长度上不同;例如:</p><p>abcdefgABCDEFG1234567890</p><p>abcdefgABCDEFG1234567890</p></li></ul><p><img src="https://ws2.sinaimg.cn/large/e64a4785gy1fxnt9lw7w8j20bn0ip44t.jpg" alt=""></p></li></ol><h5 id="(⼆)、GBK-字符集"><a href="#(⼆)、GBK-字符集" class="headerlink" title="(⼆)、GBK 字符集"></a>(⼆)、GBK 字符集</h5><p> 中国的汉字太多,GB2312字符集中的6763个汉字不够使⽤,1993年⼜颁布了《汉字编码扩展规范》,也就是GBK 编码,GBK 包括 GB2312 的所有内 容,同时⼜增加了近20000个新的汉字(包括繁体字)和符号。</p><h5 id="(三)、GB18030字符集"><a href="#(三)、GB18030字符集" class="headerlink" title="(三)、GB18030字符集"></a>(三)、GB18030字符集</h5><p>随着中国各少数⺠民族使⽤电脑,中⽂字符集继续扩展。国家标准GB18030- 2000《信息交换⽤汉字编码字符集基本集的补充》是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准,GB18030字符集⼜加了⼏千个新的 少数⺠民族的⽂字。GB18030-2000是GBK的取代版本,它的主要特点是在GBK基 础上增加了CJK(china-japan-korea,中⽇韩)统⼀汉字扩充的汉字。</p><h5 id="(四)、DBCS字符集"><a href="#(四)、DBCS字符集" class="headerlink" title="(四)、DBCS字符集"></a>(四)、DBCS字符集</h5><p>GB2312、GBK、GB18030等⼀系列汉字编码,中国程序员通称他们叫做 “DBCS”(Double Byte Charecter Set 双字节字符集)。其最⼤的特点是:除 ASCII码字符外,其它的每个字符都占两个字节⻓长度。</p><h4 id="四、Unicode字符集(UCS-,统⼀字符集、万国码、单⼀码)"><a href="#四、Unicode字符集(UCS-,统⼀字符集、万国码、单⼀码)" class="headerlink" title="四、Unicode字符集(UCS ,统⼀字符集、万国码、单⼀码)"></a>四、<strong>Unicode</strong>字符集<code>(UCS ,统⼀字符集、万国码、单⼀码)</code></h4><h5 id="(⼀)、出现的原因"><a href="#(⼀)、出现的原因" class="headerlink" title="(⼀)、出现的原因"></a>(⼀)、出现的原因</h5><ol><li><p>当时各个国家都像中国这样搞出⼀套⾃⼰的编码标准,结果相互之间谁也不懂谁的编码,谁也不⽀持别⼈的编码,甚⾄中国⼤陆和中国台湾这样只相隔了150海⾥,使⽤着同⼀种语⾔的兄弟地区,也采⽤了不同的 DBCS 编码⽅案。 在1994年之前,也就是Unicode编码出现之前,⼤陆地区的中国⼈想使⽤台 湾软件,还必须加装⼀套⽀持 BIG5 编码的”倚天汉字系统”才可以⽤,装错了字符系统,显示就会乱码。</p></li><li><p>ISO (国际标准化组织 International Organization for Standardization)组 织着⼿解决编码不统⼀的问题舍弃了所有地区性编码⽅案,重新搞了⼀个包括了地球上所有⽂化、所有字 ⺟和符号的编码!做”Universal Multiple-Octet Coded Character Set”,(字 ⾯意思:全球通⽤的多⼋位字节字符集,中⽂名称为:统⼀字符集)简称UCS, 俗称 “Unicode”。</p><p> Unicode是计算机科学领域⾥的⼀项业界标准,包括字符集、编码⽅案等。 Unicode 是为了解决传统的字符编码⽅案的局限⽽产⽣的,它为每种语⾔中的每 个字符设定了统⼀并且唯⼀的⼆进制编码,以满⾜跨语⾔、跨平台进⾏⽂本转换、处理的要求。1990年开始研发,1994年正式公布。Unicode编码的出现,其实就是为了适应全球化的发展,便于不同语⾔之间的兼容交互,⽽ASCII编码⽆法完成这个任务。</p></li></ol><h5 id="(⼆)、Unicode编码的特点"><a href="#(⼆)、Unicode编码的特点" class="headerlink" title="(⼆)、Unicode编码的特点"></a>(⼆)、Unicode编码的特点</h5><ol><li>Unicode 开始制订时,计算机的存储器容量极⼤地发展,空间再也不成为问 题。<ul><li>Unicode字符集中,ISO 直接规定必须⽤两个字节(UCS-2⽅案),也就 是16位来统⼀表示所有的字符;</li><li>对于ASCII码中的字符,Unicode 保持其原编码不变,但是将其⻓长度由原 来的8位扩展为16位,⽽其他⽂化和语⾔的字符则全部重新统⼀编码;</li><li>由于”半⻆角”英⽂符号只需要⽤到低8位,所以其⾼8位永远是0来补⻬齐,因 此这种⼤⽓的⽅案在保存英⽂⽂本时会多浪费⼀倍的空间。</li></ul></li><li>Unicode 是⽤两个字节来表示为⼀个字符,总共可以组合出65536不同的字 符这⼤概已经可以覆盖世界上所有⽂化的符号。但是Unicode对汉字⽀持其实 依然不⾜够好,因为简体和繁体汉字总共有六七万个汉字,⽽UCS-2最多能表示 65536个,所以Unicode只能排除⼀些⼏乎不⽤的汉字,好在常⽤的简体汉字也 不过七千多个。为了能表示所有的汉字,ISO已经准备了UCS-4⽅案,给Unicode增加了UCS-4规范,就是⽤四个字节来表示⼀个字符,这样就可以保存 42亿个不同的字符了!</li><li>Unicode字符集中包含中⽂字符<strong>20902</strong>个。其中第⼀个是汉字“⼀”(位置编号为19968,⼗六进制表示为:\u4E00),最后⼀个是汉字“龥”(位置编号40869,⼗六进制表示为:\u9FA5)。请⼤家牢记:[\u4E00-\u9FA5]。它表示 Unicode字符集中第⼀个中⽂字符到最后⼀个中⽂字符的意思,换句话说它是所 有中⽂字的表达式。这在以后的⼯作中经常⽤到。</li></ol><p><code>备注:</code></p><p> <code>“龥”字同【吁】字。</code></p><ul><li><code>⼀拼⾳xu1。</code><ul><li><code>叹息:⻓长~短叹。</code><ul><li><code>⼆拼⾳yu4【吁】的简体字</code></li></ul></li></ul></li><li><code>为某种要求⽽呼喊:呼~。</code><ul><li><code>三拼⾳yu1</code></li></ul></li><li><code>象声字,哟喝牲⼝停⽌前进的声⾳</code></li></ul><ol start="4"><li>Unicode编码与GBK系列编码最⼤的区别<ul><li>Unicode编码虽然与GBK都是双字节编码,但是Unicode编码中每个字符 都是两个字节,即便是原ASCII码中的字符也是两个字节;⽽GBK编码中依 然保留原ASCII码中的字符为单字节,除此之外的字符才是双字节。</li></ul></li><li>Unicode 在制订时没有考虑与任何⼀种现有的编码⽅案保持兼容<ul><li>因此 GBK 与Unicode 在汉字的内码编排上完全是不⼀样的,没有⼀种简单 的算术⽅法可以把⽂本内容从Unicode编码和另⼀种编码进⾏转换,这种转换必 须通过查表来进⾏。</li></ul></li></ol><h4 id="五、Unicode字符集的字符编码规则"><a href="#五、Unicode字符集的字符编码规则" class="headerlink" title="五、Unicode字符集的字符编码规则"></a>五、<strong>Unicode</strong>字符集的字符编码规则</h4><h5 id="(⼀)、UTF编码"><a href="#(⼀)、UTF编码" class="headerlink" title="(⼀)、UTF编码"></a>(⼀)、UTF编码</h5><p>事实证明,对可以⽤ASCII表示的字符使⽤Unicode并不⾼效,因为Unicode⽐ASCII占⽤⼤⼀倍的空间。⼀个ASCII中的数字和字⺟,明明可以⽤⼋位0和1就表示清楚,Unicode⾮ 要⽤16位来表示。那么多余的那8位(也就是⾼字节)⽤0来补⻬齐,对ASCII码来 说⾼字节的0毫⽆⽤处,⽩⽩浪费了空间。 为了保证在⽹络传输中减少不必要的流量浪费,提升⽂本传输速度,出现了 ⼀些中间格式的字符集,他们被称为统⼀的转换格式,即UTF系列编码(Unicode Transformation Format)。UTF是Unicode字符集的编码⽅式。 常⻅见的UTF格式有:UTF-8、UTF-16以及 UTF-32。⽆论是UTF-16还是 UTF-8都是处理Unicode字符集的,但是它们的编码规则不相同。</p><h5 id="(⼆)、UTF-16编码"><a href="#(⼆)、UTF-16编码" class="headerlink" title="(⼆)、UTF-16编码"></a>(⼆)、UTF-16编码</h5><p>UTF-16⽐较好理解,就是任何字符都⽤两个字节来保存。</p><ul><li>Unicode在定义时就是两个字节表示⼀个字符,因此常常将Unicode与 UTF-16等同对待;</li><li>UTF-16编码效率最⾼,字符到字节相互转换更简单,进⾏字符串操作也更好。它适合在本地磁盘和内存之间使⽤,可以进⾏字符和字节之间的快速 切换,如Java的内存编码就采⽤UTF-16编码;</li><li>UTF-16不够经济,如果⽂档中都是英⽂字⺟,那么这个做就⾮常浪费。明明⽤⼀个字节就能保存的偏⽤两个字节来保存。尤其在现在的⽹络带宽还 有限的今天,使⽤UTF-16编码会增⼤⽹络传输的流量,很没必要;</li><li>UTF-16编码不适合在⽹络之间传输,因为⽹络传输容易损坏字节流,⼀ 旦字节流损坏将很难恢复。</li></ul><h5 id="(三)、UTF-8编码"><a href="#(三)、UTF-8编码" class="headerlink" title="(三)、UTF-8编码"></a>(三)、UTF-8编码</h5><ol><li><p>utf-8编码是Unicode字符集最常⽤的编码⽅式。</p><ul><li>UTF-8⽐UTF-16的解码要复杂。UTF-8编码是可变字节编码;</li><li>⽂本读取是⼀个字节⼀个字节的来读取,然后再根据字节中开头的bit标志 来识别,然后确定⼏个字节是⼀个字符单元;</li><li>UTF-8字符集中,原Unicode前128个字符是单字节编码(实体编号在127 以内),编号在128⾄2047的是双字节编码(2的11次⽅=2048),编号在 2048之后就是三字节编码;</li><li>⼀个字节代表⼀个字符:第⼀个字节为0。</li><li>两个字节代表⼀个字符:第⼀个字节的前3位是110,第2个字节的前2 位是10,说明两个字节代表⼀个字符;</li><li>三个字节代表⼀个字符:第1个字节的前4位是1110,第2个字节的前2 位是10,第3个字节的前2位是10,说明三个字节代表⼀个字符。如下图:</li></ul><p><img src="https://ws3.sinaimg.cn/large/e64a4785gy1fxnufs96a5j20dn04bmxx.jpg" alt=""></p><ul><li>UTF-8⽂件中,ASCII码占⼀个字节,中⽂字则占三字节⻓长度; </li><li>相⽐较UTF-16⽽⾔,UTF-8更适合⽹络传输。<ul><li>对ASCII字符采⽤单字节存储,最⼤程度低节省⽂件传输时的流量⼤ ⼩;</li><li>单个字符损坏也不会影响后⾯的其他字符,编码安全性强;</li><li>在编码效率上介于GBK和UTF-16之间;</li><li>因此,UTF-8在编码效率上和编码安全性上做了平衡,是理想的中⽂ 编码⽅式。</li></ul></li></ul></li><li><p>UTF-8⽂件的解码过程</p><ul><li><p>建议使⽤的软件⼯具:</p><ul><li>进制转化可以通过在线进制转换⼯具实现。<a href="https://tool.lu/hexconvert/" rel="external nofollow noopener noreferrer" target="_blank">https://tool.lu/hexconvert/</a> </li><li>查看⼗六进制代码建议使⽤:<strong>UltraEdit</strong>⽂本编辑器</li><li>⽹⻚页制作建议使⽤:HBuilder前端开发⼯具</li></ul></li><li><p>举例说明计算机对UTF-8⽂件的解码过程</p><p>有⼀个UTF-8编码的⽂本,⽂本内容如下:</p><p><code>“aá⼀”</code></p><p><code>分别是英⽂字⺟“a”,法语字⺟“á”,中⽂汉字“⼀”。</code></p><ol><li><p>获取⼗六进制编码为:61 C3 A9 E4 B8 80</p></li><li><p>计算二进制编码:</p><p>01100001</p><p>11000011</p><p>10100001</p><p>11100100</p><p>10111000</p><p>10000000</p><p><code>此时,能看出该⽂本共有六个字节。到底哪⼏个字节是⼀个字符单元呢?</code></p><ol start="3"><li>根据<strong>UTF-8</strong>编码规则将字节分组后:</li></ol><p>01100001</p><p>11000011</p><p>10100001</p><p>11100100</p><p>10111000</p><p>10000000</p><ol start="4"><li>重新计算,得出对应<strong>Unicode</strong>字符集的⼆进制编码为:</li></ol><p>00000000 01100001</p><p>00000000 11100001</p><p>01001110 00000000 </p><ol start="5"><li>计算机从<strong>Unicode</strong>字符集中反查出字符为:</li></ol><p>a</p><p>á</p><p>⼀</p><p><code>【如何知道上述⼆进制编码对应的字符是什么呢?】</code></p><ul><li><p>⼗进制编号:</p><p>97</p><p>225</p><p>19968</p></li><li><p>知道<strong>Unicode</strong>字符的<strong>10</strong>进制编号后,反查该字符呢?</p><p>在html⽂件中利⽤html实体编号就可以查出来。</p><p><strong>&#</strong>实体编号;</p><p>aá一</p><p>输出:aá⼀</p></li></ul></li></ol></li></ul></li></ol><h5 id="(四)、UTF-8-编码(UTF-8-with-BOM)"><a href="#(四)、UTF-8-编码(UTF-8-with-BOM)" class="headerlink" title="(四)、UTF-8+编码(UTF-8 with BOM)"></a>(四)、UTF-8+编码(UTF-8 with BOM)</h5><ol><li><p>BOM (Byte Order Mark , 字节序列标记)</p><p>如果⽤记事本把⼀个⽂本⽂件另存为UTF-8编码⽅式的话,⽤ultraEditor打 开这个⽂件,切换到⼗六进制编辑状态就可以看到开头的EF BB BF了。这是个标 识UTF-8编码⽂件的好办法。如果接收者收到以EF BB BF开头的字节流,就知道 这是UTF-8编码的⽂件。所以UTF-8可以⽤BOM来表明编码⽅式。<br>其实EF BB BF的⼆进制编码为:<br> EF 11101111<br> BB 10111011<br> BF 10111111<br> 转成Unicode⼆进制编码为:1111111011111111 ⼗进制编号为:65279<br> 在html⻚页⾯上输出为:空格</p></li><li><p>UTF-8编码的⽂件中,BOM占三个字节。</p><p><img src="https://wx3.sinaimg.cn/large/e64a4785gy1fxnuyh567kj20hq0gw44m.jpg" alt=""></p></li></ol><h5 id="(五)、UTF-16-with-BOM编码"><a href="#(五)、UTF-16-with-BOM编码" class="headerlink" title="(五)、UTF-16 with BOM编码"></a>(五)、UTF-16 with BOM编码</h5><ol><li><p>保存的⽂件类型为UTF-16,那么开头的字节流是:FF FE (表示UTF- 16)。</p><p>FF FE的⼆进制编码为:11111111 11111110 Unicode⼆进制编码同上。</p><p>⼗进制编号为:65534</p><p>在html⻚页⾯上输出为:空格</p></li><li><p>UTF-16编码的⽂件中,BOM占两个字节。</p></li></ol><h4 id="六、“奇怪的联通现象”"><a href="#六、“奇怪的联通现象”" class="headerlink" title="六、“奇怪的联通现象”"></a>六、“奇怪的联通现象”</h4><h5 id="(⼀)、测试步骤"><a href="#(⼀)、测试步骤" class="headerlink" title="(⼀)、测试步骤:"></a>(⼀)、测试步骤:</h5><p>有个很著名的奇怪现象:当你在 windows 的记 事本⾥新建⼀个⽂件,输⼊”联通”两个字之后,保存,关闭,然后双击⽂件 打开。观察到什么了吗?</p><p>⽂字消失,取⽽代之的是⼏个乱码!</p><p>再试试输⼊“⼒挺联通”,保存后打开会如何呢?莫⾮联通得罪了微软?</p><p><img src="https://ws3.sinaimg.cn/large/e64a4785gy1fxnv2zqwu6j20dz048dh2.jpg" alt=""></p><h5 id="(⼆)、解答"><a href="#(⼆)、解答" class="headerlink" title="(⼆)、解答"></a>(⼆)、解答</h5><ul><li><p>其实出现乱码的主要原因是:GB2312编码与UTF-8编码产⽣了编码冲 撞,导致编码误解,从⽽触发了错误的⽂件打开⽅式所引起的;</p></li><li><p>当新建⼀个⽂本⽂件时,记事本的编码默认是ANSI,如果在ANSI的编码 输⼊汉字,那么他实际就是GB2312系列的编码,在这种编码下,”联通”的 ⼗六进制编码是:</p><p>C1 1100 0001</p><p>AA 1010 1010</p><p>CD 1100 1101</p><p>A8 1010 1000</p></li></ul><ul><li><p>虽然保存的是GB2312编码,但是编码后的的⼆进制数据正好和UTF-8的 格式吻合,所以“记事本”把这些字符(”联通”)当做UTF-8的编码去解码, 所以显示的结果会出现问题;</p></li><li><p>如果输⼊中⽂”爱联通”,保存⽂件后关闭。再次打开,则不会出现乱码问 题,因为中⽂”爱”在编码表中对应的⼆进制数据不符合UTF-8的格式,所以 记事本使⽤GB2312来解码,后⾯的”联通”当然也使⽤GB2312解码,所以就 不会出现乱码。总之,只要GBK⽂本的⼆进制编码不与UTF-8吻合,就不会 被误解为UTF-8⽂件,也就不会使⽤错误的打开⽅式来打开了;</p></li><li><p>⾮常奇妙的是输⼊“⼒挺联通”,还会出现乱码。原因是“⼒挺”这两个字的 GB2312⼆进制编码也恰好与UTF-8吻合;</p></li><li><p>换⼀种⽂本编辑器来打开,或许问题就不会出现。如果没有专业的⽂本编辑器,甚⾄使⽤word或浏览器来打开,也能正常显示。</p></li></ul><p><img src="https://ws4.sinaimg.cn/large/e64a4785gy1fxnv6a1i3xj20su0oygyk.jpg" alt=""></p><p><img src="https://ws3.sinaimg.cn/large/e64a4785gy1fxnvgjizsmj20hk0cgdix.jpg" alt=""></p><p><img src="https://ws2.sinaimg.cn/large/e64a4785gy1fxnvhe56joj20di09umxu.jpg" alt=""></p><h4 id="七、其它编码或字符集"><a href="#七、其它编码或字符集" class="headerlink" title="七、其它编码或字符集"></a>七、其它编码或字符集</h4><h5 id="(⼀)、ANSI编码"><a href="#(⼀)、ANSI编码" class="headerlink" title="(⼀)、ANSI编码"></a>(⼀)、ANSI编码</h5><p> ANSI是⼀种字符编码标准,其实就是各个国家或地区的国标。对于中国地</p><p>区就是GB2312编码,中国台湾地区就是BIG5编码,对于⽇本就是JIS编码,对于 美国⾃然就是ASCII码等等。</p><p> windows操作系统中的记事本,默认保存的编码就是ANSI编码(在中国就 是GB2312)</p><h5 id="(⼆)、ISO-8859-1字符集"><a href="#(⼆)、ISO-8859-1字符集" class="headerlink" title="(⼆)、ISO-8859-1字符集"></a>(⼆)、ISO-8859-1字符集</h5><p> 标准ASCII码只有128 个字符,后来变成了国际标准ISO-646。但是很显然 ASCII码实在太少,远远不够⽤,于是 在 ASCII 码基础上⼜制定了⼀系列标准⽤来扩展 ASCII 编码,它们是 ISO-8859-1~ISO-8859-15。其中 ISO-8859-1 涵盖了⼤多数⻄西欧语⾔字符,应⽤的最⼴泛;</p><ul><li>ISO-8859-1 仍然是单字节编码,它总共能表示 256 个字符。</li><li>Linux操作系统默认的就是ISO-8859-1编码; ⽽Win32操作系统的机器默 认是GB2312编码。</li></ul><blockquote><p> 常⻅见的字符集有 ASCII(ISO-646)、ISO-8859-1、GB2312、GBK、Unicode 等,它们都可以被看作是不同⽂化的⼤字典。字符 编码它们规定了字符转化的规则,按照这个规则就可以让计算机能正确地识别字 符。</p><p> ⽬前存储中⽂的编码格式很多,例如 GB2312、GBK、UTF-8、UTF-16 这 ⼏种格式都可以存储汉字,那到底选择哪种编码格式来保存⽂件呢?这就要综合 考虑、有所取舍,要考虑到底是存储空间重要还是编码效率更重要,从⽽正确选 择编码格式。</p></blockquote>]]></content>
<categories>
<category> 计算机基础 </category>
</categories>
<tags>
<tag> 字符集 </tag>
<tag> 字符编码 </tag>
</tags>
</entry>
</search>