-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
980 lines (472 loc) · 601 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
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>在文件夹中添加右键菜单“通过 Android Studio 打开项目”</title>
<link href="/posts/android-studio/"/>
<url>/posts/android-studio/</url>
<content type="html"><![CDATA[<h3 id="打开注册表编辑器"><a href="#打开注册表编辑器" class="headerlink" title="打开注册表编辑器"></a>打开注册表编辑器</h3><p>首先打开注册表编辑器,可以通过 Win+R 快捷键打开运行,然后输入 <code>regedit</code> 打开,也可以直接在任务栏的搜索框搜索“注册表编辑器”</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/android-studio/winr.png" alt=""></p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/android-studio/search.png" alt=""></p><h3 id="定位到右键菜单相关的注册表项"><a href="#定位到右键菜单相关的注册表项" class="headerlink" title="定位到右键菜单相关的注册表项"></a>定位到右键菜单相关的注册表项</h3><p>找到以下路径:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">计算机\HKEY_CLASSES_ROOT\Directory</span><br></pre></td></tr></table></figure><p>直接复制粘贴到地址栏回车即可。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/android-studio/top.png" alt=""></p><h3 id="添加所需的项"><a href="#添加所需的项" class="headerlink" title="添加所需的项"></a>添加所需的项</h3><h4 id="文件夹中空白处的右键菜单"><a href="#文件夹中空白处的右键菜单" class="headerlink" title="文件夹中空白处的右键菜单"></a>文件夹中空白处的右键菜单</h4><p>然后依次展开 <code>Background\shell</code>,在 <code>shell</code> 处右键,点击 <code>新建-项</code> ,新建项的名字可以随意,我这里为了方便识别写 <code>AndroidStudio</code> ,选中新建的 <code>AndroidStudio</code> 项,右侧会有一个叫”(默认)”的数据项,双击”(默认)”,填入 <code>Open Folder as AndroidStudio Project</code> ,这个就是最终在右键菜单中显示的内容,你也可以填写其他内容比如 <code>在 Android Studio 中打开</code> 。</p><p>然后在左侧 <code>AndroidStudio</code> 这一项点右键,点击 <code>新建-字符串值</code>,新建值的名字写 <code>Icon</code> ,双击 <code>Icon</code> ,在数值数据内填入 Android Studio 的安装路径,具体到exe文件,注意如果是64位系统这里要选 <code>studio64.exe</code> 。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/android-studio/background.png" alt=""></p><p>接下来还是在左侧 <code>AndroidStdio</code> 的地方右键,点击 <code>新建-项</code>,新建项的名字填 <code>command</code> ,双击右侧的 “(默认)”,在数值数据内填入如下格式的内容:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">"D:\Program Files\Android\Android Studio\bin\studio64.exe" "%V"</span><br></pre></td></tr></table></figure><p>将studio的路径换成你的安装路径即可,注意后面的 “%V”,以及引号都是半角(英文)引号。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/android-studio/b_command.png" alt=""></p><h4 id="选中文件夹右键菜单"><a href="#选中文件夹右键菜单" class="headerlink" title="选中文件夹右键菜单"></a>选中文件夹右键菜单</h4><p>回到上层的 <code>Directory</code> 项,展开 <code>shell</code> ,同样的方法添加 <code>AndroidStudio</code> 项并添加 <code>Icon</code> 数据项。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/android-studio/directory.png" alt=""></p><p>同样的方法添加 <code>command</code> 项,注意这里需要将 <code>%V</code> 换成 <code>%1</code>。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/android-studio/d_command.png" alt=""></p><h3 id="大功告成"><a href="#大功告成" class="headerlink" title="大功告成"></a>大功告成</h3><p>文件夹内空白处右键菜单</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/android-studio/b_result.png" alt=""></p><p>选中文件夹右键菜单</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/android-studio/d_result.png" alt=""></p>]]></content>
<categories>
<category> 乱七八糟 </category>
</categories>
<tags>
<tag> Android Studio </tag>
<tag> 右键菜单 </tag>
<tag> 打开项目 </tag>
</tags>
</entry>
<entry>
<title>二分类学习-分类模型的评价指标(AUC)</title>
<link href="/posts/auc/"/>
<url>/posts/auc/</url>
<content type="html"><![CDATA[<p>二分类常用的评价指标是 AUC(Area Under Curve),也就是ROC曲线和x轴之间的面积。</p><h2 id="1-什么是ROC曲线(Wiki)"><a href="#1-什么是ROC曲线(Wiki)" class="headerlink" title="1. 什么是ROC曲线(Wiki)"></a>1. 什么是ROC曲线(<a href="https://zh.wikipedia.org/wiki/ROC%E6%9B%B2%E7%BA%BF" target="_blank" rel="noopener">Wiki</a>)</h2><p>在了解AUC之前首先需要知道ROC曲线。在<a href="https://zh.wikipedia.org/wiki/信号检测理论" target="_blank" rel="noopener">信号检测理论</a>中,<strong>接收者操作特征曲线</strong>(<strong>receiver operating characteristic curve</strong>,即<strong>ROC曲线</strong>)是一种坐标图式的分析工具,用于 (1) 选择最佳的信号侦测模型、舍弃次佳的模型。 (2) 在同一模型中设定最佳<a href="https://zh.wikipedia.org/wiki/阈值" target="_blank" rel="noopener">阈值</a>。</p><p>在做决策时,ROC分析能不受成本/效益的影响,给出客观中立的建议。</p><h2 id="2-一些术语"><a href="#2-一些术语" class="headerlink" title="2. 一些术语"></a>2. 一些术语</h2><table align="center" style="border: thin solid"><tbody><tr><th colspan="2" rowspan="2"> </th><th colspan="2" align="center">真实值</th><th rowspan="2">总数</th></tr><tr><th><i>p</i></th><th><i>n</i></th></tr><tr><th rowspan="2" valign="middle">预<br>测<br>输<br>出</th><th valign="middle" style="padding:0.5em;"><i>p'</i></th><th style="padding:0.5em;">真阳性<br>(TP)</th><th style="padding:0.5em;">伪阳性<br>(FP)</th><th style="padding:0.5em;">P'</th></tr><tr><th valign="middle" style="padding:0.5em;"><i>n'</i></th><th style="padding: 0.5em;">伪阴性<br>(FN)</th><th style="padding:0.5em;">真阴性<br>(TN)</th><th style="padding:0.5em;">N'</th></tr><tr><th colspan="2" style="padding:0.5em;">总数</th><th align="center">P</th><th align="center">N</th><th></th></tr></tbody></table><p>下面所有的内容都是基于此混淆矩阵的。</p><h4 id="TP(真阳性)"><a href="#TP(真阳性)" class="headerlink" title="TP(真阳性)"></a>TP(真阳性)</h4><p>true positives,即正例被判定为正例的数量</p><h4 id="TN(真阴性)"><a href="#TN(真阴性)" class="headerlink" title="TN(真阴性)"></a>TN(真阴性)</h4><p>true negatives,即范例被判定为反例的数量</p><h4 id="FP(伪阳性)"><a href="#FP(伪阳性)" class="headerlink" title="FP(伪阳性)"></a>FP(伪阳性)</h4><p>false positives,即反例被判定为正例的数量</p><h4 id="FN(伪阴性)"><a href="#FN(伪阴性)" class="headerlink" title="FN(伪阴性)"></a>FN(伪阴性)</h4><p>false negative,即正例被判定为反例的数量</p><h4 id="TPR(真阳性率)"><a href="#TPR(真阳性率)" class="headerlink" title="TPR(真阳性率)"></a>TPR(真阳性率)</h4><p>true positives rate,又称:命中率 (hit rate)、敏感度(sensitivity)</p><p>$ TPR = \frac{TP}{P} = \frac{TP}{TP+FN}$</p><h4 id="FPR(伪阳性率)"><a href="#FPR(伪阳性率)" class="headerlink" title="FPR(伪阳性率)"></a>FPR(伪阳性率)</h4><p>false positive rate,又称:错误命中率,假警报率 (false alarm rate)</p><p>$ FPR = \frac{FP}{N} = {FP}{FP + TN}$</p><h4 id="ACC(准确度)"><a href="#ACC(准确度)" class="headerlink" title="ACC(准确度)"></a>ACC(准确度)</h4><p>accuracy,(真阳性+真阴性) / 总样本数</p><p>$ACC = \frac{TP + TN}{P + N}$</p><h4 id="Precision(精确率)"><a href="#Precision(精确率)" class="headerlink" title="Precision(精确率)"></a>Precision(精确率)</h4><p>$Precision = \frac{TP}{TP+FP}$ ,即当前划分到正样本类别中,被正确分类的比例。</p><h4 id="Recall(召回率)"><a href="#Recall(召回率)" class="headerlink" title="Recall(召回率)"></a>Recall(召回率)</h4><p>$Recall = TPR$ ,即所有的正样本类别中,被正确划分到正样本的比例(召回了多少正样本比例)。</p><h4 id="Loss-(损失率)"><a href="#Loss-(损失率)" class="headerlink" title="Loss (损失率)"></a>Loss (损失率)</h4><p>待确定</p><h4 id="F1-Score"><a href="#F1-Score" class="headerlink" title="F1-Score"></a>F1-Score</h4><p>F-Score 是 Precision 和 Recall 的加权调和平均,即</p><p>$\frac{1}{F} = \frac{1}{\alpha^2+1}\frac{1}{P}+\frac{\alpha^2}{\alpha^2+1}\frac{1}{R}$</p><p>$F=\frac{(\alpha^2+1)P*R}{\alpha^2P+R}$</p><p>当 $\alpha=1$ 时,F-Score 就是 F1-Score:</p><p>$\frac{1}{F1}=\frac{1}{2}(\frac{1}{P}+\frac{1}{R})$</p><p>$ F1=\frac{2PR}{P+R}$</p><h2 id="3-ROC空间"><a href="#3-ROC空间" class="headerlink" title="3. ROC空间"></a>3. ROC空间</h2><p>ROC空间将伪阳性率(FPR)定义为 <em>X</em> 轴,真阳性率(TPR)定义为 <em>Y</em> 轴。</p><p><strong>给定</strong>一个二元分类<strong>模型</strong>和它的<strong>阈值</strong>,就能从所有样本的(阳性/阴性)真实值和预测值计算出一个 (X=FPR, Y=TPR) 座标点。</p><p>从 (0, 0) 到 (1,1) 的对角线将ROC空间划分为左上/右下两个区域,在这条线的以上的点代表了一个好的分类结果(胜过随机分类),而在这条线以下的点代表了差的分类结果(劣于随机分类)。</p><p><strong>完美的预测</strong>是一个在左上角的点,在ROC空间座标 (0,1)点,X=0 代表着没有伪阳性,Y=1 代表着没有伪阴性(所有的阳性都是真阳性);也就是说,不管分类器输出结果是阳性或阴性,都是100%正确。一个<strong>随机的预测</strong>会得到位于从 (0, 0) 到 (1, 1) <strong>对角线</strong>(也叫<strong>无识别率线</strong>)上的一个点;最直观的随机预测的例子就是抛硬币。</p><h2 id="4-ROC-曲线"><a href="#4-ROC-曲线" class="headerlink" title="4. ROC 曲线"></a>4. ROC 曲线</h2><p>上述ROC空间里的单点,是给定分类模型且给定阈值后得出的。但同一个<a href="https://zh.wikipedia.org/w/index.php?title=二元分類模型&action=edit&redlink=1" target="_blank" rel="noopener">二元分类模型</a>的<a href="https://zh.wikipedia.org/wiki/阈值" target="_blank" rel="noopener">阈值</a>可能设定为高或低,每种阈值的设定会得出不同的FPR和TPR。</p><ul><li>将<strong>同一模型每个阈值</strong> 的 (FPR, TPR) 座标都画在ROC空间里,就成为<strong>特定模型的ROC曲线</strong>。</li></ul><h2 id="5-AUC"><a href="#5-AUC" class="headerlink" title="5. AUC"></a>5. AUC</h2><p>ROC曲线下方的面积(英语:Area under the Curve of ROC (AUC ROC)),其意义是:</p><ul><li>因为是在1x1的方格里求面积,AUC必在0~1之间。</li><li>假设阈值以上是阳性,以下是阴性;</li><li>若随机抽取一个阳性样本和一个阴性样本,分类器<strong>正确判断</strong>阳性样本的值高于阴性样本之<strong>几率</strong> 。</li><li>简单说:<strong>AUC值越大的分类器,正确率越高。</strong></li></ul><p>从AUC判断分类器(预测模型)优劣的标准:</p><ul><li>AUC = 1,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。</li><li>0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。</li><li>AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。</li><li>AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。</li></ul><h2 id="6-AUC-计算方法"><a href="#6-AUC-计算方法" class="headerlink" title="6. AUC 计算方法"></a>6. AUC 计算方法</h2><p>二者都是逼近法求近似值</p><h3 id="1)梯形法"><a href="#1)梯形法" class="headerlink" title="1)梯形法"></a>1)梯形法</h3><p>简单地将每个相邻的点以直线连接,计算连线下方的总面积。因为每一线段下方都是一个梯形,所以叫<strong>梯形法</strong>。</p><ul><li>优点:简单,所以常用。</li><li>缺点:倾向于低估AUC。</li></ul><h3 id="2)ROC-AUCH法"><a href="#2)ROC-AUCH法" class="headerlink" title="2)ROC AUCH法"></a>2)ROC AUCH法</h3><p>暂无。</p><hr><p>参考:</p><p><a href="https://testerhome.com/topics/10527" target="_blank" rel="noopener">https://testerhome.com/topics/10527</a></p><p><a href="https://zh.wikipedia.org/wiki/ROC%E6%9B%B2%E7%BA%BF" target="_blank" rel="noopener">https://zh.wikipedia.org/wiki/ROC%E6%9B%B2%E7%BA%BF</a></p><p><a href="https://www.jianshu.com/p/be2e037900a1" target="_blank" rel="noopener">https://www.jianshu.com/p/be2e037900a1</a></p>]]></content>
<categories>
<category> NLP </category>
<category> 二分类 </category>
</categories>
<tags>
<tag> NLP </tag>
<tag> 二分类 </tag>
<tag> AUC </tag>
</tags>
</entry>
<entry>
<title>binclassification</title>
<link href="/posts/binclassification/"/>
<url>/posts/binclassification/</url>
<content type="html"><![CDATA[<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Markmap</title><style>* { margin: 0; padding: 0;}#mindmap { display: block; width: 100vw; height: 100vh;}</style><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/themes/prism.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/style.min.css"><meta name="generator" content="Hexo 4.2.1"></head><body><svg id="mindmap"></svg><script src="https://cdn.jsdelivr.net/npm/[email protected]"></script><script src="https://cdn.jsdelivr.net/npm/[email protected]"></script><script>(getMarkmap => { window.WebFontConfig = { custom: { families: ['KaTeX_AMS', 'KaTeX_Caligraphic:n4,n7', 'KaTeX_Fraktur:n4,n7', 'KaTeX_Main:n4,n7,i4,i7', 'KaTeX_Math:i4,i7', 'KaTeX_Script', 'KaTeX_SansSerif:n4,n7,i4', 'KaTeX_Size1', 'KaTeX_Size2', 'KaTeX_Size3', 'KaTeX_Size4', 'KaTeX_Typewriter'] }, active: () => { getMarkmap().refreshHook.call(); } }; })(() => window.markmap)</script><script src="https://cdn.jsdelivr.net/npm/[email protected]/webfontloader.js" defer></script><script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.umd.min.js"></script><script>(r => { setTimeout(r); })(() => { const { markmap, mm } = window;})</script><script>((getMarkmap, getOptions, data) => { const { Markmap } = getMarkmap(); window.mm = Markmap.create('svg#mindmap', getOptions == null ? void 0 : getOptions(), data); })(() => window.markmap,null,{"t":"heading","d":1,"p":{"lines":[0,1]},"v":"二分类","c":[{"t":"heading","d":2,"p":{"lines":[2,3]},"v":"基础知识","c":[{"t":"heading","d":3,"p":{"lines":[4,5]},"v":"常用算法模型","c":[{"t":"heading","d":4,"p":{"lines":[6,7]},"v":"<a href=\"https://zh.wikipedia.org/zh-hans/%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%88%86%E7%B1%BB%E5%99%A8\">朴素贝叶斯</a>"},{"t":"heading","d":4,"p":{"lines":[8,9]},"v":"<a href=\"https://zh.wikipedia.org/wiki/%E9%80%BB%E8%BE%91%E5%9B%9E%E5%BD%92\">逻辑回归</a>","c":[{"t":"heading","d":5,"p":{"lines":[10,11]},"v":"线性回归"},{"t":"heading","d":5,"p":{"lines":[12,13]},"v":"激活函数","c":[{"t":"list_item","d":7,"p":{"lines":[14,15]},"v":"<a href=\"https://en.wikipedia.org/wiki/Sigmoid_function\">sigmoid</a> 函数"}]},{"t":"heading","d":5,"p":{"lines":[16,17]},"v":"损失函数"},{"t":"heading","d":5,"p":{"lines":[18,19]},"v":"梯度下降算法"}]},{"t":"heading","d":4,"p":{"lines":[20,21]},"v":"<a href=\"https://zh.wikipedia.org/wiki/K-%E8%BF%91%E9%82%BB%E7%AE%97%E6%B3%95\">KNN</a>"},{"t":"heading","d":4,"p":{"lines":[22,23]},"v":"<a href=\"https://zh.wikipedia.org/wiki/K-%E8%BF%91%E9%82%BB%E7%AE%97%E6%B3%95\">决策树</a>"},{"t":"heading","d":4,"p":{"lines":[24,25]},"v":"<a href=\"https://zh.wikipedia.org/wiki/K-%E5%B9%B3%E5%9D%87%E7%AE%97%E6%B3%95\">K-Means聚类</a>"},{"t":"heading","d":4,"p":{"lines":[26,27]},"v":"<a href=\"https://zh.wikipedia.org/zh-hans/AdaBoost\">AdaBoost</a>"},{"t":"heading","d":4,"p":{"lines":[28,29]},"v":"<a href=\"https://zh.wikipedia.org/wiki/%E4%BA%BA%E5%B7%A5%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C\">神经网络</a>"},{"t":"heading","d":4,"p":{"lines":[30,31]},"v":"<a href=\"https://zh.wikipedia.org/wiki/%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%9C%BA\">支持向量机(SVM)</a>"}]},{"t":"heading","d":3,"p":{"lines":[32,33]},"v":"模型评估","c":[{"t":"heading","d":4,"p":{"lines":[34,35]},"v":"AUC","c":[{"t":"heading","d":5,"p":{"lines":[36,37]},"v":"<a href=\"https://zh.wikipedia.org/wiki/ROC%E6%9B%B2%E7%BA%BF\">ROC 曲线</a>"},{"t":"heading","d":5,"p":{"lines":[38,39]},"v":"TP, TN, FP, FN","c":[{"t":"list_item","d":7,"p":{"lines":[40,41]},"v":"true positives"},{"t":"list_item","d":7,"p":{"lines":[41,42]},"v":"false positives"},{"t":"list_item","d":7,"p":{"lines":[42,43]},"v":"false negatives"},{"t":"list_item","d":7,"p":{"lines":[43,44]},"v":"true negatives"}]},{"t":"heading","d":5,"p":{"lines":[45,46]},"v":"TPR, FPR","c":[{"t":"list_item","d":7,"p":{"lines":[47,48]},"v":"<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>T</mi><mi>P</mi><mi>R</mi><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>N</mi></mrow></mfrac></mrow><annotation encoding=\"application/x-tex\">TPR = \\frac{TP}{TP+FN}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.68333em;vertical-align:0em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">T</span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">P</span><span class=\"mord mathnormal\" style=\"margin-right:0.00773em;\">R</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1.275662em;vertical-align:-0.403331em;\"></span><span class=\"mord\"><span class=\"mopen nulldelimiter\"></span><span class=\"mfrac\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.872331em;\"><span style=\"top:-2.655em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">T</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span><span class=\"mbin mtight\">+</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">F</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.10903em;\">N</span></span></span></span><span style=\"top:-3.23em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"frac-line\" style=\"border-bottom-width:0.04em;\"></span></span><span style=\"top:-3.394em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">T</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span></span></span></span></span><span class=\"vlist-s\"></span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.403331em;\"><span></span></span></span></span></span><span class=\"mclose nulldelimiter\"></span></span></span></span></span>"},{"t":"list_item","d":7,"p":{"lines":[48,49]},"v":"<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>F</mi><mi>P</mi><mi>R</mi><mo>=</mo><mfrac><mrow><mi>F</mi><mi>P</mi></mrow><mrow><mi>F</mi><mi>P</mi><mo>+</mo><mi>T</mi><mi>N</mi></mrow></mfrac></mrow><annotation encoding=\"application/x-tex\">FPR = \\frac{FP}{FP+TN}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.68333em;vertical-align:0em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">F</span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">P</span><span class=\"mord mathnormal\" style=\"margin-right:0.00773em;\">R</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1.275662em;vertical-align:-0.403331em;\"></span><span class=\"mord\"><span class=\"mopen nulldelimiter\"></span><span class=\"mfrac\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.872331em;\"><span style=\"top:-2.655em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">F</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span><span class=\"mbin mtight\">+</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">T</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.10903em;\">N</span></span></span></span><span style=\"top:-3.23em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"frac-line\" style=\"border-bottom-width:0.04em;\"></span></span><span style=\"top:-3.394em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">F</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span></span></span></span></span><span class=\"vlist-s\"></span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.403331em;\"><span></span></span></span></span></span><span class=\"mclose nulldelimiter\"></span></span></span></span></span>"}]},{"t":"heading","d":5,"p":{"lines":[50,51]},"v":"准确率 <span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>A</mi><mi>C</mi><mi>C</mi><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>T</mi><mi>N</mi></mrow><mrow><mi>t</mi><mi>o</mi><mi>t</mi><mi>a</mi><mi>l</mi></mrow></mfrac></mrow><annotation encoding=\"application/x-tex\">ACC = \\frac{TP+TN}{total}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.68333em;vertical-align:0em;\"></span><span class=\"mord mathnormal\">A</span><span class=\"mord mathnormal\" style=\"margin-right:0.07153em;\">C</span><span class=\"mord mathnormal\" style=\"margin-right:0.07153em;\">C</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1.217331em;vertical-align:-0.345em;\"></span><span class=\"mord\"><span class=\"mopen nulldelimiter\"></span><span class=\"mfrac\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.872331em;\"><span style=\"top:-2.6550000000000002em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\">t</span><span class=\"mord mathnormal mtight\">o</span><span class=\"mord mathnormal mtight\">t</span><span class=\"mord mathnormal mtight\">a</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.01968em;\">l</span></span></span></span><span style=\"top:-3.23em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"frac-line\" style=\"border-bottom-width:0.04em;\"></span></span><span style=\"top:-3.394em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">T</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span><span class=\"mbin mtight\">+</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">T</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.10903em;\">N</span></span></span></span></span><span class=\"vlist-s\"></span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.345em;\"><span></span></span></span></span></span><span class=\"mclose nulldelimiter\"></span></span></span></span></span>"},{"t":"heading","d":5,"p":{"lines":[52,53]},"v":"损失率","c":[{"t":"list_item","d":7,"p":{"lines":[54,55]},"v":"sigmoid"},{"t":"list_item","d":7,"p":{"lines":[55,56]},"v":"softmax"}]},{"t":"heading","d":5,"p":{"lines":[57,58]},"v":"精确率","c":[{"t":"list_item","d":7,"p":{"lines":[59,60]},"v":"<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>P</mi><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>P</mi></mrow></mfrac></mrow><annotation encoding=\"application/x-tex\">P = \\frac{TP}{TP+FP}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.68333em;vertical-align:0em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">P</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1.275662em;vertical-align:-0.403331em;\"></span><span class=\"mord\"><span class=\"mopen nulldelimiter\"></span><span class=\"mfrac\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.872331em;\"><span style=\"top:-2.655em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">T</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span><span class=\"mbin mtight\">+</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">F</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span></span></span></span><span style=\"top:-3.23em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"frac-line\" style=\"border-bottom-width:0.04em;\"></span></span><span style=\"top:-3.394em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">T</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span></span></span></span></span><span class=\"vlist-s\"></span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.403331em;\"><span></span></span></span></span></span><span class=\"mclose nulldelimiter\"></span></span></span></span></span>"}]},{"t":"heading","d":5,"p":{"lines":[61,62]},"v":"召回率","c":[{"t":"list_item","d":7,"p":{"lines":[63,64]},"v":"<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>R</mi><mo>=</mo><mi>T</mi><mi>P</mi><mi>R</mi></mrow><annotation encoding=\"application/x-tex\">R = TPR</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.68333em;vertical-align:0em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.00773em;\">R</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.68333em;vertical-align:0em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">T</span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">P</span><span class=\"mord mathnormal\" style=\"margin-right:0.00773em;\">R</span></span></span></span>"}]},{"t":"heading","d":5,"p":{"lines":[65,66]},"v":"F-score","c":[{"t":"list_item","d":7,"p":{"lines":[67,68]},"v":"<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>F</mi><mo>=</mo><mfrac><mrow><mo stretchy=\"false\">(</mo><msup><mi>α</mi><mn>2</mn></msup><mo>+</mo><mn>1</mn><mo stretchy=\"false\">)</mo><mi>P</mi><mo>∗</mo><mi>R</mi></mrow><mrow><msup><mi>α</mi><mn>2</mn></msup><mi>P</mi><mo>+</mo><mi>R</mi></mrow></mfrac></mrow><annotation encoding=\"application/x-tex\">F = \\frac{(\\alpha^2+1)P*R}{\\alpha^2P+R}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.68333em;vertical-align:0em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">F</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1.512251em;vertical-align:-0.403331em;\"></span><span class=\"mord\"><span class=\"mopen nulldelimiter\"></span><span class=\"mfrac\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:1.10892em;\"><span style=\"top:-2.655em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.0037em;\">α</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.7463142857142857em;\"><span style=\"top:-2.786em;margin-right:0.07142857142857144em;\"><span class=\"pstrut\" style=\"height:2.5em;\"></span><span class=\"sizing reset-size3 size1 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span><span class=\"mbin mtight\">+</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.00773em;\">R</span></span></span></span><span style=\"top:-3.23em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"frac-line\" style=\"border-bottom-width:0.04em;\"></span></span><span style=\"top:-3.485em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mopen mtight\">(</span><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.0037em;\">α</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8913142857142857em;\"><span style=\"top:-2.931em;margin-right:0.07142857142857144em;\"><span class=\"pstrut\" style=\"height:2.5em;\"></span><span class=\"sizing reset-size3 size1 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span><span class=\"mbin mtight\">+</span><span class=\"mord mtight\">1</span><span class=\"mclose mtight\">)</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span><span class=\"mbin mtight\">∗</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.00773em;\">R</span></span></span></span></span><span class=\"vlist-s\"></span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.403331em;\"><span></span></span></span></span></span><span class=\"mclose nulldelimiter\"></span></span></span></span></span>"},{"t":"list_item","d":7,"p":{"lines":[68,70]},"v":"当 <span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>α</mi></mrow><annotation encoding=\"application/x-tex\">\\alpha</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.43056em;vertical-align:0em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.0037em;\">α</span></span></span></span> 为 1 时,F-score 就是 F1-score,<br>\n<span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>F</mi><mn>1</mn><mo>−</mo><mi>s</mi><mi>c</mi><mi>o</mi><mi>r</mi><mi>e</mi><mo>=</mo><mfrac><mrow><mn>2</mn><mi>P</mi><mi>R</mi></mrow><mrow><mi>P</mi><mo>+</mo><mi>R</mi></mrow></mfrac></mrow><annotation encoding=\"application/x-tex\">F1-score = \\frac{2PR}{P+R}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.76666em;vertical-align:-0.08333em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">F</span><span class=\"mord\">1</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span><span class=\"mbin\">−</span><span class=\"mspace\" style=\"margin-right:0.2222222222222222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.43056em;vertical-align:0em;\"></span><span class=\"mord mathnormal\">s</span><span class=\"mord mathnormal\">c</span><span class=\"mord mathnormal\">o</span><span class=\"mord mathnormal\" style=\"margin-right:0.02778em;\">r</span><span class=\"mord mathnormal\">e</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2777777777777778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1.275662em;vertical-align:-0.403331em;\"></span><span class=\"mord\"><span class=\"mopen nulldelimiter\"></span><span class=\"mfrac\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.872331em;\"><span style=\"top:-2.655em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span><span class=\"mbin mtight\">+</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.00773em;\">R</span></span></span></span><span style=\"top:-3.23em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"frac-line\" style=\"border-bottom-width:0.04em;\"></span></span><span style=\"top:-3.394em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">2</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.13889em;\">P</span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.00773em;\">R</span></span></span></span></span><span class=\"vlist-s\"></span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.403331em;\"><span></span></span></span></span></span><span class=\"mclose nulldelimiter\"></span></span></span></span></span>"}]}]}]}]},{"t":"heading","d":2,"p":{"lines":[71,72]},"v":"开发框架","c":[{"t":"heading","d":3,"p":{"lines":[73,74]},"v":"<a href=\"https://pytorch.org/\">Pytorch</a>","c":[{"t":"heading","d":4,"p":{"lines":[75,76]},"v":"简单介绍","c":[{"t":"list_item","d":6,"p":{"lines":[77,78]},"v":"<a href=\"https://en.wikipedia.org/wiki/PyTorch\">Wiki</a>"},{"t":"list_item","d":6,"p":{"lines":[78,84]},"v":"PyTorch是比较灵活的,它是Torch深度学习框架的一个端口,<br>\n可用于构建深度神经网络和执行Tensor计算。Torch是一个基于<br>\nLua的框架,而PyTorch是在Python上运行的,使用动态计算图,<br>\n它的Autogard软件包从tensors中构建计算图并自动计算梯度。<br>\nTensors是多维数组,就像numpy的ndarrays一样,也可以在<br>\nGPU上运行。"}]},{"t":"heading","d":4,"p":{"lines":[85,86]},"v":"环境配置","c":[{"t":"list_item","d":6,"p":{"lines":[87,92]},"v":"<pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># 以 ubuntu20.04 NVIDIA GTX 1050Ti 为例</span>\npip3 <span class=\"token function\">install</span> <span class=\"token assign-left variable\">torch</span><span class=\"token operator\">==</span><span class=\"token number\">1.8</span>.1+cu111 <span class=\"token assign-left variable\">torchvision</span><span class=\"token operator\">==</span><span class=\"token number\">0.9</span>.1+cu111 <span class=\"token assign-left variable\">torchaudio</span><span class=\"token operator\">==</span><span class=\"token number\">0.8</span>.1 -f https://download.pytorch.org/whl/torch_stable.html\n</code></pre>\n"},{"t":"list_item","d":6,"p":{"lines":[92,93]},"v":"注:不同GPU型号和驱动版本对应不同cuda版本,需要自行配对(网上有对照表)"}]},{"t":"heading","d":4,"p":{"lines":[95,96]},"v":"官方文档","c":[{"t":"list_item","d":6,"p":{"lines":[97,98]},"v":"<a href=\"https://pytorch.org/tutorials/\">https://pytorch.org/tutorials/</a>"}]}]},{"t":"heading","d":3,"p":{"lines":[99,100]},"v":"<a href=\"https://www.tensorflow.org/\">TensorFlow</a>","c":[{"t":"heading","d":4,"p":{"lines":[101,102]},"v":"简单介绍","c":[{"t":"list_item","d":6,"p":{"lines":[103,104]},"v":"<a href=\"https://en.wikipedia.org/wiki/TensorFlow\">Wiki</a>"},{"t":"list_item","d":6,"p":{"lines":[104,106]},"v":"TensorFlow由GoogleBrain团队的研究人员和工程师开发,<br>\n是深度学习领域中最常用的软件库"}]},{"t":"heading","d":4,"p":{"lines":[107,108]},"v":"环境配置","c":[{"t":"list_item","d":6,"p":{"lines":[109,116]},"v":"<pre class=\"language-bash\"><code class=\"language-bash\">pip <span class=\"token function\">install</span> pandas\npip <span class=\"token function\">install</span> <span class=\"token assign-left variable\">tensorflow</span><span class=\"token operator\">==</span><span class=\"token number\">1.14</span>.0\n<span class=\"token punctuation\">..</span>.\n</code></pre>\n"}]},{"t":"heading","d":4,"p":{"lines":[116,117]},"v":"官方文档","c":[{"t":"list_item","d":6,"p":{"lines":[118,119]},"v":"<a href=\"https://www.tensorflow.org/tutorials?hl=zh-cn\">https://www.tensorflow.org/tutorials?hl=zh-cn</a>"}]}]},{"t":"heading","d":3,"p":{"lines":[120,121]},"v":"NeoML"},{"t":"heading","d":3,"p":{"lines":[122,123]},"v":"Altapps"},{"t":"heading","d":3,"p":{"lines":[124,125]},"v":"Keras"},{"t":"heading","d":3,"p":{"lines":[126,127]},"v":"Caffe"},{"t":"heading","d":3,"p":{"lines":[128,129]},"v":"DeepLearning4j"},{"t":"heading","d":3,"p":{"lines":[130,131]},"v":"..."}]}]})</script></body></html>]]></content>
</entry>
<entry>
<title>二分类学习思维导图</title>
<link href="/posts/binclassify/"/>
<url>/posts/binclassify/</url>
<content type="html"><![CDATA[<iframe frameborder="no" width="100%"height="800px"src="/posts/binclassification/index.html"></iframe><hr><p>参考资料:</p><p><a href="https://samperson1997.github.io/2018/06/03/classification-algorithm/" target="_blank" rel="noopener">https://samperson1997.github.io/2018/06/03/classification-algorithm/</a></p><p><a href="https://zhuanlan.zhihu.com/p/62762472" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/62762472</a></p><p><a href="https://testerhome.com/topics/10527" target="_blank" rel="noopener">https://testerhome.com/topics/10527</a></p><p><a href="https://www.jianshu.com/p/be2e037900a1" target="_blank" rel="noopener">https://www.jianshu.com/p/be2e037900a1</a></p>]]></content>
<categories>
<category> NLP </category>
<category> 二分类 </category>
</categories>
<tags>
<tag> NLP </tag>
<tag> 二分类 </tag>
<tag> 思维导图 </tag>
</tags>
</entry>
<entry>
<title>VSCode 实用功能--用户片段(自定义文件模板)</title>
<link href="/posts/recommend/vsc-snippets/"/>
<url>/posts/recommend/vsc-snippets/</url>
<content type="html"><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p><strong>VSVode是全世界最好用的编辑器</strong>! </p><p>今天写C++的小程序突然觉得每次创建文件、创建调试的配置文件以及 Makefile 等很麻烦,于是想要创建一组文件模板,可以在每次创建项目的时候自动创建好需要的文件,经过搜索发现 vsc 的这个功能(用户代码),于是写下这篇博客记录一下。</p><p>vsc 默认可以创建一些语言专用的模板比如 c++、c#等,如下图:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vsc/kinds.png" alt="kinds"></p><p>但是我们也可以创建自定义的代码模板(全局使用),具体的操作如下:</p><h3 id="如何创建"><a href="#如何创建" class="headerlink" title="如何创建"></a>如何创建</h3><p>打开 VSCode,依次点击 文件-首选项-用户片段(英文为 File-Preference-UserSnippets),会出现上图中的选项</p><h4 id="首先创建C-的模板(可以自定义)如下:"><a href="#首先创建C-的模板(可以自定义)如下:" class="headerlink" title="首先创建C++的模板(可以自定义)如下:"></a>首先创建C++的模板(可以自定义)如下:</h4><p>选择 C++ 选项,在其中粘贴以下内容。</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//cpp.json</span></span><br><span class="line">{</span><br><span class="line"><span class="attr">"C++ Snippets"</span>:{</span><br><span class="line"><span class="attr">"prefix"</span>: <span class="string">"C++"</span>, <span class="comment">//在新建立的文件中输入C++,Tab或回车可以自动补全为以下 body 的内容</span></span><br><span class="line"><span class="attr">"body"</span>: [</span><br><span class="line"><span class="string">"#include <iostream>"</span>,</span><br><span class="line"><span class="string">"using namespace std;"</span>,</span><br><span class="line"><span class="string">""</span>,</span><br><span class="line"><span class="string">"int main()"</span>,</span><br><span class="line"><span class="string">"{"</span>,</span><br><span class="line"><span class="string">"\t$0"</span>,<span class="comment">//$0表示创建好后光标位置,$1表示tab后下一个位置</span></span><br><span class="line"><span class="string">"\treturn 0;"</span>,</span><br><span class="line"><span class="string">"}"</span>,</span><br><span class="line"><span class="string">""</span>,</span><br><span class="line">],</span><br><span class="line"><span class="attr">"description"</span>: <span class="string">"A cpp file template."</span> <span class="comment">//提示信息</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>创建文件时文件内会有一些注释,可以看一下注释的内容,解释了如何创建模板以及一个示例。</p><p>此时在项目中创建一个 main.cpp 文件,在其中输入 <code>C++</code> ,会出现如下提示:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vsc/cpp.png" alt="cpp"></p><p>回车或 Tab,会自动补全为以下内容(不要跟我说建议不要 <code>using namespace std;</code> 🤡):</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vsc/cpp2.png" alt="cpp2"></p><h4 id="创建-Makefile-模板:"><a href="#创建-Makefile-模板:" class="headerlink" title="创建 Makefile 模板:"></a>创建 Makefile 模板:</h4><p>选择 New Global Snippets File,输入文件名,在其中填写以下内容</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="attr">"gcc makefile"</span>: {</span><br><span class="line"><span class="attr">"prefix"</span>: <span class="string">"makefile_gcc"</span>,</span><br><span class="line"><span class="attr">"body"</span>: [</span><br><span class="line"><span class="string">"CC=gcc"</span>,</span><br><span class="line"><span class="string">"SRCS=$(wildcard *.c)"</span>,</span><br><span class="line"><span class="string">"OBJS=$(patsubst %.c, %.o, $(SRCS))"</span>,</span><br><span class="line"><span class="string">"FLAG=-g"</span>,</span><br><span class="line"><span class="string">"NAME=$(wildcard *.c)"</span>,</span><br><span class="line"><span class="string">"TARGET=$(patsubst %.c, %.exe, $(NAME))"</span>,</span><br><span class="line"><span class="string">""</span>,</span><br><span class="line"><span class="string">"$(TARGET):$(OBJS)"</span>,</span><br><span class="line"><span class="string">"\t$(CC) -o $@ $^ $(FLAG)"</span>,</span><br><span class="line"><span class="string">""</span>,</span><br><span class="line"><span class="string">"%.o:%.c"</span>,</span><br><span class="line"><span class="string">"\t$(CC) -o $@ -c $< -g"</span>,</span><br><span class="line"><span class="string">""</span>,</span><br><span class="line"><span class="string">"clean:"</span>,</span><br><span class="line"><span class="string">"\tdel $(TARGET) $(OBJS)"</span></span><br><span class="line"></span><br><span class="line">],</span><br><span class="line"><span class="attr">"description"</span>: <span class="string">"gcc make file"</span></span><br><span class="line">},</span><br><span class="line"><span class="attr">"g++ makefile"</span>: {</span><br><span class="line"><span class="attr">"prefix"</span>: <span class="string">"makefile_g++"</span>,</span><br><span class="line"><span class="attr">"body"</span>: [</span><br><span class="line"><span class="string">"CC=g++"</span>,</span><br><span class="line"><span class="string">"SRCS=$(wildcard *.cpp)"</span>,</span><br><span class="line"><span class="string">"OBJS=$(patsubst %.cpp, %.o, $(SRCS))"</span>,</span><br><span class="line"><span class="string">"FLAG=-g"</span>,</span><br><span class="line"><span class="string">"NAME=$(wildcard *.cpp)"</span>,</span><br><span class="line"><span class="string">"TARGET=$(patsubst %.cpp, %.exe, $(NAME))"</span>,</span><br><span class="line"><span class="string">""</span>,</span><br><span class="line"><span class="string">"$(TARGET):$(OBJS)"</span>,</span><br><span class="line"><span class="string">"\t$(CC) -o $@ $^ $(FLAG)"</span>,</span><br><span class="line"><span class="string">""</span>,</span><br><span class="line"><span class="string">"%.o:%.c"</span>,</span><br><span class="line"><span class="string">"\t$(CC) -o $@ -c $< -g"</span>,</span><br><span class="line"><span class="string">""</span>,</span><br><span class="line"><span class="string">"clean:"</span>,</span><br><span class="line"><span class="string">"\trm -rf $(TARGET) $(OBJS)"</span></span><br><span class="line"></span><br><span class="line">],</span><br><span class="line"><span class="attr">"description"</span>: <span class="string">"g++ make file"</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在项目中新建一个 Makefile 文件,输入 makefile_g++,自动补全后为以下内容:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vsc/g%2B%2B.png" alt="g++"></p><p>可以自动扫描当前目录中以 <code>.cpp</code> 结尾的文件,并进行编译。</p><p><strong>具体参考 Makefile 万能模板。</strong></p><h4 id="创建调试所用的-task-json-模板"><a href="#创建调试所用的-task-json-模板" class="headerlink" title="创建调试所用的 task.json 模板"></a>创建调试所用的 task.json 模板</h4><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"><span class="attr">"Cpp Make Task"</span>: {</span><br><span class="line"><span class="attr">"prefix"</span>: <span class="string">"task_make"</span>,</span><br><span class="line"><span class="attr">"body"</span>: [</span><br><span class="line"><span class="string">"{"</span>,</span><br><span class="line"><span class="string">"\t\"tasks\": ["</span>,</span><br><span class="line"><span class="string">"\t{"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"type\": \"cppbuild\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"label\": \"Make\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"command\": \"D:\\\\\\\\Programs\\\\\\\\MinGW\\\\\\\\bin\\\\\\\\make.exe\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"args\": ["</span>,</span><br><span class="line"><span class="string">"\t\t\t\t// \"-g\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t// \"\\${file}\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t// \"-o\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t// \"\\${fileDirname}\\\\\\\\\\${fileBasenameNoExtension}.exe\""</span>,</span><br><span class="line"><span class="string">"\t\t\t],"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"options\": {"</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"cwd\": \"\\${workspaceFolder}\""</span>,</span><br><span class="line"><span class="string">"\t\t\t},"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"problemMatcher\": ["</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"\\$gcc\""</span>,</span><br><span class="line"><span class="string">"\t\t\t],"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"group\": {"</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"kind\": \"build\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"isDefault\": true"</span>,</span><br><span class="line"><span class="string">"\t\t\t},"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"detail\": \"调试器生成的任务。\""</span>,</span><br><span class="line"><span class="string">"\t\t}"</span>,</span><br><span class="line"><span class="string">"\t],"</span>,</span><br><span class="line"><span class="string">"\t\"version\": \"2.0.0\""</span>,</span><br><span class="line"><span class="string">"}"</span></span><br><span class="line">],</span><br><span class="line"><span class="attr">"description"</span>: <span class="string">"g++ debug task"</span></span><br><span class="line">},</span><br><span class="line"><span class="attr">"Cpp g++ task"</span>: {</span><br><span class="line"><span class="attr">"prefix"</span>: <span class="string">"task_g++"</span>,</span><br><span class="line"><span class="attr">"body"</span>: [</span><br><span class="line"><span class="string">"{"</span>,</span><br><span class="line"><span class="string">"\t\"tasks\": ["</span>,</span><br><span class="line"><span class="string">"\t{"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"type\": \"cppbuild\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"label\": \"g++\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"command\": \"D:\\\\\\\\Programs\\\\\\\\MinGW\\\\\\\\bin\\\\\\\\g++.exe\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"args\": ["</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"-g\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"\\${file}\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"-o\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"\\${fileDirname}\\\\\\\\\\${fileBasenameNoExtension}.exe\""</span>,</span><br><span class="line"><span class="string">"\t\t\t],"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"options\": {"</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"cwd\": \"\\${workspaceFolder}\""</span>,</span><br><span class="line"><span class="string">"\t\t\t},"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"problemMatcher\": ["</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"\\$gcc\""</span>,</span><br><span class="line"><span class="string">"\t\t\t],"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"group\": {"</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"kind\": \"build\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\"isDefault\": true"</span>,</span><br><span class="line"><span class="string">"\t\t\t},"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"detail\": \"调试器生成的任务。\""</span>,</span><br><span class="line"><span class="string">"\t\t}"</span>,</span><br><span class="line"><span class="string">"\t],"</span>,</span><br><span class="line"><span class="string">"\t\"version\": \"2.0.0\""</span>,</span><br><span class="line"><span class="string">"}"</span></span><br><span class="line">],</span><br><span class="line"><span class="attr">"description"</span>: <span class="string">"g++ debug task"</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="创建-launch-json-模板"><a href="#创建-launch-json-模板" class="headerlink" title="创建 launch.json 模板"></a>创建 launch.json 模板</h4><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"><span class="attr">"g++ launch"</span>: {</span><br><span class="line"><span class="attr">"prefix"</span>: <span class="string">"launch"</span>,</span><br><span class="line"><span class="attr">"body"</span>: [</span><br><span class="line"><span class="string">"{"</span>,</span><br><span class="line"><span class="string">"\t\"version\": \"0.2.0\","</span>,</span><br><span class="line"><span class="string">"\t\"configurations\": ["</span>,</span><br><span class="line"><span class="string">"\t\t{"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"name\": \"g++.exe - 生成和调试活动文件\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"type\": \"cppdbg\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"request\": \"launch\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"program\": \"\\${fileDirname}\\\\\\\\\\${fileBasenameNoExtension}.exe\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"args\": [],"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"stopAtEntry\": false,"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"cwd\": \"\\${workspaceFolder}\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"environment\": [],"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"externalConsole\": true,"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"MIMode\": \"gdb\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"miDebuggerPath\": \"D:\\\\\\\\Programs\\\\\\\\MinGW\\\\\\\\bin\\\\\\\\gdb.exe\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\"setupCommands\": ["</span>,</span><br><span class="line"><span class="string">"\t\t\t\t{"</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\t\"description\": \"为 gdb 启用整齐打印\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\t\"text\": \"-enable-pretty-printing\","</span>,</span><br><span class="line"><span class="string">"\t\t\t\t\t\"ignoreFailures\": true"</span>,</span><br><span class="line"><span class="string">"\t\t\t\t}"</span>,</span><br><span class="line"><span class="string">"\t\t\t],"</span>,</span><br><span class="line"><span class="string">"\t\t\t\"preLaunchTask\": \"Make$0\""</span>,</span><br><span class="line"><span class="string">"\t\t}"</span>,</span><br><span class="line"><span class="string">"\t]"</span>,</span><br><span class="line"><span class="string">"}"</span></span><br><span class="line">],</span><br><span class="line"><span class="attr">"description"</span>: <span class="string">"g++ launch"</span></span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>以上。</p>]]></content>
<categories>
<category> recommend </category>
</categories>
<tags>
<tag> vscode </tag>
<tag> 模板 </tag>
<tag> 用户片段 </tag>
<tag> Makefile </tag>
</tags>
</entry>
<entry>
<title>Mirai QQ机器人安装及配置(以CentOS为例)</title>
<link href="/posts/mirai-install/"/>
<url>/posts/mirai-install/</url>
<content type="html"><![CDATA[<h2 id="一、安装框架"><a href="#一、安装框架" class="headerlink" title="一、安装框架"></a>一、安装框架</h2><h3 id="1-安装iTXTech-MCL-Installer"><a href="#1-安装iTXTech-MCL-Installer" class="headerlink" title="1. 安装iTXTech MCL Installer"></a>1. 安装iTXTech MCL Installer</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 首先安装 cargo 用于构建 mcl-installer </span></span><br><span class="line">$ sudo yum install cargo</span><br><span class="line"><span class="comment"># 安装 upx 用于压缩</span></span><br><span class="line">$ sudo yum install upx</span><br><span class="line"><span class="comment"># 克隆仓库</span></span><br><span class="line">$ git <span class="built_in">clone</span> https://github.com/iTXTech/mcl-installer.git</span><br><span class="line">$ <span class="built_in">cd</span> mcl-installer</span><br><span class="line"><span class="comment"># native-tls => 使用系统的 OpenSSL,rustls => 使用 rustls。</span></span><br><span class="line"><span class="comment"># --release 用于构建优化过的二进制文件,如需要进行调试请去除该参数。</span></span><br><span class="line"><span class="comment"># 在此之前要确保安装了Openssl,参考 https://cloudwafer.com/blog/installing-openssl-on-centos-7/</span></span><br><span class="line">$ cargo build --features native-tls --release</span><br><span class="line">$ <span class="built_in">cd</span> target/release</span><br><span class="line">$ strip mcl-installer <span class="comment"># strip 可减小可执行文件大小</span></span><br><span class="line">$ upx --best --lzma mcl-installer <span class="comment"># 使用 upx 压缩可进一步缩小可执行文件大小</span></span><br></pre></td></tr></table></figure><h3 id="2-安装iTXTech-MCL"><a href="#2-安装iTXTech-MCL" class="headerlink" title="2. 安装iTXTech MCL"></a>2. 安装iTXTech MCL</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">cd</span> PATH_TO_INSTALL_MCL <span class="comment"># 切换到要安装 mcl 的目录</span></span><br><span class="line">$ PATH_TO_INSTALLER/mcl-installer <span class="comment"># 运行mcl-installer</span></span><br><span class="line">Would you like to install Java? (Y/N, default: Y)</span><br><span class="line"><span class="comment"># 是否安装Java,如果上面的检测结果输出的Java版本大于11即可,可输入N跳过安装,否则必须安装Java</span></span><br><span class="line"></span><br><span class="line">Java version (8-15, default: 11): <span class="comment"># 选择Java版本安装,默认为Java 11</span></span><br><span class="line">JRE or JDK (1: JRE, 2: JDK, default: JRE): <span class="comment"># 选择JRE还是JDK安装,默认为JRE</span></span><br><span class="line">Binary Architecture (default: x64): <span class="comment"># 选择架构安装,默认x64</span></span><br><span class="line"><span class="comment"># 如果操作系统为Windows并且需要使用 mirai-native,请选择 x32(而不是i386等其他名字)</span></span><br><span class="line"></span><br><span class="line">The latest stable version of iTXTech MCL is x.x.x <span class="comment"># 获取最新MCL并询问是否下载</span></span><br><span class="line">Would you like to download it? (Y/N, default: Y) <span class="comment"># Y:下载,N:取消</span></span><br></pre></td></tr></table></figure><h3 id="3-安装-mirai-api-http-插件"><a href="#3-安装-mirai-api-http-插件" class="headerlink" title="3. 安装 mirai-api-http 插件"></a>3. 安装 <a href="https://github.com/project-mirai/mirai-api-http" target="_blank" rel="noopener">mirai-api-http</a> 插件</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">cd</span> PATH_TO_INSTALL_MCL <span class="comment"># 切换到 mcl安装目录</span></span><br><span class="line">$ ./mcl --update-package net.mamoe:mirai-api-http --channel stable --<span class="built_in">type</span> plugin</span><br></pre></td></tr></table></figure><h3 id="4-安装-mirai-login-solver-selenium-插件-用于登陆时完成验证码"><a href="#4-安装-mirai-login-solver-selenium-插件-用于登陆时完成验证码" class="headerlink" title="4. 安装 mirai-login-solver-selenium 插件(用于登陆时完成验证码)"></a>4. 安装 <strong><a href="https://github.com/project-mirai/mirai-login-solver-selenium" target="_blank" rel="noopener">mirai-login-solver-selenium</a></strong> 插件(用于登陆时完成验证码)</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ ./mcl --update-package net.mamoe:mirai-login-solver-selenium --channel nightly --<span class="built_in">type</span> plugin</span><br><span class="line"><span class="comment"># 第一次运行会下载geckodriver,可能会下载失败,可以手动下载(下载过程会有地址)放入 ./MxLibData/selenium 文件夹下在重新启动</span></span><br></pre></td></tr></table></figure><h2 id="二、使用python-SDK(Graia-Framework)"><a href="#二、使用python-SDK(Graia-Framework)" class="headerlink" title="二、使用python-SDK(Graia Framework)"></a>二、使用python-SDK(<a href="https://github.com/GraiaProject/Application" target="_blank" rel="noopener">Graia Framework</a>)</h2><p><strong>参考文档 <a href="https://graia-document.vercel.app/" target="_blank" rel="noopener">https://graia-document.vercel.app/</a></strong></p><p>本篇仅作最直接的过程,更多细节和解释可以查看原文档。</p><h3 id="1-安装sdk插件"><a href="#1-安装sdk插件" class="headerlink" title="1. 安装sdk插件"></a>1. 安装sdk插件</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ pip install graia-application-mirai</span><br></pre></td></tr></table></figure><h3 id="2-添加配置"><a href="#2-添加配置" class="headerlink" title="2. 添加配置"></a>2. 添加配置</h3><p>运行过一次mcl(通过命令 <code>./mcl</code> )后,会生成 <code>./config/net.mnmoe.mirai-api-http/setting.yml</code> 文件,修改其中的以下配置</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># file: mirai-client/config/MiraiAPIHTTP/net.mamoe.mirai.api.http.config.Setting</span></span><br><span class="line"><span class="attr">authKey:</span> <span class="string">graia-mirai-api-http-authkey</span> <span class="comment"># 你可以自己设定, 这里作为示范</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 可选,缓存大小,默认4096.缓存过小会导致引用回复与撤回消息失败</span></span><br><span class="line"><span class="attr">cacheSize:</span> <span class="number">4096</span></span><br><span class="line"></span><br><span class="line"><span class="attr">enableWebsocket:</span> <span class="literal">true</span> <span class="comment"># 是否启用 websocket 方式, 若使用 websocket 方式交互会得到更好的性能</span></span><br><span class="line"><span class="attr">host:</span> <span class="string">'0.0.0.0'</span> <span class="comment"># httpapi 服务监听的地址, 错误的设置会造成 Graia Application 无法与其交互</span></span><br><span class="line"><span class="attr">port:</span> <span class="number">8080</span> <span class="comment"># httpapi 服务监听的端口, 错误的设置会造成 Graia Application 无法与其交互</span></span><br></pre></td></tr></table></figure><h3 id="3-编写自己的插件"><a href="#3-编写自己的插件" class="headerlink" title="3. 编写自己的插件"></a>3. 编写自己的插件</h3><p>将以下代码保存到文件 <code>bot.py</code> 内, 确保该文件位于你的工作区内:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> graia.broadcast <span class="keyword">import</span> Broadcast</span><br><span class="line"><span class="keyword">from</span> graia.application <span class="keyword">import</span> GraiaMiraiApplication, Session</span><br><span class="line"><span class="keyword">from</span> graia.application.message.chain <span class="keyword">import</span> MessageChain</span><br><span class="line"><span class="keyword">import</span> asyncio</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> graia.application.message.elements.internal <span class="keyword">import</span> Plain</span><br><span class="line"><span class="keyword">from</span> graia.application.friend <span class="keyword">import</span> Friend</span><br><span class="line"></span><br><span class="line">loop = asyncio.get_event_loop()</span><br><span class="line"></span><br><span class="line">bcc = Broadcast(loop=loop)</span><br><span class="line">app = GraiaMiraiApplication(</span><br><span class="line"> broadcast=bcc,</span><br><span class="line"> connect_info=Session(</span><br><span class="line"> host=<span class="string">"http://localhost:8080"</span>, <span class="comment"># 填入 httpapi 服务运行的地址</span></span><br><span class="line"> authKey=<span class="string">"graia-mirai-api-http-authkey"</span>, <span class="comment"># 填入 authKey</span></span><br><span class="line"> account=<span class="number">1234567890</span>, <span class="comment"># 你的机器人的 qq 号</span></span><br><span class="line"> websocket=<span class="literal">True</span> <span class="comment"># Graia 已经可以根据所配置的消息接收的方式来保证消息接收部分的正常运作.</span></span><br><span class="line"> )</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="meta">@bcc.receiver("FriendMessage")</span></span><br><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">def</span> <span class="title">friend_message_listener</span><span class="params">(app: GraiaMiraiApplication, friend: Friend, message: MessageChain)</span>:</span></span><br><span class="line"> <span class="keyword">await</span> app.sendFriendMessage(friend, MessageChain.create([</span><br><span class="line"> Plain(<span class="string">f"Hello <span class="subst">{ friend.nickname }</span>, you said '<span class="subst">{ message.asDisplay() }</span>'!"</span>)</span><br><span class="line"> ]))</span><br><span class="line"></span><br><span class="line">app.launch_blocking()</span><br></pre></td></tr></table></figure><h3 id="4-运行自己的插件"><a href="#4-运行自己的插件" class="headerlink" title="4. 运行自己的插件"></a>4. 运行自己的插件</h3><p>首先保存 mcl 处于正常运行状态,出现类似如下信息</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ ./mcl</span><br><span class="line">......</span><br><span class="line">2021-04-03 01:55:26 I/Bot.1234567890: Login successful</span><br><span class="line">2021-04-03 01:55:26 I/main: mirai-console started successfully.</span><br><span class="line">2021-04-03 01:55:28 I/Bot.1234567890: Server list: 36.155.229.203:8080, 111.30.178.34:8080, 120.232.18.180:8080, 111.30.169.27:80, 36.155.229.140:14000, 120.232.18.55:443, 111.30.181.202:80, 36.155.229.228:80, msfwifi.3g.qq.com:8080, 111.30.169.93:80.</span><br></pre></td></tr></table></figure><p>运行插件:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ python bot.py</span><br></pre></td></tr></table></figure><p>接下来用另一个QQ向机器人发送消息即可(“Unknown Error”是我的QQ昵称)</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/mirai-install/first_dialogue.png" alt="first_dialogue"></p><p>同时,Mirai Console 得到以下日志:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">2021-04-03 02:24:49 V/Bot.2690919164: Unknown Error(1361050885) -> 123</span><br><span class="line">2021-04-03 02:24:49 V/Bot.2690919164: Friend(1361050885) <- Hello Unknown Error, you said '123'!</span><br><span class="line">2021-04-03 02:25:03 V/Bot.2690919164: Unknown Error(1361050885) -> 456</span><br><span class="line">2021-04-03 02:25:03 V/Bot.2690919164: Friend(1361050885) <- Hello Unknown Error, you said '456'!</span><br></pre></td></tr></table></figure><p>bot.py 得到以下日志:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[2021-04-03 02:24:49,152][INFO]: 2690919164: [Unknown Error(1361050885)] -> '[mirai:source:11960,1617387889]123'</span><br><span class="line">[2021-04-03 02:24:49,366][INFO]: [BOT 2690919164] Friend(1361050885) <- "Hello Unknown Error, you said '123'!"</span><br><span class="line">[2021-04-03 02:25:03,234][INFO]: 2690919164: [Unknown Error(1361050885)] -> '[mirai:source:11961,1617387903]456'</span><br><span class="line">[2021-04-03 02:25:03,432][INFO]: [BOT 2690919164] Friend(1361050885) <- "Hello Unknown Error, you said '456'!"</span><br></pre></td></tr></table></figure><p>至此,QQ机器人已经可以正常运行,至于机器人可以做哪些事情,就取决于你的插件有多么丰富了!</p><h3 id="5-更丰富的插件"><a href="#5-更丰富的插件" class="headerlink" title="5. 更丰富的插件"></a>5. 更丰富的插件</h3><p>在 <a href="https://graiaproject.github.io/Application/" target="_blank" rel="noopener">https://graiaproject.github.io/Application/</a> 中发现更多有用的api来使你的插件更加丰富。</p><h4 id="使用-saya-管理插件"><a href="#使用-saya-管理插件" class="headerlink" title="使用 saya 管理插件"></a>使用 saya 管理插件</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">pip install graia-saya</span><br><span class="line">pip install image</span><br><span class="line">git <span class="built_in">clone</span> https://github.com/Roc136/saya_plugins_collection.git</span><br></pre></td></tr></table></figure><hr><p>涉及到的项目仓库地址:</p><p>Mirai:<a href="https://github.com/mamoe/mirai" target="_blank" rel="noopener">https://github.com/mamoe/mirai</a></p><p>Mirai Console: <a href="https://github.com/mamoe/mirai-console" target="_blank" rel="noopener">https://github.com/mamoe/mirai-console</a></p><p>mirai-api-http: <a href="https://github.com/project-mirai/mirai-api-http" target="_blank" rel="noopener">https://github.com/project-mirai/mirai-api-http</a></p><p>Mirai Console Loader: <a href="https://github.com/iTXTech/mirai-console-loader" target="_blank" rel="noopener">https://github.com/iTXTech/mirai-console-loader</a></p><p>iTXTech MCL Installer: <a href="https://github.com/iTXTech/mcl-installer" target="_blank" rel="noopener">https://github.com/iTXTech/mcl-installer</a></p><p>mirai-login-solver-selenium: <a href="https://github.com/project-mirai/mirai-login-solver-selenium" target="_blank" rel="noopener">https://github.com/project-mirai/mirai-login-solver-selenium</a></p><p>Graia Framework: <a href="https://github.com/GraiaProject/Application" target="_blank" rel="noopener">https://github.com/GraiaProject/Application</a></p>]]></content>
<categories>
<category> NLP </category>
</categories>
<tags>
<tag> mirai </tag>
<tag> QQ机器人 </tag>
</tags>
</entry>
<entry>
<title>Ubuntu20.04安装加各项配置</title>
<link href="/posts/ubuntu-install/"/>
<url>/posts/ubuntu-install/</url>
<content type="html"><![CDATA[<h3 id="一、安装"><a href="#一、安装" class="headerlink" title="一、安装"></a>一、安装</h3><h4 id="选择语言"><a href="#选择语言" class="headerlink" title="选择语言"></a>选择语言</h4><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/ubuntu-install/QQ%E5%9B%BE%E7%89%8720210130000610.jpg" alt=""></p><h4 id="选择键盘布局"><a href="#选择键盘布局" class="headerlink" title="选择键盘布局"></a>选择键盘布局</h4><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/ubuntu-install/QQ%E5%9B%BE%E7%89%8720210130001230.jpg" alt=""></p><h4 id="选择安装方式"><a href="#选择安装方式" class="headerlink" title="选择安装方式"></a>选择安装方式</h4><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/ubuntu-install/QQ%E5%9B%BE%E7%89%8720210130001205.jpg" alt=""></p><h4 id="选择安装类型"><a href="#选择安装类型" class="headerlink" title="选择安装类型"></a>选择安装类型</h4><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/ubuntu-install/QQ%E5%9B%BE%E7%89%8720210130001224.jpg" alt=""></p><p>/分区,我这里选择分配70G的空间</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/ubuntu-install/QQ%E5%9B%BE%E7%89%8720210130001134.jpg" alt=""></p><p>交换分区,我只分配了4G的空间</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/ubuntu-install/QQ%E5%9B%BE%E7%89%8720210130001214.jpg" alt=""></p><p>/boot分区,网上的教程这里都只分配几百MB的空间,我这一次重装的原因就是升级内核时由于/boot空间不够而失败,又无法增大该分区,尝试删除旧内核也无效,无奈之下重装系统,/boot分配2G空间</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/ubuntu-install/QQ%E5%9B%BE%E7%89%8720210130001237.jpg" alt=""></p><p>/home分区,我分配了48G空间,/efi分区,我的128G硬盘剩余1G左右,将这些空间全部分配给efi分区</p><p>最终分配结果:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/ubuntu-install/QQ%E5%9B%BE%E7%89%8720210130001242.jpg" alt=""></p><h4 id="选择地区"><a href="#选择地区" class="headerlink" title="选择地区"></a>选择地区</h4><p>此处无图</p><h4 id="配置用户名密码"><a href="#配置用户名密码" class="headerlink" title="配置用户名密码"></a>配置用户名密码</h4><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/ubuntu-install/QQ%E5%9B%BE%E7%89%8720210130001247.jpg" alt=""></p><h3 id="二、一些配置"><a href="#二、一些配置" class="headerlink" title="二、一些配置"></a>二、一些配置</h3><h4 id="1-为root用户添加密码"><a href="#1-为root用户添加密码" class="headerlink" title="1. 为root用户添加密码"></a>1. 为root用户添加密码</h4><p>由于Ubuntu刚安装时root用户是没有密码的,需要为root设置密码</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo passwd</span><br></pre></td></tr></table></figure><p>接下来第一次输入当前用户的密码以执行sudo权限的命令,再输入两次为root设置的新密码</p><h4 id="2-设置开机自动挂载硬盘"><a href="#2-设置开机自动挂载硬盘" class="headerlink" title="2. 设置开机自动挂载硬盘"></a>2. 设置开机自动挂载硬盘</h4><p>由于我除了安装系统的128G固态之外还有一块2T的数据盘,每次开机都要手动挂载的话非常麻烦,设置自动挂载可以省下不少时间。</p><p>使用如下命令查看硬盘信息:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo blkid</span><br></pre></td></tr></table></figure><p>得到类似如下信息</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">/dev/nvme0n1p2: UUID="86a4a9ac-3ef7-4285-bb5a-25d18748a2d7" TYPE="swap" PARTUUID="97fcac94-ac56-4868-83a7-5fd86627b6ca"</span><br><span class="line">/dev/nvme0n1p1: UUID="8705b28b-d4ed-44b4-ba22-d580adc5f660" TYPE="ext4" PARTUUID="ad567570-370b-456f-8a7d-2cbb95f3e2c5"</span><br><span class="line">/dev/loop0: TYPE="squashfs"</span><br><span class="line">/dev/loop1: TYPE="squashfs"</span><br><span class="line">/dev/loop2: TYPE="squashfs"</span><br><span class="line">/dev/loop3: TYPE="squashfs"</span><br><span class="line">/dev/loop4: TYPE="squashfs"</span><br><span class="line">/dev/loop5: TYPE="squashfs"</span><br><span class="line">/dev/loop6: TYPE="squashfs"</span><br><span class="line">/dev/loop7: TYPE="squashfs"</span><br><span class="line">/dev/nvme0n1p3: UUID="99d887ca-093c-42e4-b559-8ce487582dba" TYPE="ext4" PARTUUID="0189dfdd-12ce-4b0d-afb5-560b10dcb73f"</span><br><span class="line">/dev/nvme0n1p4: UUID="a2263ce8-2541-40e5-beaa-8f0a5fedf8d2" TYPE="ext4" PARTUUID="ff1784cf-26a9-4dae-90a2-a3e0a7c90acc"</span><br><span class="line">/dev/nvme0n1p5: UUID="0CBD-9D7D" TYPE="vfat" PARTUUID="8b352fc8-fd4b-43ea-b97c-fbfd6f401f28"</span><br><span class="line">/dev/sda1: LABEL="Data" UUID="A03C00983C006C1A" TYPE="ntfs" PARTLABEL="Basic data partition" PARTUUID="276a3145-f2a5-4566-83be-7e22bf203706"</span><br><span class="line">/dev/sda2: LABEL="M-fM-^AM-\"M-eM-$M-^M" UUID="BE2C196B2C192047" TYPE="ntfs" PARTLABEL="Basic data partition" PARTUUID="8a98b31f-d6c9-447f-b586-a027f2c1d23c"</span><br><span class="line">/dev/sda3: UUID="B61B-0118" TYPE="vfat" PARTLABEL="EFI system partition" PARTUUID="b75d4ff7-ebfd-46d9-8d5e-fd591fe9514a"</span><br><span class="line">/dev/sda5: UUID="62E21DDDE21DB66F" TYPE="ntfs" PARTLABEL="Basic data partition" PARTUUID="8c6df33c-cfa3-438b-8a65-0cde412ff5df"</span><br><span class="line">/dev/loop8: TYPE="squashfs"</span><br><span class="line">/dev/loop9: TYPE="squashfs"</span><br><span class="line">/dev/loop10: TYPE="squashfs"</span><br><span class="line">/dev/sda4: PARTLABEL="Microsoft reserved partition" PARTUUID="dea4dd3d-81fa-415e-843a-e9062c4f50e3"</span><br></pre></td></tr></table></figure><p>找到并记住自己要挂载的磁盘的UUID和Type,编辑fstab文件,假设为 UUID=abcdefg,Type=”ntfs”,创建要挂载的目录,比如 /mnt/Data</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo mkdir /mnt/Data</span><br><span class="line">sudo vim /etc/fstab</span><br></pre></td></tr></table></figure><p>在文件末尾添加 </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># UUID 挂载目录 分区磁盘格式 选项 是否开机检查 分区类型</span><br><span class="line">UUID=abcdefg /mnt/Data ntfs defaults 0 2</span><br></pre></td></tr></table></figure><p>第一个数字表示是否开机检查,第二个数字表示分区类型,0为交换分区,1为启动分区,2为普通分区</p><p><strong>不知道自己要挂载的是哪块分区怎么办?</strong></p><p>使用如下命令根据各分区的信息确定</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo fdisk -l</span><br></pre></td></tr></table></figure><p>可以得到类似这种信息</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br></pre></td><td class="code"><pre><span class="line">Disk /dev/loop0:97.9 MiB,102637568 字节,200464 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop1:54.98 MiB,57626624 字节,112552 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop2:9.7 MiB,9510912 字节,18576 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop3:62.9 MiB,65105920 字节,127160 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop4:29.9 MiB,31334400 字节,61200 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop5:255.58 MiB,267980800 字节,523400 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop6:49.8 MiB,52203520 字节,101960 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop7:31.9 MiB,32600064 字节,63672 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/nvme0n1:119.25 GiB,128035676160 字节,250069680 个扇区</span><br><span class="line">Disk model: KBG30ZMT128G TOSHIBA </span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line">磁盘标签类型:gpt</span><br><span class="line">磁盘标识符:7A17571D-39A0-4B0F-B57E-CB2437365401</span><br><span class="line"></span><br><span class="line">设备 起点 末尾 扇区 大小 类型</span><br><span class="line">/dev/nvme0n1p1 2048 139999231 139997184 66.8G Linux 文件系统</span><br><span class="line">/dev/nvme0n1p2 139999232 147998719 7999488 3.8G Linux swap</span><br><span class="line">/dev/nvme0n1p3 147998720 151998463 3999744 1.9G Linux 文件系统</span><br><span class="line">/dev/nvme0n1p4 154068992 250068991 96000000 45.8G Linux 文件系统</span><br><span class="line">/dev/nvme0n1p5 151998464 154068991 2070528 1011M EFI 系统</span><br><span class="line"></span><br><span class="line">分区表记录没有按磁盘顺序。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/sda:1.84 TiB,2000398934016 字节,3907029168 个扇区</span><br><span class="line">Disk model: WDC WD20SPZX-08U</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 4096 字节</span><br><span class="line">I/O 大小(最小/最佳):4096 字节 / 4096 字节</span><br><span class="line">磁盘标签类型:gpt</span><br><span class="line">磁盘标识符:BA79D8A9-DDCC-4B25-8DE2-20FADCB70928</span><br><span class="line"></span><br><span class="line">设备 起点 末尾 扇区 大小 类型</span><br><span class="line">/dev/sda1 32768 3638593535 3638560768 1.7T Microsoft 基本数据</span><br><span class="line">/dev/sda2 3638593536 3639676927 1083392 529M Microsoft 基本数据</span><br><span class="line">/dev/sda3 3639676928 3639881727 204800 100M EFI 系统</span><br><span class="line">/dev/sda4 3639881728 3639914495 32768 16M Microsoft 保留</span><br><span class="line">/dev/sda5 3639914496 3898640383 258725888 123.4G Microsoft 基本数据</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop8:55.39 MiB,58073088 字节,113424 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop9:51.4 MiB,53522432 字节,104536 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/loop10:64.79 MiB,67915776 字节,132648 个扇区</span><br><span class="line">单元:扇区 / 1 * 512 = 512 字节</span><br><span class="line">扇区大小(逻辑/物理):512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳):512 字节 / 512 字节</span><br></pre></td></tr></table></figure><p>可以看到我要挂载的是1.7T的/dev/sda1分区,复制UUID,再编辑fstab文件即可。</p><p>下次开机就会自动挂载,此时要挂载可以用以下命令:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo mount /dev/sda1 /mnt/Data</span><br></pre></td></tr></table></figure><h4 id="3-修改文件管理器侧边栏默认的图片、文档、下载等文件夹的位置"><a href="#3-修改文件管理器侧边栏默认的图片、文档、下载等文件夹的位置" class="headerlink" title="3. 修改文件管理器侧边栏默认的图片、文档、下载等文件夹的位置"></a>3. 修改文件管理器侧边栏默认的图片、文档、下载等文件夹的位置</h4><p>使用以下命令修改配置</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo gedit ~/.config/user-dirs.dirs</span><br></pre></td></tr></table></figure><p>以下配置视个人情况自行决定,这里仅展示我的配置(由于我有一块额外的数据盘,所以将这些内容都放在另一块磁盘中,可以在重装系统的时候不必删除所有的数据)</p><p>将 </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">XDG_DOWNLOAD_DIR="$HOME/下载"</span><br><span class="line">XDG_DOCUMENTS_DIR="$HOME/文档"</span><br><span class="line">XDG_MUSIC_DIR="$HOME/音乐"</span><br><span class="line">XDG_PICTURES_DIR="$HOME/图片"</span><br><span class="line">XDG_VIDEOS_DIR="$HOME/视频"</span><br></pre></td></tr></table></figure><p>修改为</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">XDG_DOWNLOAD_DIR="/mnt/Data/Downloads"</span><br><span class="line">XDG_DOCUMENTS_DIR="/mnt/Data/WorkSpace/Word"</span><br><span class="line">XDG_MUSIC_DIR="/mnt/Data/WorkSpace/Music"</span><br><span class="line">XDG_PICTURES_DIR="/mnt/Data/WorkSpace/Photo"</span><br><span class="line">XDG_VIDEOS_DIR="/mnt/Data/WorkSpace/Video"</span><br></pre></td></tr></table></figure><p>这些配置将在下一次打开文件管理器的时候改变,旧的目录会自动添加到收藏栏,可以视情况自行删除。</p><h4 id="4-配置ssh"><a href="#4-配置ssh" class="headerlink" title="4. 配置ssh"></a>4. 配置ssh</h4><p><strong>在本地保存服务器信息</strong>,不需要每次连接时输入ip和密码</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim ~/.ssh/config</span><br></pre></td></tr></table></figure><p>添加以下信息,其中name是方便自己记忆的服务器名字,可以随意,下一次连接只需要 <code>ssh name</code> 即可,ip是自己的服务器ip,22是默认端口,可以不写,如果不是22端口就要写在这里,username是在服务器上的账户名字。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Host name</span><br><span class="line">HostName ip</span><br><span class="line">Port 22</span><br><span class="line">User username</span><br></pre></td></tr></table></figure><p><strong>在服务器上保存自己的ip和密码</strong></p><p>先在本地生成一对公钥密钥,过程需要输入生成的目录,默认是~/.ssh目录。该命令会生成:id_rsa(密钥)和 id_rsa.pub(公钥)</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-keygen -t rsa</span><br></pre></td></tr></table></figure><p>将公钥拷贝到服务器上,其中的name是前面保存信息时候写的名字,该过程会询问是否信任该服务器并要求输入一次服务器密码。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-copy-id name</span><br></pre></td></tr></table></figure><p>之后直接使用 <code>ssh name</code> 即可连接服务器。</p><h3 id="三、安装及配置常用软件"><a href="#三、安装及配置常用软件" class="headerlink" title="三、安装及配置常用软件"></a>三、安装及配置常用软件</h3><h4 id="0-换源"><a href="#0-换源" class="headerlink" title="0. 换源"></a>0. 换源</h4><p>桌面版的Ubuntu换源要比命令行方便多了,点击右上角图标-设置-关于-software updates-下载自</p><p>如果安装师地区选择了国内(shanghai)这里会是“中国的服务器”,但是还是会一些不方便,我会手动改成阿里云的源或清华的源。单击下拉选项,选择其他站点,选择阿里云的源(mirrors.aliyun.com)或清华的源(mirrors.tuna.tsinghua.edu.cn)。点击选择服务器,关闭时会更新软件缓存。</p><h4 id="1-v2ray"><a href="#1-v2ray" class="headerlink" title="1. v2ray"></a>1. v2ray</h4><p>众所周知,网络和git是程序员必不可少的两件利器,新装系统先把网络配置好才能更好地使用。</p><p>安装方式,参考 <a href="https://github.com/v2fly/" target="_blank" rel="noopener">https://github.com/v2fly/</a></p><p>可能遇到的问题 <a href="https://github.com/v2fly/fhs-install-v2ray/issues/122" target="_blank" rel="noopener">https://github.com/v2fly/fhs-install-v2ray/issues/122</a></p><p>使用 <code>sudo systemctl enable v2ray</code> 设置v2ray开机自启</p><h4 id="2-git"><a href="#2-git" class="headerlink" title="2. git"></a>2. git</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install git</span><br></pre></td></tr></table></figure><p><strong>查看git的所有配置</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git config --list</span><br></pre></td></tr></table></figure><p><strong>使用代理</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 将其中的port替换为自己的http代理端口</span></span><br><span class="line">git config --global http.proxy http://localhost:port</span><br><span class="line">git config --global https.proxy http://localhost:port</span><br></pre></td></tr></table></figure><p><strong>为git设置用户名和邮箱</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git config --global user.name <span class="string">"yourname"</span></span><br><span class="line">git config --global user.email youremail@youremail</span><br></pre></td></tr></table></figure><p><strong>查看用户名和邮箱</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git config user.name</span><br><span class="line">git config user.email</span><br></pre></td></tr></table></figure><h4 id="3-vim"><a href="#3-vim" class="headerlink" title="3. vim"></a>3. vim</h4><p>编辑器众多,最小巧,个性化配置最灵活的我认为要数vim了</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install vim</span><br><span class="line">vim ~/.vimrc</span><br></pre></td></tr></table></figure><p><strong>修改配置文件</strong></p><p>以下是一些简单的配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">"显示行号,关闭行号的命令为set nonumber</span><br><span class="line">set number</span><br><span class="line">"不与 Vi 兼容</span><br><span class="line">set nocompatible</span><br><span class="line">"语法高亮</span><br><span class="line">syntax on</span><br><span class="line">"启用256色</span><br><span class="line">set t_Co=256</span><br><span class="line">"开启文件类型检查,并且载入与该类型对应的缩进规则。</span><br><span class="line">filetype indent on</span><br><span class="line">"下一行的缩进会自动跟上一行的缩进保持一致</span><br><span class="line">set autoindent</span><br><span class="line">"光标所在的当前行高亮。</span><br><span class="line">set cursorline</span><br><span class="line">"输入搜索模式时,每输入一个字符,就自动跳到第一个匹配的结果</span><br><span class="line">set incsearch</span><br><span class="line">"光标遇到括号时自动高亮对应的另一个括号</span><br><span class="line">set showmatch</span><br><span class="line">"保存操作历史在文件中</span><br><span class="line">set undofile</span><br><span class="line">"设置最多保存多少次操作历史</span><br><span class="line">set history=1000</span><br><span class="line">"设置保存操作历史的文件路径</span><br><span class="line">set undodir=~/.vim/.undo//</span><br><span class="line">"设置备份文件路径</span><br><span class="line">set backupdir=~/.vim/.backup//</span><br><span class="line">"设置交换文件路径</span><br><span class="line">set directory=~/.vim/.swp//</span><br><span class="line">"打开文件监视。如果在编辑过程中文件发生外部改变(比如被别的编辑器编辑了),就会发出提示</span><br><span class="line">set autoread</span><br><span class="line">"命令模式下,底部操作指令按下 Tab 键自动补全。第一次按下 Tab,会显示所有匹配的操作指令的清单;第二次按下 Tab,会依次选择各个指令。</span><br><span class="line">set wildmenu</span><br><span class="line">set wildmode=longest:list,full</span><br></pre></td></tr></table></figure><p>更多配置可以参考:<a href="http://www.ruanyifeng.com/blog/2018/09/vimrc.html" target="_blank" rel="noopener">http://www.ruanyifeng.com/blog/2018/09/vimrc.html</a> 评论区也是有一些好内容的。</p><p>一些常用技巧:<a href="https://blog.csdn.net/weixin_47550354/article/details/106794738" target="_blank" rel="noopener">https://blog.csdn.net/weixin_47550354/article/details/106794738</a></p><h4 id="4-vscode"><a href="#4-vscode" class="headerlink" title="4. vscode"></a>4. vscode</h4><p>可视化的编辑器我用vscode</p><p>在官网下载最新的安装包 <a href="https://code.visualstudio.com/download" target="_blank" rel="noopener">https://code.visualstudio.com/download</a></p><p>选择deb包直接下载,下载好后双击就可以安装。</p><p><strong>添加插件</strong></p><p>推荐的几个插件:</p><ul><li>chinese - 简体中文,英文好的可以忽略</li><li>remote-ssh - ssh连接工具,可以直接在服务器上编辑代码,会自动读取本地~/.ssh/config文件中保存的服务器</li><li>Indent-Rainbow - 让对齐更具有可读性</li><li>Bracket Pair Colorizer - 让括号更具有可读性</li><li>Material Icon Theme - 好看的图标</li></ul><p>更多插件参考 <a href="https://zhuanlan.zhihu.com/p/40417719" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/40417719</a></p><p><strong>在右键添加 “在VSCode中打开”</strong></p><p>创建脚本文件,文件名即为右键时显示的命令名,可以自定义</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim ~/.<span class="built_in">local</span>/share/nautilus/scripts/codeit</span><br></pre></td></tr></table></figure><p>在文件中输入以下内容</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">#!/bin/bash</span><br><span class="line">code $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS</span><br></pre></td></tr></table></figure><p>添加执行权限</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo chmod u+x code_it</span><br></pre></td></tr></table></figure><h4 id="5-chrome"><a href="#5-chrome" class="headerlink" title="5. chrome"></a>5. chrome</h4><p>浏览器我用chrome</p><p><strong>配置插件</strong></p><p>前面安装好v2ray还没有真正使用,这里配合浏览器插件 ProxySwitchyOmega 可以方便地切换不同网络环境。插件自带教程,这里不做赘述。</p><p><strong>添加代理规则</strong></p><p>参考:<a href="https://github.com/gfwlist/gfwlist" target="_blank" rel="noopener">https://github.com/gfwlist/gfwlist</a></p><h4 id="6-Typora"><a href="#6-Typora" class="headerlink" title="6. Typora"></a>6. Typora</h4><p>在 markdown 离线编辑器里,Typora算是数一数二的了,小巧又美观。</p><p>参考 <a href="https://support.typora.io/Typora-on-Linux/" target="_blank" rel="noopener">https://support.typora.io/Typora-on-Linux/</a></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># or use</span></span><br><span class="line"><span class="comment"># sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA300B7755AFCFAE</span></span><br><span class="line">wget -qO - https://typora.io/linux/public-key.asc | sudo apt-key add -</span><br><span class="line"></span><br><span class="line"><span class="comment"># add Typora's repository</span></span><br><span class="line">sudo add-apt-repository <span class="string">'deb https://typora.io/linux ./'</span></span><br><span class="line">sudo apt-get update</span><br><span class="line"></span><br><span class="line"><span class="comment"># install typora</span></span><br><span class="line">sudo apt-get install typora</span><br></pre></td></tr></table></figure><p><strong>设置.md文件默认使用Typora打开</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo vim /etc/gnome/defaults.list</span><br></pre></td></tr></table></figure><p>在末尾添加</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">text/markdown=typora.desktop</span><br></pre></td></tr></table></figure><h4 id="7-wine-QQ,wine-WeChat"><a href="#7-wine-QQ,wine-WeChat" class="headerlink" title="7. wine-QQ,wine-WeChat"></a>7. wine-QQ,wine-WeChat</h4><p>没办法,这两个工作学习都需要</p><h5 id="安装wine架构"><a href="#安装wine架构" class="headerlink" title="安装wine架构"></a>安装wine架构</h5><p>参考 <a href="https://github.com/wszqkzqk/deepin-wine-ubuntu" target="_blank" rel="noopener">https://github.com/wszqkzqk/deepin-wine-ubuntu</a></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://gitee.com/wszqkzqk/deepin-wine-for-ubuntu.git</span><br><span class="line"><span class="built_in">cd</span> deepin-wine-for-ubuntu/</span><br><span class="line">sudo bash install.sh</span><br></pre></td></tr></table></figure><p>下载对应的QQ,微信容器安装包,双击即可安装。</p><h5 id="解决QQ无法加载图片的问题"><a href="#解决QQ无法加载图片的问题" class="headerlink" title="解决QQ无法加载图片的问题"></a>解决QQ无法加载图片的问题</h5><p>原因是wine对ipv6的支持出现问题,这里使用代理法方式绕开wine使用ipv6连接网络。</p><p>修改v2ray的配置文件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo vim /usr/<span class="built_in">local</span>/etc/v2ray/config.json</span><br></pre></td></tr></table></figure><p>添加以下内容,xxxx替换为自己要设置的端口,不要和已占用的端口重复</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"># 在 inbounds 项添加</span><br><span class="line">{</span><br><span class="line"> "tag": "qq",</span><br><span class="line"> "protocol": "http",</span><br><span class="line"> "listen": "127.0.0.1",</span><br><span class="line"> "port": xxxx,</span><br><span class="line"> "settings": {</span><br><span class="line"> "timeout": 0</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"># 在原有的 routing 后面添加</span><br><span class="line">"routing": {</span><br><span class="line"> "domainStrategy": "Asls",</span><br><span class="line"> "rules": [</span><br><span class="line"> {</span><br><span class="line"> "type": "field",</span><br><span class="line"> "inboundTag": "qq",</span><br><span class="line"> "outboundTag": "direct"</span><br><span class="line"> }</span><br><span class="line"> ]</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>QQ登陆界面点击右上角设置,使用http代理,ip填127.0.0.1,port填上面设定的端口,登陆后可以解决图片无法加载的问题。</p><p>下拉菜单无法显示,可以使用上下键切换,或者点击左上角wine右边的小箭头,选择TXMenuWindow就可以。</p><h5 id="解决微信聊天输入框中文显示为黑条或黑框,黑块的问题"><a href="#解决微信聊天输入框中文显示为黑条或黑框,黑块的问题" class="headerlink" title="解决微信聊天输入框中文显示为黑条或黑框,黑块的问题"></a>解决微信聊天输入框中文显示为黑条或黑框,黑块的问题</h5><p>参考 <a href="https://github.com/wszqkzqk/deepin-wine-ubuntu/issues/136#issuecomment-514585722" target="_blank" rel="noopener">https://github.com/wszqkzqk/deepin-wine-ubuntu/issues/136#issuecomment-514585722</a></p><p>网上的一种简单方法是修改wine启动文件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo vim /opt/deepinwine/tools/run.sh</span><br></pre></td></tr></table></figure><p>将 WINE_CMD 一行修改为</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">WINE_CMD="LC_ALL=zh_CN.UTF-8 deepin-wine"</span><br></pre></td></tr></table></figure><p>本人尝试后发现,每次登陆微信后需要在输入框输入一次小表情后才有效,这里使用的是另一种方法,修改字体文件。</p><p>下载微软雅黑字体(或其他任意字体),假设下载的字体文件名为 msyh.ttc</p><h6 id="1-添加字体"><a href="#1-添加字体" class="headerlink" title="1)添加字体"></a>1)添加字体</h6><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cp msyh.ttc ~/.deepinwine/Deepin-WeChat/drive_c/windows/Fonts</span><br></pre></td></tr></table></figure><h6 id="2-修改系统注册表"><a href="#2-修改系统注册表" class="headerlink" title="2)修改系统注册表"></a>2)修改系统注册表</h6><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gedit ~/.deepinwine/Deepin-WeChat/system.reg</span><br></pre></td></tr></table></figure><p>修改以下两行</p><p>“MS Shell Dlg”=”msyh”</p><p>“MS Shell Dlg 2”=”msyh”</p><h6 id="3-字体注册"><a href="#3-字体注册" class="headerlink" title="3)字体注册"></a>3)字体注册</h6><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gedit msyh_config.reg</span><br></pre></td></tr></table></figure><p>内容添加</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">REGEDIT4</span><br><span class="line">[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink]</span><br><span class="line">"Lucida Sans Unicode"="msyh.ttc"</span><br><span class="line">"Microsoft Sans Serif"="msyh.ttc"</span><br><span class="line">"MS Sans Serif"="msyh.ttc"</span><br><span class="line">"Tahoma"="msyh.ttc"</span><br><span class="line">"Tahoma Bold"="msyhbd.ttc"</span><br><span class="line">"msyh"="msyh.ttc"</span><br><span class="line">"Arial"="msyh.ttc"</span><br><span class="line">"Arial Black"="msyh.ttc"</span><br></pre></td></tr></table></figure><p>注册</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">WINEPREFIX=~/.deepinwine/Deepin-WeChat deepin-wine regedit msyh_config.reg</span><br></pre></td></tr></table></figure><h6 id="4-重启"><a href="#4-重启" class="headerlink" title="4)重启"></a>4)重启</h6><h5 id="解决微信不能发送图片的问题"><a href="#解决微信不能发送图片的问题" class="headerlink" title="解决微信不能发送图片的问题"></a>解决微信不能发送图片的问题</h5><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install libjpeg62:i386</span><br></pre></td></tr></table></figure><h4 id="8-gnome插件"><a href="#8-gnome插件" class="headerlink" title="8. gnome插件"></a>8. gnome插件</h4><p>一些好的插件可以让你的 Ubuntu 更易于使用。</p><p>首先安装连接器</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install chrome-gnome-shell</span><br></pre></td></tr></table></figure><p>安装浏览器插件 <a href="https://chrome.google.com/webstore/detail/gnome-shell-integration/gphhapmejobijbbhgpjhcjognlahblep" target="_blank" rel="noopener">GNOME Shell integration</a></p><p><a href="https://extensions.gnome.org/extension/19/user-themes/" target="_blank" rel="noopener"><strong>User Themes</strong></a> 自定义主题</p><p><a href="https://extensions.gnome.org/extension/307/dash-to-dock/" target="_blank" rel="noopener"><strong>Dash to Dock</strong></a> 替换系统的dock</p><p>可能会出现两个dock的情况,删除系统自带的 <code>usr/share/gnome-shell/extensions</code> 下的 <code>ubuntu-dock</code> </p><p><a href="https://extensions.gnome.org/extension/675/lunar-calendar/" target="_blank" rel="noopener"><strong>Lunar Calendar 农历</strong></a> 在日历中添加农历</p><p>旧版本滚动会导致插件失效,最新版本目前(2021-1-28)发布还未通过,作者在评论区发布了下载链接,可以直接将压缩包解压到 ~/.local/share/gnome-shell/extensions 路径下,注意将文件夹名改为 metadata.json 中提供的 uuid,即 <a href="mailto:[email protected]">[email protected]</a></p><p><a href="https://extensions.gnome.org/extension/3896/network-speed/" target="_blank" rel="noopener"><strong>Network Speed</strong></a> 显示实时网速</p><p><a href="https://extensions.gnome.org/extension/120/system-monitor/" target="_blank" rel="noopener"><strong>system-monitor</strong></a> 显示系统监视信息,包括内存使用量,CPU占用率,硬盘用量等</p><p><a href="https://extensions.gnome.org/extension/1031/topicons/" target="_blank" rel="noopener"><strong>TopIcons Plus</strong></a> 将旧版任务栏图标(Gnome Shell的左下方)移至顶部面板,包括wine-QQ和wine-Wechat的图表</p><h4 id="9-VMware"><a href="#9-VMware" class="headerlink" title="9. VMware"></a>9. VMware</h4><p>参考 <a href="https://zj-linux-guide.readthedocs.io/zh_CN/latest/tool-install-configure/[Ubuntu%2016.04]VMware%E5%AE%89%E8%A3%85/" target="_blank" rel="noopener">https://zj-linux-guide.readthedocs.io/zh_CN/latest/tool-install-configure/[Ubuntu%2016.04]VMware%E5%AE%89%E8%A3%85/</a></p><p>从官网下载最新安装包 <a href="https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html" target="_blank" rel="noopener">https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html</a></p><p>赋予用户权限</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo chmod a+x VMware*.bundle</span><br></pre></td></tr></table></figure><p>安装</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo ./VMware*.bundle</span><br></pre></td></tr></table></figure><p><strong>问题:第一次打开需要安装“several modules”,却“A required application is missing”</strong></p><p>解决办法一:</p><p>重启进入BIOS关闭安全启动(secure boot),执行下面的步骤</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim vm-patch.sh</span><br></pre></td></tr></table></figure><p>添加以下内容</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">VMWARE_VERSION=workstation-16.1.0</span><br><span class="line">TMP_FOLDER=/tmp/patch-vmware</span><br><span class="line">rm -fdr <span class="variable">$TMP_FOLDER</span></span><br><span class="line">mkdir -p <span class="variable">$TMP_FOLDER</span></span><br><span class="line"><span class="built_in">cd</span> <span class="variable">$TMP_FOLDER</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/mkubecek/vmware-host-modules.git</span><br><span class="line"><span class="built_in">cd</span> <span class="variable">$TMP_FOLDER</span>/vmware-host-modules</span><br><span class="line">git checkout <span class="variable">$VMWARE_VERSION</span></span><br><span class="line">git fetch</span><br><span class="line">sudo make</span><br><span class="line">sudo make install</span><br><span class="line">sudo rm /usr/lib/vmware/lib/libz.so.1/libz.so.1</span><br><span class="line">sudo ln -s /lib/x86_64-linux-gnu/libz.so.1 /usr/lib/vmware/lib/libz.so.1/libz.so.1</span><br><span class="line">sudo /etc/init.d/vmware restart</span><br></pre></td></tr></table></figure><p>执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install make</span><br><span class="line">sudo bash vm-patch.sh</span><br></pre></td></tr></table></figure><p>解决办法二:</p><p>不关闭安全模式执行上面的步骤之后,安装后仍存在问题,Virtual machine monitor启动failed,Virtual ethernet启动failed,启动虚拟机时提示Could not open /dev/-vmmon/… </p><p>其原理是安全启动模式下vmware的一些核心模块没有被写入,需要设置信任列表</p><p>第一步:生产.priv和.der文件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">openssl req -new -x509 -newkey rsa:2048 -keyout vmware.priv -outform DER -out vmware.der -nodes -days 36500 -subj <span class="string">"/CN=VMWARE/"</span></span><br></pre></td></tr></table></figure><p>第二步:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ./vmware.priv ./vmware.der $(modinfo -n vmmon)</span><br><span class="line">sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ./vmware.priv ./vmware.der $(modinfo -n vmnet)</span><br></pre></td></tr></table></figure><p>第三步:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo mokutil --import vmware.der</span><br><span class="line"><span class="comment"># 然后输入两次密码(自定义)</span></span><br></pre></td></tr></table></figure><p>重启之后会进入蓝色界面,需要你手动写入签名</p><p>选择 <code>enroll mok</code><br>选择 <code>continue</code><br>选择 <code>yes</code><br>输入之前设置的密码<br>选择 <code>reboot</code><br>测试你是否写入签名</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">mokutil --<span class="built_in">test</span>-key vmware.der</span><br><span class="line"><span class="comment"># vmware.der is already enrolled</span></span><br></pre></td></tr></table></figure><h4 id="11-Anaconda"><a href="#11-Anaconda" class="headerlink" title="11. Anaconda"></a>11. Anaconda</h4><h5 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h5><p>有时候我们需要使用不同版本的python,在系统中同时安装多个python版本会非常的麻烦,Anaconda是一款python虚拟环境管理软件,可以方便地创建和管理不同版本的python环境,也可以很方便的在不同环境之间切换。</p><p>从官网下载最新的安装脚本: <a href="https://www.anaconda.com/products/individual#Downloads" target="_blank" rel="noopener">https://www.anaconda.com/products/individual#Downloads</a></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo bash Anaconda3*.sh</span><br></pre></td></tr></table></figure><p>过程会要求阅读并同意“license agreement”,一直按回车直到结束输入“yes”。之后会要求输入安装路径,建议安装到 <code>/opt/anaconda3</code> 路径下,不要安装到 <code>/root</code> 或 <code>/home</code> 下,否则不能多用户共享虚拟环境(包括当前用户和root账户也需要分别创建不同的虚拟环境,对存储的开销非常大)。</p><p>之后便是漫长的等待,最后会询问是否初始化conda,输入yes即可。</p><p>由于刚刚是用sudo命令执行的,初始化会在 <code>/root</code> 下进行初始化,当前账户并不能使用conda</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo vim /root/.bashrc</span><br></pre></td></tr></table></figure><p>将其中</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"># >>> conda initialize >>></span><br><span class="line">...</span><br><span class="line"># <<< conda initialize <<<</span><br></pre></td></tr></table></figure><p>的部分复制,再打开自己的 .bashrc</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim ~/.bashrc</span><br></pre></td></tr></table></figure><p>将复制的内容粘贴到文件末尾,重新打开终端,即可看到前面多了(base)字样,是默认激活的base环境。</p><h5 id="设置多用户共享虚拟环境"><a href="#设置多用户共享虚拟环境" class="headerlink" title="设置多用户共享虚拟环境"></a>设置多用户共享虚拟环境</h5><p>参考:<a href="https://www.zhihu.com/question/277053071/answer/946713532" target="_blank" rel="noopener">https://www.zhihu.com/question/277053071/answer/946713532</a></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">su - <span class="comment"># 登陆到root账户</span></span><br><span class="line">groupadd anaconda <span class="comment"># 创建anaconda组</span></span><br><span class="line">adduser <username> anaconda <span class="comment"># 将需要的用户添加至anaconda组</span></span><br><span class="line">chgrp -R anaconda /opt/anaconda3 <span class="comment"># 移交目录管理权</span></span><br><span class="line">chmod 770 -R /opt/anaconda3 <span class="comment"># 设置读写权限</span></span><br><span class="line">chmod g+s /opt/anaconda3 <span class="comment"># 设置组继承</span></span><br><span class="line">chmod g+s `find /opt/anaconda3/ -<span class="built_in">type</span> d` <span class="comment"># 设置子目录组继承</span></span><br><span class="line">chmod g-w /opt/anaconda3/envs <span class="comment"># 关闭共享环境的写入权限</span></span><br><span class="line"><span class="built_in">source</span> /opt/anaconda3/bin/activate <span class="comment"># root用户下启动anaconda环境</span></span><br><span class="line">conda create -n py37 python=3.7</span><br></pre></td></tr></table></figure><p>创建共享环境这样设置之后的效果是:由root用户创建的环境会保存在/opt/anaconda/envs中,所有anaconda组成员都可以访问。用户自己创建的环境则会保存至~/.conda/envs中,但是所有下载的pkg会共享在/opt/anaconda/pkgs中,即如果是别人装过的包(比如下载缓慢的PyTorch)则不用重新下载。</p><h5 id="一些常用命令"><a href="#一些常用命令" class="headerlink" title="一些常用命令"></a>一些常用命令</h5><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">conda config --<span class="built_in">set</span> auto_activate_base <span class="literal">false</span> <span class="comment"># 设置默认不激活base环境</span></span><br><span class="line">conda create -n name python=x.x <span class="comment"># 创建python版本为x.x的名字为name的虚拟环境</span></span><br><span class="line">conda remove -n name --all <span class="comment"># 删除名字为name的环境</span></span><br><span class="line">conda activate name <span class="comment"># 激活名字为name的虚拟环境</span></span><br><span class="line">conda deactivate <span class="comment"># 推出当前虚拟环境</span></span><br><span class="line">conda list <span class="comment"># 列出当前环境安装的包</span></span><br><span class="line">conda env list <span class="comment"># 列出当前已创建的环境</span></span><br></pre></td></tr></table></figure><h4 id="11-mysql"><a href="#11-mysql" class="headerlink" title="11. mysql"></a>11. mysql</h4><p>参考:<a href="https://blog.csdn.net/liang19890820/article/details/105071479" target="_blank" rel="noopener">https://blog.csdn.net/liang19890820/article/details/105071479</a></p><h5 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h5><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装mysql-server</span></span><br><span class="line">sudo apt install mysql-server</span><br><span class="line"><span class="comment"># 运行安全脚本,过程会询问是否安装验证密码插件,用于测试密码强度,可以选择不安装,之后需要输入两次密码为root账户设置密码,之后依次询问是否删除匿名账户,是否禁止root从远程账户登陆,是否删除test数据库并取消对其访问权限,是否刷新授权表,可以根据自己的情况选择</span></span><br><span class="line">sudo mysql_secure_installation</span><br></pre></td></tr></table></figure><h5 id="修改root账户认证方式"><a href="#修改root账户认证方式" class="headerlink" title="修改root账户认证方式"></a>修改root账户认证方式</h5><p>虽然上面设置了 root 用户的密码,但当通过 MySQL 终端登录时,并不能通过密码进行认证:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mysql -u root -p</span><br><span class="line">Enter password:</span><br><span class="line">ERROR 1698 (28000): Access denied <span class="keyword">for</span> user <span class="string">'root'</span>@<span class="string">'localhost'</span></span><br></pre></td></tr></table></figure><p>这是因为在 MySQL 5.7 及之后的版本中,root 用户被默认设置为通过 auth_socket 插件(而非密码)认证,其主要原因是出于对数据库的安全性考虑。</p><p>话虽如此,但偶尔也需要外部程序来访问,这时就会很麻烦了。为了使 root 用户能通过密码方式连接 MySQL,先通过终端打开 MySQL 的提示符:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo mysql</span><br></pre></td></tr></table></figure><p>然后通过如下命令,检查 MySQL 中每个用户的认证方式:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">mysql> SELECT user, authentication_string, plugin, host FROM mysql.user;</span><br><span class="line">+------------------+-------------------------------------------+-----------------------+-----------+</span><br><span class="line">| user | authentication_string | plugin | host |</span><br><span class="line">+------------------+-------------------------------------------+-----------------------+-----------+</span><br><span class="line">| root | | auth_socket | localhost |</span><br><span class="line">| mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |</span><br><span class="line">| mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |</span><br><span class="line">| debian-sys-maint | *ABA968D18E3A0B6DEB02F9D5FBDA21415A86977B | mysql_native_password | localhost |</span><br><span class="line">+------------------+-------------------------------------------+-----------------------+-----------+</span><br><span class="line">4 rows in set (0.00 sec)</span><br></pre></td></tr></table></figure><p>显而易见,root 用户的认证方式是 auth_socket。</p><p>现在运行如下命令,将认证方式更改为密码认证(即:msql_native_password):</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';</span><br></pre></td></tr></table></figure><p>注意:务必设置一个高强度的密码(这里的“123456”仅仅是为了测试),该操作将会改变步骤 2 中设置的密码。</p><p>完成之后,再来查看一下 root 用户的认证方式:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">mysql> SELECT user, authentication_string, plugin, host FROM mysql.user;</span><br><span class="line">+------------------+-------------------------------------------+-----------------------+-----------+</span><br><span class="line">| user | authentication_string | plugin | host |</span><br><span class="line">+------------------+-------------------------------------------+-----------------------+-----------+</span><br><span class="line">| root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | mysql_native_password | localhost |</span><br><span class="line">| mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |</span><br><span class="line">| mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |</span><br><span class="line">| debian-sys-maint | *ABA968D18E3A0B6DEB02F9D5FBDA21415A86977B | mysql_native_password | localhost |</span><br><span class="line">+------------------+-------------------------------------------+-----------------------+-----------+</span><br><span class="line">4 rows in set (0.00 sec)</span><br></pre></td></tr></table></figure><p>可以看到,已经修改成功了,现在退出数据库:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql> exit</span><br></pre></td></tr></table></figure><p>再来尝试一下,让 root 用户以密码形式登录:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">mysql -u root -p</span><br><span class="line">Enter password:</span><br><span class="line">Welcome to the MySQL monitor. Commands end with ; or \g.</span><br><span class="line">Your MySQL connection id is 7</span><br><span class="line">Server version: 5.7.29-0ubuntu0.18.04.1 (Ubuntu)</span><br><span class="line"> </span><br><span class="line">Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.</span><br><span class="line"> </span><br><span class="line">Oracle is a registered trademark of Oracle Corporation and/or its</span><br><span class="line">affiliates. Other names may be trademarks of their respective</span><br><span class="line">owners.</span><br><span class="line"> </span><br><span class="line">Type <span class="string">'help;'</span> or <span class="string">'\h'</span> <span class="keyword">for</span> <span class="built_in">help</span>. Type <span class="string">'\c'</span> to clear the current input statement.</span><br><span class="line"> </span><br><span class="line">mysql></span><br></pre></td></tr></table></figure><p>可以正常连接了。</p><h5 id="创建用户"><a href="#创建用户" class="headerlink" title="创建用户"></a>创建用户</h5><p>mysql安装好了,但平时使用总不能一直用root账户,这时候就需要创建一个新的账户。</p><p>创建一个通过本地localhost连接的用户名为roc,密码为password的账户。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql> CREATE USER 'roc'@'localhost' IDENTIFIED BY 'password';</span><br></pre></td></tr></table></figure><p>给用户授权,privileges可以是 SELECT,UPDATE,DELETE,ALL 等</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql> GRANT privileges ON databasename.tablename TO 'username'@'host';</span><br></pre></td></tr></table></figure><h4 id="12-搜狗输入法"><a href="#12-搜狗输入法" class="headerlink" title="12. 搜狗输入法"></a>12. 搜狗输入法</h4><p>用了多年的搜狗输入法,也尝试过其他输入法,始终觉得还是搜狗好用。</p><p>参考:<a href="https://www.cnblogs.com/cocode/p/12875555.html" target="_blank" rel="noopener">https://www.cnblogs.com/cocode/p/12875555.html</a></p><p><strong>添加ukui的官方源</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">curl -sL <span class="string">'https://keyserver.ubuntu.com/pks/lookup?&op=get&search=0x73BC8FBCF5DE40C6ADFCFFFA9C949F2093F565FF'</span> | sudo apt-key add</span><br><span class="line">sudo apt-add-repository <span class="string">'deb http://archive.ubuntukylin.com/ukui focal main'</span></span><br><span class="line">sudo apt upgrade</span><br></pre></td></tr></table></figure><p><strong>安装</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install sogouimebs</span><br></pre></td></tr></table></figure><p><strong>设置默认输入法</strong></p><p>把默认输入法设置为fcitx,重启电脑</p><h4 id="13-Nodejs和npm"><a href="#13-Nodejs和npm" class="headerlink" title="13. Nodejs和npm"></a>13. Nodejs和npm</h4><p>想在Ubuntu上写博客不得不安装Nodejs和npm等环境,安装过程没什么可说的</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install nodejs</span><br><span class="line">sudo apt-get install npm</span><br></pre></td></tr></table></figure><h4 id="14-Seafile"><a href="#14-Seafile" class="headerlink" title="14. Seafile"></a>14. Seafile</h4><p>自建云盘的客户端</p><p>参考:<a href="https://help.seafile.com/syncing_client/install_linux_client/" target="_blank" rel="noopener">https://help.seafile.com/syncing_client/install_linux_client/</a></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">sudo wget https://linux-clients.seafile.com/seafile.asc -O /usr/share/keyrings/seafile-keyring.asc</span><br><span class="line">sudo bash -c <span class="string">"echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/seafile-keyring.asc] https://linux-clients.seafile.com/seafile-deb/focal/ stable main' > /etc/apt/sources.list.d/seafile.list"</span></span><br><span class="line">sudo apt update</span><br><span class="line">sudo apt install -y seafile-gui</span><br><span class="line"><span class="comment"># 如果仅安装命令行版本</span></span><br><span class="line">sudo apt-get install seafile-cli</span><br></pre></td></tr></table></figure><h4 id="15-Gpaste"><a href="#15-Gpaste" class="headerlink" title="15. Gpaste"></a>15. Gpaste</h4><p>用来保存剪辑版历史</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install gnome-shell-extensions-gpaste gpaste</span><br></pre></td></tr></table></figure><p><del>安装需要的软件</del>(不用这种方法安装)</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">install autoconf automake libtool autopoint gettext libglib2.0-dev build-essential libgtk-3-dev</span><br></pre></td></tr></table></figure><p><del>克隆仓库并安装</del></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/Keruspe/GPaste.git</span><br><span class="line"><span class="built_in">cd</span> Gpaste</span><br><span class="line">./autogen.sh</span><br><span class="line">./configure --sysconfdir=/etc</span><br><span class="line">make</span><br><span class="line">sudo make install</span><br><span class="line">sudo glib-compile-schemas /usr/share/glib-2.0/schemas/</span><br></pre></td></tr></table></figure><h3 id="四、美化"><a href="#四、美化" class="headerlink" title="四、美化"></a>四、美化</h3><h4 id="1-壁纸软件"><a href="#1-壁纸软件" class="headerlink" title="1. 壁纸软件"></a>1. 壁纸软件</h4><p>既然美化,没有一款更换壁纸的软件怎么能行。</p><p>本人使用 <a href="https://github.com/cheesecakeufo/komorebi" target="_blank" rel="noopener">komorebi</a></p><p>支持视频和图片,可以显示时间,功能不多,但对于我来说已经够了。</p><h4 id="2-更换主题、图标、鼠标指针"><a href="#2-更换主题、图标、鼠标指针" class="headerlink" title="2. 更换主题、图标、鼠标指针"></a>2. 更换主题、图标、鼠标指针</h4><p>安装tweaks,用于管理主题包等,还有一些其他功能这里暂时不需要</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install gnome-tweaks</span><br></pre></td></tr></table></figure><p>可以从以下网址下载自己喜欢的主题、图标、鼠标指针文件: <a href="https://www.gnome-look.org/browse/ord/rating/" target="_blank" rel="noopener">https://www.gnome-look.org/browse/ord/rating/</a></p><p>其中主题文件解压到 <code>/usr/share/themes/</code> ,图标和鼠标指针文件解压到 <code>/usr/share/icons/</code>。</p><p>解压好后在软件中搜索 tweaks(优化),在“外观”选项卡可以修改主题和图标等。</p><h4 id="3-修改登陆界面的背景"><a href="#3-修改登陆界面的背景" class="headerlink" title="3. 修改登陆界面的背景"></a>3. 修改登陆界面的背景</h4><p>参考 <a href="https://github.com/thiggy01/change-gdm-background" target="_blank" rel="noopener">https://github.com/thiggy01/change-gdm-background</a></p><p>安装依赖</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install libglib2.0-dev-bin</span><br></pre></td></tr></table></figure><p>赋予执行权限</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">chmod +x change-gdm-background</span><br></pre></td></tr></table></figure><p>修改背景</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 修改背景为某一图片</span></span><br><span class="line">sudo ./change-gdm-background /path/to/image</span><br><span class="line"><span class="comment"># 修改背景为某种颜色,使用16进制颜色</span></span><br><span class="line">sudo ./change-gdm-background \<span class="comment">#yourhexcode</span></span><br><span class="line"><span class="comment"># 恢复默认</span></span><br><span class="line">sudo ./change-gdm-background --restore</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> linux </category>
</categories>
<tags>
<tag> ubuntu </tag>
<tag> 20.04 </tag>
<tag> 安装 </tag>
</tags>
</entry>
<entry>
<title>NLP打造高质量数据集</title>
<link href="/posts/nlp1/"/>
<url>/posts/nlp1/</url>
<content type="html"><![CDATA[<h3 id="一、什么是高质量"><a href="#一、什么是高质量" class="headerlink" title="一、什么是高质量"></a>一、什么是高质量</h3><p>刚入坑的一些小伙伴可能会以为“高质量”=“超级干净”,于是为了追求“高质量”而疯狂的预处理,最后哭了╮(╯▽╰)╭。</p><p>做数据集一般有两种动机。一种是为了research,也就是为了造福广大研究人员以及推动领域的进步;</p><blockquote><p>不得不说SQuAD的发布对NLP这一波研究热潮的推动作用还是蛮大的</p></blockquote><p>另一种,就是为了使用数据驱动的方法来优化业务指标,或解决项目中实实在在存在的问题。</p><p>这两个看似不太相关的目的背后对“高质量”的定义确是非常相近的,那就是:解决问题!</p><p>只不过,对后一种目的来说,问题一般来源于线上系统</p><blockquote><p>一般来说,在做数据集之前一般已经存在一套系统了(为了让系统冷启动,一般先开发一套规则驱动的系统),系统上线后自然会产生日志,分析其中的badcase便可以知道哪些问题是现有系统搞不定的,这些问题就可以考虑使用数据驱动的方法来解决,于是需要做数据集了。而解决这些问题就是你做数据集的第一目标啦。</p></blockquote><p>而对于前一种目的来说,问题一般来源于学术界的研究现状</p><blockquote><p>现阶段的NLP研究多为数据驱动的,甚至说数据集驱动的。虽然这不是一个好现象,不过也不得不承认很大程度上推动了NLP的发展和研究热潮。当现有的数据集无法cover领域痛点,或无法发挥数学工具潜力,或已经被解决掉的时候,就需要一个新的数据集,更确切的说是新的benchmark了。</p></blockquote><p>换句话说,还有哪些问题是行业痛点问题?或可以进一步挖掘现阶段数学工具的潜力?或现有数学工具的现发展阶段还没法很好的解决该问题?这应该是做一个高质量数据集前首先要考虑的问题。</p><p>想想2015年的SNLI[1]、2016年的SQuAD[2]、2018年的GLUE[3], CoQA[4],再到如今的SuperGLUE[5], MRQA(<a href="https://mrqa.github.io),都是问题驱动的,当现有数据集不足以cover问题痛点或无法满足数学工具潜力,或上一个问题已经被解决的差不多的时候,就会有新的数据集冒出来解决下一个痛点问题。" target="_blank" rel="noopener">https://mrqa.github.io),都是问题驱动的,当现有数据集不足以cover问题痛点或无法满足数学工具潜力,或上一个问题已经被解决的差不多的时候,就会有新的数据集冒出来解决下一个痛点问题。</a></p><p>在明确要解决的问题后,数据集的质量也就保障了一半,剩下的一半就要看这个数据集怎么做啦。这里面最关键的问题是数据与标签来源的选择,以及预处理程度的把握。除此之外,迭代闭环的构建以及对复杂NLP任务的处理也会对问题解决的效率和质量产生非常重要的影响。下面开始依次介绍(~ ̄∇ ̄)-☆</p><h3 id="二、基本工具"><a href="#二、基本工具" class="headerlink" title="二、基本工具"></a>二、基本工具</h3><p>所谓工欲善其事必先利其器,只要不是太着急,在做数据集之前先掌握一些好用的工具和tricks,可以大大减少无谓的重复和低效劳动,提高迭代效率。</p><ul><li><p><strong>github</strong></p><p>写爬虫和清洗<strong>最原始</strong>数据之前先在github找一下</p></li><li><p><strong>正则表达式</strong></p><p>文本清洗利器,不解释</p></li><li><p><strong>Hadoop/Spark</strong></p><p>千万级以上的语料就别去为难你的小服务器了</p></li><li><p><strong>vim</strong></p><p>分析样本专用。数据集只有几万或一二十万的话,vim性能一般还是够用的,不过默认的vim配置是比较鸡肋和反人类的,需要事先熟悉和配置好。要是跟vim过不去,其他带正则搜索和高亮显示的性能别太差的编辑器也ok</p></li><li><p><strong>awk,grep,cut,wc等命令行工具</strong></p><p>分析样本专用。数据集大了,你的vim就罢工了,当然你要是跟这些命令过不去也可以在ipython里玩,只不过写代码效率更低,而且分析结果保存起来更麻烦一些,再就是别来open(file).readlines()这种神操作就好</p></li><li><p><strong>ipython + screen/tmux</strong></p><p>在分析一些重要的数据集统计特性如样本长度分布时,开个vim写python脚本会很低效,数据集一大的话反复IO更是让人无法忍受的。因此开个ipython把数据集或采样的一部分数据集load进内存里,再进行各种分析会高效的多。<br>另外为了避免ssh断开后从头重来,可以把ipython挂在screen或者tmux窗口里。当然啦,load进来的数据比较多时,记得时不时的del一下无用的中间结果,以免把服务器内存撑爆。哦对,记得了解一些常用的magic命令如%save,可以很方便的对复杂操作进行备份。</p></li></ul><h3 id="三、数据与标签来源"><a href="#三、数据与标签来源" class="headerlink" title="三、数据与标签来源"></a>三、数据与标签来源</h3><p>对数据集质量产生第二关键影响的就是数据和标签来源的选择了。其中数据可以通过人工构造、撰写的方式来产生,也可以从互联网上爬取或对公开数据集进行二次加工得到;标签同样可以人工标注,也可以远程监督的方式来获取。</p><p><strong>人工构造和标注</strong></p><p>最容易想到的方式就是数据和标签都来源于人工啦( ̄∇ ̄)可惜小夕并没有资金去众包平台上帮你们积累经验(。 ́︿ ̀。)对于很多相对简单的NLP任务,数据一般在互联网上总能找到合适的,但是也有一些任务的数据很难在互联网上接触到,一般情况下只能人工精心构造(比如自然语言推理,任务型对话中的大部分子任务,分词、NER、抽取等一些序列标注任务)。如果有小伙伴想系统的学习标注,小夕推荐一本之前在图书馆刷过一半的一本书,叫<strong>《Natural Language Annotation》</strong>,中文名貌似叫《自然语言标注:用于机器学习》。这本书写的挺赞的,还因此怼过一次不太会标注的PM小姐姐(//∇//)\(希望她不会看我知乎hhhh</p><p>还好对于大部分nlp任务而言,基本都能从互联网上找到合适的数据源,或在已有的公开数据集的基础上加以改造就可以产生。</p><p><strong>爬</strong></p><p>如果要自己爬,英文语料的话可以通过国外的twitter、quora、wiki、reddit等网站按需爬取甚至直接下载,官方提供的数据获取脚本满足不了需求的话可以在github上自己搜下,基本总能找到一些奇奇怪怪的第三方爬虫绕过限制(emmm怎么有种教别人犯罪的感觉)。如果目标数据是中文,当然国内也会有微博、贴吧、豆瓣、百度百科、知乎等网站坐等被爬啦。</p><p>当然啦,Twitter、微博、贴吧这类网站的缺点就是灌水内容太多,爬完记得去github找相应的预处理脚本瘦瘦身。注意别用那些太过浮夸的脚本,处理的太干净可能会有问题,后面会讲原因噢~</p><p><strong>改</strong></p><p>讲真,自己爬数据真是dirty work超级超级多,尤其是你要爬的数据量灰常大或者去爬一些不那么主流的网站的时候!所以小夕更加推荐的还是先从现有的数据集想办法啦,拿来现成的然后一顿改改改绝对可以省不少力!</p><p>其实很多数据集都是这样“偷懒”做成的,比如早期Socher把只有1万样本的情感分类数据集MR[16]用parser将MR里的句子给分解为短语、子句等,再分别标注,于是就变成了20多万样本量、多粒度的SST[17]╮( ̄▽ ̄””)╭最近也恰好刷到一篇做文本风格控制的paper[18],同样也是用了parser,将Yelp情感分类数据集[19]拆解后疯狂加工,变成了结构->文本的风格化文本生成数据集(parser真是个造数据集的好东西)。总之,玩过一次就知道,改比爬方便多啦╮(╯▽╰)╭</p><p><strong>远程监督</strong></p><p>在打标签方面,最容易想到的当然还是花钱众包,不用说了,下一个方法。</p><p>更加经济可用的方法就是远程监督了,这方面的可玩性就非常大啦,脑洞有多大,标注质量就会有多高!</p><p>做好远程监督的前提就是提一个靠谱的假设,比如“给定一个query-answer pair,如果answer string在搜索引擎召回的某document出现,那么该document可以回答该query”,于是有了机器阅读理解数据集TriviaQA[6]、searchQA[7];再比如“一条Twitter中包含的emoji可以反映这条Twitter的(细粒度)情感”,于是有了情感分类数据集TwitterSentiment[8]和情感可控对话生成数据集Mojitalk[9]。</p><p>如果不放心的话,自己采样一些样本,粗略统计一下你提出的假设成立的样本占比,只要大部分情况下成立就是有希望的,而后再对假设增加一些细节性的约束(比如TriviaQA里的answer必须在doc中高频出现;mojitalk里的带多媒体信息的Twitter直接丢掉,多emoji时只看最高频的emoji等),在一个靠谱的假设下,经过几番小迭代往往就可以一个能用的数据集啦。</p><p>总之,玩好远程监督也就是要掌握逆向思维,忘掉“标注”这个词,把思维改成“<strong>握着标签找数据“</strong>。</p><p>好啦,先休息五秒,你懂滴(↓ ̄∇ ̄)↓</p><h3 id="四、适可而止的预处理"><a href="#四、适可而止的预处理" class="headerlink" title="四、适可而止的预处理"></a>四、适可而止的预处理</h3><p>其实在做数据集这个事情上,有“洁癖”并不是一件好事,尤其是当语料的lexical diversity & semantic richness比较强的时候,一条看似让数据集更干净的正则表达式很可能</p><ol><li>沙雕了一些跟类别标签相关的有效模式,导致一些本来成立的X->Y的映射关系因此消失了</li><li>减少了模型对抗噪声的学习机会,<strong>你无法消除所有噪声,但是却消除了很多模型识别噪声适应噪声的学习机会</strong></li></ol><p>这方面小夕一把辛酸泪呀,曾经花了半下午时间写了几十条清洗规则,结果model更难收敛以及开发集表现更差了。最终发现数据量和模型都不是太小的情况下,遵从最少预处理原则一般就够了,除了一些常规操作(比如滤掉HTML标签、URL、脱敏、去重、截断等),小夕一般只对如下情况进行处理:</p><ol><li>导致了“标签泄漏”,这种情况容易发生在任务简单、标签典型的场合,数据源比较多时尤其容易踩坑。比如你任务的目标是让模型通过文本语义判断情感,那就不要对emoji、颜文字手下留情了,严格控制它们在数据集中的比例。</li><li>导致了样本过长,比如连续100个相同的emoji、哈、啊等</li><li>样本中出现了预留的功能词(比如BERT中的[UNK],[PAD],[CLS],[SEP]之类的)</li></ol><p>当然,如果你的数据集是生成任务相关,记得滤掉黄反内容=,=。对于一些高频错别字,一堆点点点之类的让你觉得dirty的东西,没特殊需求的话就放过它们吧。。。(真想彻底消除它们的话就换数据源啊喂,不要妄想以一人之力对抗广大人民群众产生的辣鸡!!)</p><h3 id="五、验证可用性,尽早构造数据集迭代闭环"><a href="#五、验证可用性,尽早构造数据集迭代闭环" class="headerlink" title="五、验证可用性,尽早构造数据集迭代闭环"></a>五、验证可用性,尽早构造数据集迭代闭环</h3><p>无论是人工标注的还是远程监督标注的,数据集看起来做好了不代表就是可用的,如果标注的噪声太大或者标签边界太过模糊(大量标注错误,或标注规则写的太松、太模糊,导致人都分不清某几个类别之间的区别),很可能再复杂的模型都在这份数据集上无法收敛;反之,如果数据集中有“标签泄漏”(比如你用emoji远程监督构造了情感分类数据集,最后却忘了滤掉emoji)或标签与内容有非常直接的映射关系(类别太过具体或标注规则写的太死),那就会导致一个非常简单的模型都会轻易的把这个数据集刷到近乎满分,那这个模型学到的知识基本是没有什么实际意义的,换言之,这么简单直接的任务其实几条规则几行代码就搞定了,完全没必要做数据驱动的模型训练。</p><p>因此绝对不要抱着将数据集一次做成的心态,而是要尽早构造一个<strong>“生成数据集->跑baseline->badcase study->更新策略->重新生成数据集”</strong>的闭环。注意,baseline别选的太麻烦(那种对各种超参敏感的模型还是算了吧),最好是已被普遍验证有效的、有开源代码的、上手轻松的、基本不用调参就效果还可以的模型(比如BERT系列)。</p><p>这里要注意侧重点,在迭代的早期,让baseline能在你的数据集上正常收敛是第一目标,中期则是关注baseline在开发集上的表现,表现太好要留意标签泄漏或数据泄漏(X中出现了Y,或忘记去重),表现太差调调参,后期则是更多关注badcase了,看看badcase中更多的是样本问题(标注噪声)还是真的模型能力不够。</p><h3 id="六、关于复杂NLP任务"><a href="#六、关于复杂NLP任务" class="headerlink" title="六、关于复杂NLP任务"></a>六、关于复杂NLP任务</h3><p>当然啦,上面其实都说的比较宽泛,其实在不同的NLP问题上做数据集可能会很不一样。像一些简单NLP任务如文本分类等基于上面的基本原则就差不多了,但是一些复杂NLP任务如任务型对话、知识图谱相关,哪怕完全人工产生和标注都不好做的。</p><p>比如任务型对话相关的数据集,很难使用远程监督这种偷懒的方式来构造,样本和标签的产生可能都很难脱离人力标注。有兴趣的小伙伴可以参考MultiWOZ[10]这个数据集(cover了DST、act-to-text generation和context-to-text generation这三个任务型对话中的子任务)的paper,里面对machine-machine(如M2M[11])、machine-human(如DSTC系列[12][13][14])、human-human(如ATIS[15],WOZ系列[10])这三种协同构造任务型对话数据集的方式总结的很到位,会让你感受到产出一个高质量的任务完成型对话数据集是一个很有挑战的工作,自己从头摸索的话可能到头来只会收获一脸懵逼╮( ̄▽ ̄””)╭</p><p>所以面对一些比较复杂的NLP任务的时候,一定一定要记得先精读一下最新最权威的数据集的paper,这类数据集的构建经验可能整个微信和知乎也找不到几篇的噢╮(╯▽╰)╭</p><hr><h3 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h3><p>[1] Bowman S R, Angeli G, Potts C, et al. A large annotated corpus for learning natural language inference[J]. arXiv preprint arXiv:1508.05326, 2015.</p><p>[2] Rajpurkar P, Zhang J, Lopyrev K, et al. Squad: 100,000+ questions for machine comprehension of text[J]. arXiv preprint arXiv:1606.05250, 2016.<br>[3] Wang A, Singh A, Michael J, et al. Glue: A multi-task benchmark and analysis platform for natural language understanding[J]. arXiv preprint arXiv:1804.07461, 2018.<br>[4] Reddy S, Chen D, Manning C D. Coqa: A conversational question answering challenge[J]. Transactions of the Association for Computational Linguistics, 2019, 7: 249-266.<br>[5] Wang A, Pruksachatkun Y, Nangia N, et al. Superglue: A stickier benchmark for general-purpose language understanding systems[J]. arXiv preprint arXiv:1905.00537, 2019.<br>[6] Joshi M, Choi E, Weld D S, et al. Triviaqa: A large scale distantly supervised challenge dataset for reading comprehension[J]. arXiv preprint arXiv:1705.03551, 2017.<br>[7] Dunn M, Sagun L, Higgins M, et al. Searchqa: A new q&a dataset augmented with context from a search engine[J]. arXiv preprint arXiv:1704.05179, 2017.<br>[8] Go A, Bhayani R, Huang L. Twitter sentiment classification using distant supervision[J]. CS224N Project Report, Stanford, 2009, 1(12): 2009.<br>[9] Zhou X, Wang W Y. Mojitalk: Generating emotional responses at scale[J]. arXiv preprint arXiv:1711.04090, 2017.<br>[10] Budzianowski P, Wen T H, Tseng B H, et al. Multiwoz-a large-scale multi-domain wizard-of-oz dataset for task-oriented dialogue modelling[J]. arXiv preprint arXiv:1810.00278, 2018.<br>[11] P Shah, D Hakkani-Tur, G Tur, A Rastogi, A Bapna, N Nayak, and L Heck. 2018. Building a conversational agent overnight with dialogue self-play. arXiv preprint arXiv:1801.04871.<br>[12] Jason Williams, Antoine Raux, Deepak Ramachan- dran, and Alan Black. 2013. The dialog state track- ing challenge. In Proceedings of the SIGDIAL 2013 Conference, pages 404–413.<br>[13] M. Henderson, B. Thomson, and S. J. Young. 2014b. Word-based Dialog State Tracking with Recurrent Neural Networks. In Proceedings of SIGdial.<br>[14] Matthew Henderson, Blaise Thomson, and Jason D Williams. 2014c. The third dialog state tracking challenge. In Spoken Language Technology Work- shop (SLT), 2014 IEEE, pages 324–329. IEEE.<br>[15] Charles T Hemphill, John J Godfrey, and George R Doddington. 1990. The atis spoken language sys- tems pilot corpus. In Speech and Natural Language: Proceedings of a Workshop Held at Hidden Valley, Pennsylvania<br>[16] B. Pang, L. Lee. 2005. Seeing stars: Exploiting class relationships for sentiment categorization with re- spect to rating scales. In Proceedings of ACL 2005.<br>[17] R. Socher, A. Perelygin, J. Wu, J. Chuang, C. Manning, A. Ng, C. Potts. 2013. Recursive Deep Models for Semantic Compositionality Over a Sentiment Tree- bank. In Proceedings of EMNLP 2013.<br>[18] Oraby S, Harrison V, Ebrahimi A, et al. Curate and Generate: A Corpus and Method for Joint Control of Semantics and Style in Neural NLG[J]. arXiv preprint arXiv:1906.01334, 2019.<br>[19] Zhang X, Zhao J, LeCun Y. Character-level convolutional networks for text classification[C]//Advances in neural information processing systems. 2015: 649-657.</p><hr><h3 id="转载自"><a href="#转载自" class="headerlink" title="转载自"></a>转载自</h3><p><a href="https://www.jiqizhixin.com/articles/2019-09-03-4" target="_blank" rel="noopener">机器之心:如何打造高质量的NLP数据集</a></p>]]></content>
<categories>
<category> NLP </category>
<category> 数据处理策略 </category>
</categories>
<tags>
<tag> NLP </tag>
<tag> 数据处理策略 </tag>
</tags>
</entry>
<entry>
<title>朴素贝叶斯与文本分类</title>
<link href="/posts/bayes/"/>
<url>/posts/bayes/</url>
<content type="html"><![CDATA[<h3 id="一、了解文本分类"><a href="#一、了解文本分类" class="headerlink" title="一、了解文本分类"></a>一、了解文本分类</h3><p>文本分类用电脑对文本集(或其他实体或物件)按照一定的分类体系或标准进行自动分类标记。 它根据一个已经被标注的训练文档集合, 找到文档特征和文档类别之间的关系模型, 然后利用这种学习得到的关系模型对新的文档进行类别判断 。文本分类从基于知识的方法逐渐转变为基于统计 和机器学习的方法。</p><p>一般分为以下几个步骤:</p><p>(1) 预处理:将原始语料格式化为同一格式,便于后续的统一处理;</p><p>(2) 索引:将文档分解为基本处理单元,同时降低后续处理的开销;</p><p>(3) 统计:词频统计,项(单词、概念)与分类的相关概率;</p><p>(4) 特征抽取:从文档中抽取出反映文档主题的特征;</p><p>(5)分类器:分类器的训练;</p><p>(6) 评价:分类器的测试结果分析。</p><h3 id="二、朴素贝叶斯分类算法"><a href="#二、朴素贝叶斯分类算法" class="headerlink" title="二、朴素贝叶斯分类算法"></a>二、朴素贝叶斯分类算法</h3><h4 id="1-贝叶斯公式:"><a href="#1-贝叶斯公式:" class="headerlink" title="1. 贝叶斯公式:"></a>1. 贝叶斯公式:</h4><p>根据先验概率和似然来计算后验概率</p><p>$$P ( c ∣ X ) = \frac{P(X|c)P(c)}{P(X)}$$</p><p>利用了古典的数学理论,通过贝叶斯公式,由先验概率计算出后验概率,即是该假设属于某一类别的概率,然后选择后验概率最大的类作为该假设的目标值。</p><h4 id="2-贝叶斯分类器"><a href="#2-贝叶斯分类器" class="headerlink" title="2. 贝叶斯分类器"></a>2. 贝叶斯分类器</h4><p>分类是机器学习和数据挖掘中最基础的一种工作。假设现在我们有一组训练样本,以及与其相对应的分类标签。每个元组都被表示为n维属性向量 $x=(x_1,x_1,…,x_n)$ 的形式,一共有k个类别 $c_1,c_2,…,c_k$。分类要做的就是模型可以预测数据属于哪个类别。<br>对于每个类别 $c_i$ ,利用贝叶斯公式来估计在给定训练元组X时的条件概率 $P(c_i|x)$</p><p>$$P(c_i|x)=\frac{P(c_i)P(x|c_i)}{P(x)}$$</p><p>当且仅当概率 $P(c_i|x)$ 在所有类别中取值最大时,数据 $x$ 属于 $c_i$ 。 $P(c_i)$ 是类先验概率,$P(x|c_i)$ 是样本 $x$ 相对于类 $c_i$ 的类条件概率,称为似然。因为 $P(x)$ 是用于归一化的证据因子,其对于所有的类别都是恒定的。所以只需要基于训练数据来估计 $P(c_i)$ 和 $P(x|c_i)$ </p><h4 id="3-朴素贝叶斯算法的优缺点"><a href="#3-朴素贝叶斯算法的优缺点" class="headerlink" title="3. 朴素贝叶斯算法的优缺点"></a>3. 朴素贝叶斯算法的优缺点</h4><ul><li><p>优点</p><blockquote><ol><li>对待预测样本进行预测,<strong>过程简单速度快</strong>(想想邮件分类的问题,预测就是分词后进行概率乘积,在log域直接做加法更快)。</li><li><strong>对于多分类问题也同样很有效</strong>,复杂度也不会有大程度上升。</li><li><strong>在分布独立这个假设成立的情况下</strong>,贝叶斯分类器<strong>效果奇好</strong>,会略胜于逻辑回归,同时我们<strong>需要的样本量也更少一点</strong>。</li><li>对于类别类的输入特征变量,效果非常好。对于数值型变量特征,我们是默认它符合正态分布的。</li></ol></blockquote></li><li><p>缺点</p><blockquote><ol><li>对于测试集中的一个类别变量特征,如果在训练集里没见过,直接算的话概率就是0了,预测功能就失效了。当然,我们前面的文章提过我们有一种技术叫做<strong>『平滑』操作</strong>,可以缓解这个问题,最常见的平滑技术是拉普拉斯估测。</li><li>朴素贝叶斯算出的概率结果,比较大小还凑合,但实际物理含义就别太当真了。</li></ol></blockquote></li></ul><p>此外, $P(d| Ci)$ 之所以能展开成的连乘积形式</p><p>$P(d| Ci)=P(w1|Ci) P(w2|Ci) …P(wi|Ci) P(w1|Ci) …P(wm|Ci) $</p><p>就是假设一篇文章中的各个词之间是彼此独立的,其中一个词的出现丝毫不受另一个词的影响(回忆一下概率论中变 量彼此独立的概念就可以知道),但这显然不对,即使不是语言学专家的我们也知道,词语之间有明显的所谓“共现”关系,在不同主题的文章中,可能共现的次数 或频率有变化,但彼此间绝对谈不上独立。</p><p>其二,使用某个词在某个类别训练文档中出现的次数来估计 $P(wi|Ci)$ 时,只在训练样本数量非常多的情况下才比较准确(考虑扔硬币的问题,得通过大量观 察才能基本得出正反面出现的概率都是二分之一的结论,观察次数太少时很可能得到错误的答案),而需要大量样本的要求不仅给前期人工分类的工作带来更高要求 (从而成本上升),在后期由计算机处理的时候也对存储和计算资源提出了更高的要求。</p><h3 id="三、用python实现一种简单的朴素贝叶斯算法(以垃圾邮件识别为例)"><a href="#三、用python实现一种简单的朴素贝叶斯算法(以垃圾邮件识别为例)" class="headerlink" title="三、用python实现一种简单的朴素贝叶斯算法(以垃圾邮件识别为例)"></a>三、用python实现一种简单的朴素贝叶斯算法(以垃圾邮件识别为例)</h3><p><code>SpamEmail.py</code> :</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="string">Created on 2020-11-1</span></span><br><span class="line"><span class="string">@author: Roc</span></span><br><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="keyword">import</span> jieba</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SpamEmail</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line"> self.stopWords = []</span><br><span class="line"> self.getStopWords(<span class="string">"./data/中文停用词表.txt"</span>) <span class="comment"># 停用词</span></span><br><span class="line"> self.normDict, self.normFileNum = self.getWords(<span class="string">"./data/normal/"</span>) <span class="comment"># 记录正常邮件词频</span></span><br><span class="line"> self.spamDict, self.spamFileNum = self.getWords(<span class="string">"./data/spam/"</span>) <span class="comment"># 记录垃圾邮件词频</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">getStopWords</span><span class="params">(self, path)</span>:</span></span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> open(path):</span><br><span class="line"> self.stopWords.append(line[:len(line)<span class="number">-1</span>])</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">getWordsList</span><span class="params">(self, content, wordsList)</span>:</span></span><br><span class="line"> cutRes = list(jieba.cut(content))</span><br><span class="line"> <span class="keyword">for</span> w <span class="keyword">in</span> cutRes:</span><br><span class="line"> <span class="keyword">if</span> w <span class="keyword">not</span> <span class="keyword">in</span> self.stopWords <span class="keyword">and</span> w.strip() != <span class="string">''</span> <span class="keyword">and</span> w != <span class="literal">None</span> <span class="keyword">and</span> w <span class="keyword">not</span> <span class="keyword">in</span> wordsList:</span><br><span class="line"> wordsList.append(w)</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">getWords</span><span class="params">(self, path)</span>:</span></span><br><span class="line"> wordsDic = {}</span><br><span class="line"> fileList = os.listdir(path)</span><br><span class="line"> num = len(fileList)</span><br><span class="line"> <span class="keyword">for</span> fileName <span class="keyword">in</span> fileList:</span><br><span class="line"> wordsList = []</span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> open(path + fileName):</span><br><span class="line"> rule = re.compile(<span class="string">r"[^\u4e00-\u9fa5]"</span>)</span><br><span class="line"> line = rule.sub(<span class="string">""</span>, line)</span><br><span class="line"> self.getWordsList(line, wordsList)</span><br><span class="line"> <span class="keyword">for</span> item <span class="keyword">in</span> wordsList:</span><br><span class="line"> <span class="keyword">if</span> item <span class="keyword">in</span> wordsDic.keys():</span><br><span class="line"> wordsDic[item] += <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> wordsDic.setdefault(item, <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">return</span> wordsDic, num</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">getTestWords</span><span class="params">(self, wordsDic)</span>:</span></span><br><span class="line"> wordsProbDic = {}</span><br><span class="line"> <span class="keyword">for</span> word, num <span class="keyword">in</span> wordsDic.items():</span><br><span class="line"> <span class="keyword">if</span> word <span class="keyword">in</span> self.spamDict.keys() <span class="keyword">and</span> word <span class="keyword">in</span> self.normDict.keys():</span><br><span class="line"> pw_s = self.spamDict[word]/self.spamFileNum</span><br><span class="line"> pw_n = self.normDict[word]/self.normFileNum</span><br><span class="line"> <span class="keyword">elif</span> word <span class="keyword">in</span> self.spamDict.keys() <span class="keyword">and</span> word <span class="keyword">not</span> <span class="keyword">in</span> self.normDict.keys():</span><br><span class="line"> pw_s = self.spamDict[word]/self.spamFileNum</span><br><span class="line"> pw_n = <span class="number">0.0001</span> <span class="comment"># 不在正常邮件词中</span></span><br><span class="line"> <span class="keyword">elif</span> word <span class="keyword">not</span> <span class="keyword">in</span> self.spamDict.keys() <span class="keyword">and</span> word <span class="keyword">in</span> self.normDict.keys():</span><br><span class="line"> pw_s = <span class="number">0.0001</span> <span class="comment"># 不在垃圾邮件词中</span></span><br><span class="line"> pw_n = self.normDict[word]/self.normFileNum</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="comment"># 二者都不在,设置默认可能性,根据最新(2020-06)全球垃圾邮件比例设置</span></span><br><span class="line"> pw_s = <span class="number">0.4816</span></span><br><span class="line"> pw_n = <span class="number">0.5184</span></span><br><span class="line"> ps_w = pw_s / (pw_s + pw_n) <span class="comment"># 计算 P(s|w)</span></span><br><span class="line"> wordsProbDic.setdefault(word, ps_w)</span><br><span class="line"> <span class="comment"># res = {}</span></span><br><span class="line"> <span class="comment"># for w in sorted(wordsProbDic.items(), key=lambda d: d[1], reverse=True)[0:15]:</span></span><br><span class="line"> <span class="comment"># res.setdefault(w[0], w[1])</span></span><br><span class="line"> <span class="keyword">return</span> wordsProbDic</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">calBayes</span><span class="params">(self, wordsProbDic)</span>:</span></span><br><span class="line"> ps_w = <span class="number">1</span></span><br><span class="line"> pn_w = <span class="number">1</span></span><br><span class="line"> <span class="keyword">for</span> word, prob <span class="keyword">in</span> wordsProbDic.items():</span><br><span class="line"> ps_w *= prob</span><br><span class="line"> pn_w *= (<span class="number">1</span> - prob)</span><br><span class="line"> p = ps_w / (ps_w + pn_w)</span><br><span class="line"> <span class="keyword">return</span> p</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">judgeSpam</span><span class="params">(self, filename)</span>:</span></span><br><span class="line"> wordsDic = {}</span><br><span class="line"> wordsList = []</span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> open(filename):</span><br><span class="line"> rule = re.compile(<span class="string">r"[^\u4e00-\u9fa5]"</span>)</span><br><span class="line"> line = rule.sub(<span class="string">""</span>, line)</span><br><span class="line"> self.getWordsList(line, wordsList)</span><br><span class="line"> <span class="keyword">for</span> item <span class="keyword">in</span> wordsList:</span><br><span class="line"> <span class="keyword">if</span> item <span class="keyword">in</span> wordsDic.keys():</span><br><span class="line"> wordsDic[item] += <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> wordsDic.setdefault(item, <span class="number">1</span>)</span><br><span class="line"> wordsProbDic = self.getTestWords(wordsDic)</span><br><span class="line"> p = self.calBayes(wordsProbDic)</span><br><span class="line"> <span class="keyword">return</span> p > <span class="number">0.9</span></span><br></pre></td></tr></table></figure><p><code>main.py</code> :</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="string">Created on 2020-11-1</span></span><br><span class="line"><span class="string">@author: Roc</span></span><br><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="keyword">import</span> SpamEmail</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line">spam = SpamEmail.SpamEmail()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">calAccuracy</span><span class="params">(testDic)</span>:</span></span><br><span class="line"> normCount = <span class="number">0</span></span><br><span class="line"> spamCount = <span class="number">0</span></span><br><span class="line"> rightCount = <span class="number">0</span></span><br><span class="line"> FNCount = <span class="number">0</span> <span class="comment"># 假阴性,垃圾邮件漏报</span></span><br><span class="line"> FPCount = <span class="number">0</span> <span class="comment"># 假阳性,正常邮件误报,一般情况下要求假阳性率应该低一点</span></span><br><span class="line"> <span class="keyword">for</span> file, isSpam <span class="keyword">in</span> testDic.items():</span><br><span class="line"> <span class="keyword">if</span> int(file) > <span class="number">1000</span>:</span><br><span class="line"> spamCount += <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> isSpam:</span><br><span class="line"> rightCount += <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> FNCount += <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> normCount += <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> isSpam:</span><br><span class="line"> FPCount += <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> rightCount += <span class="number">1</span></span><br><span class="line"> acc = rightCount / (rightCount + FNCount + FPCount)</span><br><span class="line"> PFN = FNCount / spamCount</span><br><span class="line"> PFP = FPCount / normCount</span><br><span class="line"> <span class="keyword">return</span> acc, PFN, PFP</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line"> testFileList = os.listdir(<span class="string">"./data/test"</span>)</span><br><span class="line"> testDic = {}</span><br><span class="line"> <span class="keyword">for</span> file <span class="keyword">in</span> testFileList:</span><br><span class="line"> isSpam = spam.judgeSpam(<span class="string">"./data/test/"</span> + file)</span><br><span class="line"> testDic.setdefault(file, isSpam)</span><br><span class="line"> print(file, isSpam)</span><br><span class="line"> acc, PFN, PFP = calAccuracy(testDic)</span><br><span class="line"> print(<span class="string">"The correct rate:"</span>, acc)</span><br><span class="line"> print(<span class="string">"The False Negative rate:"</span>, PFN)</span><br><span class="line"> print(<span class="string">"The False Positive rete:"</span>, PFP)</span><br></pre></td></tr></table></figure><p>运行结果可以看到正确率可以达到98.97%(由于测试数据较少,这个正确率置信度不高,仅供参考),但假阳性的概率达到1.04%,效果不是很好。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">The correct rate: 0.9897959183673469</span><br><span class="line">The False Negative rate: 0.010050251256281407</span><br><span class="line">The False Positive rete: 0.010362694300518135</span><br></pre></td></tr></table></figure><p>数据集下载:<a href="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/bayes/data.zip" target="_blank" rel="noopener">https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/bayes/data.zip</a></p><p>测试数据中,文件名小于1000的是正常邮件,大于1000的是垃圾邮件。</p><h3 id="四、注意事项和一些小技巧"><a href="#四、注意事项和一些小技巧" class="headerlink" title="四、注意事项和一些小技巧"></a>四、注意事项和一些小技巧</h3><h4 id="注意事项:"><a href="#注意事项:" class="headerlink" title="注意事项:"></a>注意事项:</h4><ul><li>虽然很多特征是连续数值型的,但是它们不一定服从正态分布,要想办法把它们变换调整成满足正态分布!!</li><li>对测试数据中的0频次项,<strong>一定要记得平滑</strong>,简单一点可以用『拉普拉斯平滑』。</li><li>先处理处理特征,<strong>把相关特征去掉</strong>,因为高相关度的2个特征在模型中相当于发挥了2次作用。</li><li>朴素贝叶斯分类器一般可调参数比较少,比如<a href="http://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.MultinomialNB.html#sklearn.naive_bayes.MultinomialNB" target="_blank" rel="noopener">scikit-learn中的朴素贝叶斯</a>只有拉普拉斯平滑因子alpha,类别先验概率class_prior和预算数据类别先验fit_prior。模型端可做的事情不如其他模型多,因此我们还是集中精力进行数据的预处理,以及特征的选择吧。</li><li>那个,一般其他的模型(像logistic regression,SVM等)做完之后,我们都可以尝试一下bagging和boosting等融合增强方法。咳咳,很可惜,对朴素贝叶斯里这些方法都没啥用。原因?原因是这些融合方法本质上是减少过拟合,减少variance的。朴素贝叶斯是没有variance可以减小。</li></ul><h4 id="一些小技巧:"><a href="#一些小技巧:" class="headerlink" title="一些小技巧:"></a>一些小技巧:</h4><h5 id="1-对于概率为0的数据的处理"><a href="#1-对于概率为0的数据的处理" class="headerlink" title="1. 对于概率为0的数据的处理"></a>1. 对于概率为0的数据的处理</h5><p>当特征属性为离散值时,只要统计训练样本中各个划分在每个类别中出现的频率即可用来估计 $P(w|s)$ ,若某一特征值的概率为0则会使整个概率乘积变为0,这会让分类器的准确性大幅下降。</p><p>这时候使用Laplace校准:即假定训练数据库很大,以至于对每个计数加1造成的估计概率的变化忽略不计。</p><h5 id="2-小数连续相乘"><a href="#2-小数连续相乘" class="headerlink" title="2. 小数连续相乘"></a>2. 小数连续相乘</h5><p>实际项目中,概率P往往是值很小的小数,连续的微小小数相乘容易造成下溢出使乘积为0或者得不到正确答案。一种解决办法就是对乘积取自然对数,将连乘变为连加, $ln(AB)=lnA+lnB$ 。采用自然对数处理几乎不会带来任何损失,可以避免下溢出或者浮点数舍入导致的错误。</p><hr><p>参考资料:</p><p>[1]百度百科-文本分类:<a href="https://baike.baidu.com/item/%E6%96%87%E6%9C%AC%E5%88%86%E7%B1%BB" target="_blank" rel="noopener">https://baike.baidu.com/item/%E6%96%87%E6%9C%AC%E5%88%86%E7%B1%BB</a></p><p>[2]知乎-带你理解朴素贝叶斯分类算法:<a href="https://zhuanlan.zhihu.com/p/26262151" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/26262151</a></p><p>[3]CSDN-朴素贝叶斯分类器及python实现:<a href="https://blog.csdn.net/yinyu19950811/article/details/78060267" target="_blank" rel="noopener">https://blog.csdn.net/yinyu19950811/article/details/78060267</a></p><p>[4]CSDN-用朴素贝叶斯进行文本分类(上):<a href="https://blog.csdn.net/suibianshen2012/article/details/51613759" target="_blank" rel="noopener">https://blog.csdn.net/suibianshen2012/article/details/51613759</a></p><p>[5]GitHub-BayesSpam:<a href="https://github.com/shijing888/BayesSpam" target="_blank" rel="noopener">https://github.com/shijing888/BayesSpam</a></p><p>[6]CSDN-NLP系列(4)_朴素贝叶斯实战与进阶:<a href="https://blog.csdn.net/longxinchen_ml/article/details/50629613" target="_blank" rel="noopener">https://blog.csdn.net/longxinchen_ml/article/details/50629613</a></p>]]></content>
<categories>
<category> NLP </category>
<category> 二分类 </category>
</categories>
<tags>
<tag> NLP </tag>
<tag> 朴素贝叶斯 </tag>
<tag> 文本分类 </tag>
</tags>
</entry>
<entry>
<title>Vmware安装Linux虚拟机</title>
<link href="/posts/vmware/"/>
<url>/posts/vmware/</url>
<content type="html"><![CDATA[<h3 id="一、下载相关文件"><a href="#一、下载相关文件" class="headerlink" title="一、下载相关文件"></a>一、下载相关文件</h3><h4 id="1-下载Vmware并安装"><a href="#1-下载Vmware并安装" class="headerlink" title="1. 下载Vmware并安装"></a>1. 下载Vmware并安装</h4><p>建议到VMware官网下载,虽然可能有点慢。</p><p>地址 <a href="https://download3.vmware.com/software/wkst/file/VMware-workstation-full-16.0.0-16894299.exe" target="_blank" rel="noopener">https://download3.vmware.com/software/wkst/file/VMware-workstation-full-16.0.0-16894299.exe</a></p><p>注册码(<a href="https://www.iemblog.com/?p=7283&lang=zh" target="_blank" rel="noopener">网上</a>找来的,不保证可以用):</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ZF3R0-FHED2-M80TY-8QYGC-NPKYF</span><br><span class="line">YF390-0HF8P-M81RQ-2DXQE-M2UT6</span><br><span class="line">ZF71R-DMX85-08DQY-8YMNC-PPHV8</span><br></pre></td></tr></table></figure><h4 id="2-下载Linux镜像"><a href="#2-下载Linux镜像" class="headerlink" title="2. 下载Linux镜像"></a>2. 下载Linux镜像</h4><p>选择自己比较习惯的Linux发行版的镜像下载,新手推荐Ubuntu,下载地址:<a href="https://releases.ubuntu.com/20.04/ubuntu-20.04.3-desktop-amd64.iso" target="_blank" rel="noopener">https://releases.ubuntu.com/20.04/ubuntu-20.04.3-desktop-amd64.iso</a></p><h3 id="三、安装Linux(以Ubuntu为例)"><a href="#三、安装Linux(以Ubuntu为例)" class="headerlink" title="三、安装Linux(以Ubuntu为例)"></a>三、安装Linux(以Ubuntu为例)</h3><p>对于VMware里面的一些选项,不懂的可以查阅VMware<a href="https://docs.vmware.com/cn/VMware-Workstation-Pro/index.html" target="_blank" rel="noopener">官方文档</a></p><h4 id="准备阶段"><a href="#准备阶段" class="headerlink" title="准备阶段"></a>准备阶段</h4><p>打开VMware,点击创建新的虚拟机,选择自定义类型,点击两次下一步。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/new.jpg" alt=""></p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/zidingyi.jpg" alt=""></p><p>选择”稍后安装操作系统”,点击下一步。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/after.jpg" alt=""></p><p>选择Linux操作系统,版本为Ubuntu64位,点击下一步。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/select_sys.jpg" alt=""></p><p>虚拟机名称可以随意,位置最好专门放在一个文件夹,<strong>不要</strong>放在默认位置,且<strong>尽量不要</strong>放在系统盘。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/where.jpg" alt=""></p><p>选择处理器数量与内核数量,一般我们的电脑也只有一个处理器,这里选择1个处理器,4个核心。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/cpu.jpg" alt=""></p><p>分配内存大小,建议2G或4G。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/ram.jpg" alt=""></p><p>选择网络,默认就可以,这个以后可以切换,如果用着用着虚拟机上不了网了,可以试试切换网络模式。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/net.jpg" alt=""></p><p>选择I/O类型和磁盘类型,默认就可以。如果有其他需求,可以看官方给的<a href="https://docs.vmware.com/cn/VMware-Workstation-Pro/16.0/com.vmware.ws.using.doc/GUID-A0438F6C-6651-4A38-853A-0A7A494E23DF.html" target="_blank" rel="noopener">文档</a>选择合适的I/O类型和磁盘类型。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/IO.jpg" alt=""></p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/disk.jpg" alt=""></p><p>选择磁盘,创建新的虚拟磁盘。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/create_disk.jpg" alt=""></p><p>输入给虚拟机分配的磁盘大小,如果打算长期用,建议稍大一点,免得以后麻烦。</p><p>这里选择将虚拟磁盘拆分成多个文件。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/storage.jpg" alt=""></p><p>点击两次下一步,完成。会自动打开当前虚拟机的页面,点击左侧CD/DVD,修改为下载好的镜像文件。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/CDDVD.jpg" alt=""></p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/select_iso.jpg" alt=""></p><p>点击确定,然后“开启此虚拟机”。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/start.jpg" alt=""></p><h4 id="像在真机上一样安装系统(以下各个版本的Linux有区别)"><a href="#像在真机上一样安装系统(以下各个版本的Linux有区别)" class="headerlink" title="像在真机上一样安装系统(以下各个版本的Linux有区别)"></a>像在真机上一样安装系统(以下各个版本的Linux有区别)</h4><p>开机后,等待加载,大概一分钟左右,会出现图形界面。</p><p>选择Install Ubuntu,语言选择English就好,不建议中文,如果实在看不懂英文再尝试中文。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/begin_to_install.jpg" alt=""></p><p>键盘选择英式键盘,点击continue。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/keyboard.jpg" alt=""></p><p>是否要更新软件,如果<strong>网络比较好且不着急用</strong>,可以选择“Download updates”,如果着急用就<strong>不要</strong>勾选,我这里写教程不着急就勾选了,普通网络勾选了的话下载更新文件可能需要<strong>五个小时</strong>以上。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/apps.jpg" alt=""></p><p>Install Now, continue</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/installation_type.jpg" alt=""></p><p>等待一小会。</p><p>选择地区,随意。</p><p>设置账户名和密码, continue</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/username.jpg" alt=""></p><p>接下来就等待安装完成。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/vmware/waiting.jpg" alt=""></p><h3 id="三、为虚拟机换源并安装gcc、g"><a href="#三、为虚拟机换源并安装gcc、g" class="headerlink" title="三、为虚拟机换源并安装gcc、g++"></a>三、为虚拟机换源并安装gcc、g++</h3><p>点击左下角所有应用,搜索terminal并打开。执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo passwd root</span><br></pre></td></tr></table></figure><p>为root设置初始密码。第一次输入的是当前账户的密码(password for user,前面安装的时候设置的),第二次输入的是为root设置的新密码(New password),第三次输入的是重复新密码(Retype new password)。设置好后使用 <code>su -</code> 命令登陆root账户,一下均在root账户下操作。</p><h4 id="换源"><a href="#换源" class="headerlink" title="换源"></a>换源</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> /etc/apt <span class="comment"># 切换到目录</span></span><br><span class="line">sudo mv sources.list sources.list.bak <span class="comment"># 备份原来的源列表</span></span><br><span class="line">sudo vi sources.list</span><br></pre></td></tr></table></figure><p>按一次 i 进入编辑模式,任选下面一组粘贴进去</p><p><strong>清华源</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"># 如果粘贴不了,请删掉中文注释</span><br><span class="line"># 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释</span><br><span class="line">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse</span><br><span class="line"># deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse</span><br><span class="line">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse</span><br><span class="line"># deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse</span><br><span class="line">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse</span><br><span class="line"># deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse</span><br><span class="line">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse</span><br><span class="line"># deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse</span><br><span class="line"></span><br><span class="line"># 以下是预发布软件源,不建议启用</span><br><span class="line"># deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse</span><br><span class="line"># deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse</span><br></pre></td></tr></table></figure><p><strong>阿里源</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse</span><br><span class="line">deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse</span><br><span class="line">deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse</span><br><span class="line">deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse</span><br><span class="line">deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse</span><br></pre></td></tr></table></figure><p><strong>中科大源</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">deb https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse</span><br><span class="line">deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse</span><br><span class="line">deb https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse</span><br><span class="line">deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse</span><br><span class="line">deb https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse</span><br><span class="line">deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse</span><br><span class="line">deb https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse</span><br><span class="line">deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse</span><br><span class="line">deb https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse</span><br><span class="line">deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe ultiverse</span><br></pre></td></tr></table></figure><p><strong>网易163源</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">deb http://mirrors.163.com/ubuntu/ focal main restricted universe multiverse</span><br><span class="line">deb http://mirrors.163.com/ubuntu/ focal-security main restricted universe multiverse</span><br><span class="line">deb http://mirrors.163.com/ubuntu/ focal-updates main restricted universe multiverse</span><br><span class="line">deb http://mirrors.163.com/ubuntu/ focal-proposed main restricted universe multiverse</span><br><span class="line">deb http://mirrors.163.com/ubuntu/ focal-backports main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.163.com/ubuntu/ focal main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.163.com/ubuntu/ focal-security main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.163.com/ubuntu/ focal-updates main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.163.com/ubuntu/ focal-proposed main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.163.com/ubuntu/ focal-backports main restricted universe multiverse</span><br></pre></td></tr></table></figure><p>然后执行以下命令</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get update</span><br><span class="line">sudo apt-get upgrade</span><br></pre></td></tr></table></figure><h4 id="安装vim,gcc,g"><a href="#安装vim,gcc,g" class="headerlink" title="安装vim,gcc,g++"></a>安装vim,gcc,g++</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install vim <span class="comment"># 可能本来已经有vim了,如果有的话就不需要安装了</span></span><br><span class="line">sudo apt install gcc</span><br><span class="line">sudo apt install g++</span><br></pre></td></tr></table></figure><h3 id="四、常见问题"><a href="#四、常见问题" class="headerlink" title="四、常见问题"></a>四、常见问题</h3><h4 id="缺少依赖"><a href="#缺少依赖" class="headerlink" title="缺少依赖"></a>缺少依赖</h4><p>安装软件时提示缺少依赖,报错如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">Reading package lists... Done</span><br><span class="line">Building dependency tree </span><br><span class="line">Reading state information... Done</span><br><span class="line">Some packages could not be installed. This may mean that you have</span><br><span class="line">requested an impossible situation or if you are using the unstable</span><br><span class="line">distribution that some required packages have not yet been created</span><br><span class="line">or been moved out of Incoming.</span><br><span class="line">The following information may help to resolve the situation:</span><br><span class="line"></span><br><span class="line">The following packages have unmet dependencies:</span><br><span class="line"> g++ : Depends: g++-7 (>= 7.3.0-12~) but it is not going to be installed</span><br><span class="line">E: Unable to correct problems, you have held broken packages.</span><br></pre></td></tr></table></figure><p>中文版报错</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">正在读取软件包列表... 完成</span><br><span class="line">正在分析软件包的依赖关系树</span><br><span class="line">正在读取状态信息... 完成</span><br><span class="line">有一些软件包无法被安装。如果您用的是 unstable 发行版,这也许是</span><br><span class="line">因为系统无法达到您要求的状态造成的。该版本中可能会有一些您需要的软件</span><br><span class="line">包尚未被创建或是它们已被从新到(Incoming)目录移出。</span><br><span class="line">下列信息可能会对解决问题有所帮助:</span><br><span class="line"></span><br><span class="line">下列软件包有未满足的依赖关系:</span><br><span class="line">g++ : 依赖: g++-4.8 (>= 4.8.2-5~) 但是它将不会被安装</span><br><span class="line">E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。</span><br></pre></td></tr></table></figure><p>上面的g++-x,x是多少都差不多,网上推荐的都是安装aptitude来代替apt-get,我尝试之后发现问题的根源是使用的源,再用同样的方法换一个其他的源就可以解决问题。</p>]]></content>
<categories>
<category> VMware </category>
<category> linux </category>
</categories>
<tags>
<tag> linux </tag>
<tag> Vmware </tag>
<tag> 虚拟机 </tag>
</tags>
</entry>
<entry>
<title>二进制炸弹 binary bomb</title>
<link href="/posts/csapp/binary_boob/"/>
<url>/posts/csapp/binary_boob/</url>
<content type="html"><![CDATA[<h3 id="solution"><a href="#solution" class="headerlink" title="solution"></a>solution</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Houses will begat jobs, jobs will begat houses.</span><br><span class="line">1 2 4 7 11 16</span><br><span class="line">0 -118</span><br><span class="line">6 6 DrEvil</span><br><span class="line">5 115</span><br><span class="line">2 4 1 3 6 5</span><br><span class="line">1001</span><br></pre></td></tr></table></figure><h3 id="phase-1"><a href="#phase-1" class="headerlink" title="phase_1"></a>phase_1</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">0000000000400e8d <phase_1>:</span><br><span class="line"> 400e8d:48 83 ec 08 sub $0x8,%rsp</span><br><span class="line"> 400e91:be d0 23 40 00 mov $0x4023d0,%esi</span><br><span class="line"> 400e96:e8 b5 04 00 00 callq 401350 <strings_not_equal></span><br><span class="line"> 400e9b:85 c0 test %eax,%eax</span><br><span class="line"> 400e9d:74 05 je 400ea4 <phase_1+0x17></span><br><span class="line"> 400e9f:e8 ab 05 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 400ea4:48 83 c4 08 add $0x8,%rsp</span><br><span class="line"> 400ea8:c3 retq</span><br></pre></td></tr></table></figure><p>观察反汇编代码,发现第3行和第4行是实现输入字符串和地址 <code>0x4023d0</code> 处的字符串进行比较,那么就要查看存在这个地址的字符串是什么。</p><p>进入gdb调试,<code>b phase_1</code> 在phase_1处加断点,<code>run</code> ,随意输入一串字符</p><p><code>set disassemble-next-line on</code> 显示代码</p><p><code>ni</code> 执行完第3行, <code>p/x $esi</code> 打印 <code>$esi</code> 的位置,得到结果 <code>0x4023d0</code> ,继续 <code>x/100c $esi</code> 打印该地址后100个空间内的内容,得到如下图所示:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/binary_bomb/phase_1.png" alt=""></p><p>找到其中第一个 ‘\0’,前面的内容即是答案:Houses will begat jobs, jobs will begat houses.(顺便看到了后面的内容:Wow! You’ve defused the secret stage! 看样子应该是破解隐藏关卡时打印的内容,剧透了:) )</p><h3 id="phase-2"><a href="#phase-2" class="headerlink" title="phase_2"></a>phase_2</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">0000000000400ea9 <phase_2>:</span><br><span class="line"> 400ea9:55 push %rbp</span><br><span class="line"> 400eaa:53 push %rbx</span><br><span class="line"> 400eab:48 83 ec 28 sub $0x28,%rsp</span><br><span class="line"> 400eaf:64 48 8b 04 25 28 00 mov %fs:0x28,%rax</span><br><span class="line"> 400eb6:00 00 </span><br><span class="line"> 400eb8:48 89 44 24 18 mov %rax,0x18(%rsp)</span><br><span class="line"> 400ebd:31 c0 xor %eax,%eax</span><br><span class="line"> 400ebf:48 89 e6 mov %rsp,%rsi</span><br><span class="line"> 400ec2:e8 aa 05 00 00 callq 401471 <read_six_numbers></span><br><span class="line"> 400ec7:83 3c 24 00 cmpl $0x0,(%rsp)</span><br><span class="line"> 400ecb:79 05 jns 400ed2 <phase_2+0x29></span><br><span class="line"> 400ecd:e8 7d 05 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 400ed2:48 89 e5 mov %rsp,%rbp</span><br><span class="line"> 400ed5:bb 01 00 00 00 mov $0x1,%ebx</span><br><span class="line"> 400eda:89 d8 mov %ebx,%eax</span><br><span class="line"> 400edc:03 45 00 add 0x0(%rbp),%eax</span><br><span class="line"> 400edf:39 45 04 cmp %eax,0x4(%rbp)</span><br><span class="line"> 400ee2:74 05 je 400ee9 <phase_2+0x40></span><br><span class="line"> 400ee4:e8 66 05 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 400ee9:83 c3 01 add $0x1,%ebx</span><br><span class="line"> 400eec:48 83 c5 04 add $0x4,%rbp</span><br><span class="line"> 400ef0:83 fb 06 cmp $0x6,%ebx</span><br><span class="line"> 400ef3:75 e5 jne 400eda <phase_2+0x31></span><br><span class="line"> 400ef5:48 8b 44 24 18 mov 0x18(%rsp),%rax</span><br><span class="line"> 400efa:64 48 33 04 25 28 00 xor %fs:0x28,%rax</span><br><span class="line"> 400f01:00 00 </span><br><span class="line"> 400f03:74 05 je 400f0a <phase_2+0x61></span><br><span class="line"> 400f05:e8 f6 fb ff ff callq 400b00 <__stack_chk_fail@plt></span><br><span class="line"> 400f0a:48 83 c4 28 add $0x28,%rsp</span><br><span class="line"> 400f0e:5b pop %rbx</span><br><span class="line"> 400f0f:5d pop %rbp</span><br><span class="line"> 400f10:c3 retq</span><br></pre></td></tr></table></figure><p>可以看到第10行调用一个函数叫 <code>read_six_numbers</code> 应该是读取标准输入的六个数。</p><p>然后第11、12行可以确定输入的第一个数只要非负即可,所以暂定第一个数为1。</p><p>再看一下第18行,可以看到是将 <code>%eax</code> 与 <code>0x4(%rbp)</code> 进行比较,不相等则爆炸。而第23、24行可告诉我们 <code>%ebx</code> 依次递增,不等于6时返回循环。而由第15行知, <code>%ebx</code> 初值为1,也就是五次循环依次将输入的后五个数和 <code>%eax</code> 进行比较。</p><p>于是我们需要知道每次循环时 <code>%eax</code> 的值。</p><p>再看整个循环体(16-24行),可以发现每次循环除 <code>%ebx</code> 作为循环变量依次递增外,<code>%rbp</code> 的地址也依次向后移动一个 <code>int</code> 大小,而第16、17行告诉我们每次循环时 <code>%eax</code> 的值都是由上一个输入的数再加上循环变量 <code>%rdp</code> 的值得到的,于是得到递推公式:</p><p>$$<br>a_n = a_{n - 1}+(n - 1)<br>$$</p><p>其中 $a_1$ 是任意非负整数。</p><p>所以答案就是:1 2 4 7 11 16 或 0 1 3 6 10 15 或 2 3 5 8 12 17 或 ……</p><h3 id="phase-3"><a href="#phase-3" class="headerlink" title="phase_3"></a>phase_3</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line">0000000000400f11 <phase_3>:</span><br><span class="line"> 400f11:48 83 ec 18 sub $0x18,%rsp</span><br><span class="line"> 400f15:64 48 8b 04 25 28 00 mov %fs:0x28,%rax</span><br><span class="line"> 400f1c:00 00 </span><br><span class="line"> 400f1e:48 89 44 24 08 mov %rax,0x8(%rsp)</span><br><span class="line"> 400f23:31 c0 xor %eax,%eax</span><br><span class="line"> 400f25:48 8d 4c 24 04 lea 0x4(%rsp),%rcx</span><br><span class="line"> 400f2a:48 89 e2 mov %rsp,%rdx</span><br><span class="line"> 400f2d:be cf 25 40 00 mov $0x4025cf,%esi</span><br><span class="line"> 400f32:e8 79 fc ff ff callq 400bb0 <__isoc99_sscanf@plt></span><br><span class="line"> 400f37:83 f8 01 cmp $0x1,%eax</span><br><span class="line"> 400f3a:7f 05 jg 400f41 <phase_3+0x30></span><br><span class="line"> 400f3c:e8 0e 05 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 400f41:83 3c 24 07 cmpl $0x7,(%rsp)</span><br><span class="line"> 400f45:77 65 ja 400fac <phase_3+0x9b></span><br><span class="line"> 400f47:8b 04 24 mov (%rsp),%eax</span><br><span class="line"> 400f4a:ff 24 c5 40 24 40 00 jmpq *0x402440(,%rax,8)</span><br><span class="line"> 400f51:b8 28 01 00 00 mov $0x128,%eax# 0</span><br><span class="line"> 400f56:eb 05 jmp 400f5d <phase_3+0x4c></span><br><span class="line"> 400f58:b8 00 00 00 00 mov $0x0,%eax# 1</span><br><span class="line"> 400f5d:2d 3c 02 00 00 sub $0x23c,%eax</span><br><span class="line"> 400f62:eb 05 jmp 400f69 <phase_3+0x58></span><br><span class="line"> 400f64:b8 00 00 00 00 mov $0x0,%eax# 2</span><br><span class="line"> 400f69:05 07 03 00 00 add $0x307,%eax</span><br><span class="line"> 400f6e:eb 05 jmp 400f75 <phase_3+0x64></span><br><span class="line"> 400f70:b8 00 00 00 00 mov $0x0,%eax# 3</span><br><span class="line"> 400f75:2d 69 02 00 00 sub $0x269,%eax</span><br><span class="line"> 400f7a:eb 05 jmp 400f81 <phase_3+0x70></span><br><span class="line"> 400f7c:b8 00 00 00 00 mov $0x0,%eax# 4</span><br><span class="line"> 400f81:05 69 02 00 00 add $0x269,%eax</span><br><span class="line"> 400f86:eb 05 jmp 400f8d <phase_3+0x7c></span><br><span class="line"> 400f88:b8 00 00 00 00 mov $0x0,%eax# 5</span><br><span class="line"> 400f8d:2d 69 02 00 00 sub $0x269,%eax</span><br><span class="line"> 400f92:eb 05 jmp 400f99 <phase_3+0x88></span><br><span class="line"> 400f94:b8 00 00 00 00 mov $0x0,%eax</span><br><span class="line"> 400f99:05 69 02 00 00 add $0x269,%eax</span><br><span class="line"> 400f9e:eb 05 jmp 400fa5 <phase_3+0x94></span><br><span class="line"> 400fa0:b8 00 00 00 00 mov $0x0,%eax</span><br><span class="line"> 400fa5:2d 69 02 00 00 sub $0x269,%eax</span><br><span class="line"> 400faa:eb 0a jmp 400fb6 <phase_3+0xa5></span><br><span class="line"> 400fac:e8 9e 04 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 400fb1:b8 00 00 00 00 mov $0x0,%eax</span><br><span class="line"> 400fb6:83 3c 24 05 cmpl $0x5,(%rsp)</span><br><span class="line"> 400fba:7f 06 jg 400fc2 <phase_3+0xb1></span><br><span class="line"> 400fbc:3b 44 24 04 cmp 0x4(%rsp),%eax</span><br><span class="line"> 400fc0:74 05 je 400fc7 <phase_3+0xb6></span><br><span class="line"> 400fc2:e8 88 04 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 400fc7:48 8b 44 24 08 mov 0x8(%rsp),%rax</span><br><span class="line"> 400fcc:64 48 33 04 25 28 00 xor %fs:0x28,%rax</span><br><span class="line"> 400fd3:00 00 </span><br><span class="line"> 400fd5:74 05 je 400fdc <phase_3+0xcb></span><br><span class="line"> 400fd7:e8 24 fb ff ff callq 400b00 <__stack_chk_fail@plt></span><br><span class="line"> 400fdc:48 83 c4 18 add $0x18,%rsp</span><br><span class="line"> 400fe0:c3 retq</span><br></pre></td></tr></table></figure><p>到了第三阶段,显然复杂很多,看上去很多 <code>jmp</code> 命令,应该是分支语句。</p><p>从头来看,可以看到第10行调用了 <code>scanf</code> 函数,接着便将 <code>%eax</code> 和1进行比较,不大于就爆炸!</p><p>也就是说输入格式不对就爆炸。</p><p>不过幸好我们已知输入两个整数。</p><p>接下来第14行将第一个数和7进行比较,大于7直接跳到41行,boom!所以第一个数应该小于7.</p><p>第17行则是根据输入的第一个数进行跳转。</p><p>接下来从后看,由第45、46行可知,第二个数要和最终的 <code>%eax</code> 相等。而由第43行可知第一个数不能大于5.</p><p>于是便有六种答案(后一个数是根据代码中的立即数计算得到的),依次是:</p><p>0 -118</p><p>1 -414</p><p>2 158</p><p>3 -617</p><p>4 0</p><p>5 -617</p><h3 id="phase-4"><a href="#phase-4" class="headerlink" title="phase_4"></a>phase_4</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line">0000000000400fe1 <func4>:# x in %edi, 0 in %esi, 14 in %edx</span><br><span class="line"> 400fe1:48 83 ec 08 sub $0x8,%rsp</span><br><span class="line"> 400fe5:89 d0 mov %edx,%eax</span><br><span class="line"> 400fe7:29 f0 sub %esi,%eax</span><br><span class="line"> 400fe9:89 c1 mov %eax,%ecx</span><br><span class="line"> 400feb:c1 e9 1f shr $0x1f,%ecx</span><br><span class="line"> 400fee:01 c8 add %ecx,%eax</span><br><span class="line"> 400ff0:d1 f8 sar %eax</span><br><span class="line"> 400ff2:8d 0c 30 lea (%rax,%rsi,1),%ecx</span><br><span class="line"> 400ff5:39 f9 cmp %edi,%ecx</span><br><span class="line"> 400ff7:7e 0c jle 401005 <func4+0x24></span><br><span class="line"> 400ff9:8d 51 ff lea -0x1(%rcx),%edx</span><br><span class="line"> 400ffc:e8 e0 ff ff ff callq 400fe1 <func4></span><br><span class="line"> 401001:01 c0 add %eax,%eax</span><br><span class="line"> 401003:eb 15 jmp 40101a <func4+0x39></span><br><span class="line"> 401005:b8 00 00 00 00 mov $0x0,%eax</span><br><span class="line"> 40100a:39 f9 cmp %edi,%ecx</span><br><span class="line"> 40100c:7d 0c jge 40101a <func4+0x39></span><br><span class="line"> 40100e:8d 71 01 lea 0x1(%rcx),%esi</span><br><span class="line"> 401011:e8 cb ff ff ff callq 400fe1 <func4></span><br><span class="line"> 401016:8d 44 00 01 lea 0x1(%rax,%rax,1),%eax</span><br><span class="line"> 40101a:48 83 c4 08 add $0x8,%rsp</span><br><span class="line"> 40101e:c3 retq </span><br><span class="line"></span><br><span class="line">000000000040101f <phase_4>:</span><br><span class="line"> 40101f:48 83 ec 18 sub $0x18,%rsp</span><br><span class="line"> 401023:64 48 8b 04 25 28 00 mov %fs:0x28,%rax</span><br><span class="line"> 40102a:00 00 </span><br><span class="line"> 40102c:48 89 44 24 08 mov %rax,0x8(%rsp)</span><br><span class="line"> 401031:31 c0 xor %eax,%eax</span><br><span class="line"> 401033:48 8d 4c 24 04 lea 0x4(%rsp),%rcx</span><br><span class="line"> 401038:48 89 e2 mov %rsp,%rdx</span><br><span class="line"> 40103b:be cf 25 40 00 mov $0x4025cf,%esi</span><br><span class="line"> 401040:e8 6b fb ff ff callq 400bb0 <__isoc99_sscanf@plt></span><br><span class="line"> 401045:83 f8 02 cmp $0x2,%eax</span><br><span class="line"> 401048:75 06 jne 401050 <phase_4+0x31></span><br><span class="line"> 40104a:83 3c 24 0e cmpl $0xe,(%rsp)</span><br><span class="line"> 40104e:76 05 jbe 401055 <phase_4+0x36></span><br><span class="line"> 401050:e8 fa 03 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 401055:ba 0e 00 00 00 mov $0xe,%edx</span><br><span class="line"> 40105a:be 00 00 00 00 mov $0x0,%esi</span><br><span class="line"> 40105f:8b 3c 24 mov (%rsp),%edi</span><br><span class="line"> 401062:e8 7a ff ff ff callq 400fe1 <func4></span><br><span class="line"> 401067:83 f8 06 cmp $0x6,%eax</span><br><span class="line"> 40106a:75 07 jne 401073 <phase_4+0x54></span><br><span class="line"> 40106c:83 7c 24 04 06 cmpl $0x6,0x4(%rsp)</span><br><span class="line"> 401071:74 05 je 401078 <phase_4+0x59></span><br><span class="line"> 401073:e8 d7 03 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 401078:48 8b 44 24 08 mov 0x8(%rsp),%rax</span><br><span class="line"> 40107d:64 48 33 04 25 28 00 xor %fs:0x28,%rax</span><br><span class="line"> 401084:00 00 </span><br><span class="line"> 401086:74 05 je 40108d <phase_4+0x6e></span><br><span class="line"> 401088:e8 73 fa ff ff callq 400b00 <__stack_chk_fail@plt></span><br><span class="line"> 40108d:48 83 c4 18 add $0x18,%rsp</span><br><span class="line"> 401091:c3 retq</span><br></pre></td></tr></table></figure><p>先看 <code>phase_4</code> 函数,第34行也调用了 <code>scanf</code> 函数,gdb调试看一下 <code>0x4025cf</code> 处存放的是什么:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/binary_bomb/phase_4.png" alt=""></p><p>可以看到需要输入两个 <code>int</code> 。</p><p>继续看第37、38行,是将第一个数和 14 进行比较,大于14就爆炸。</p><p>接下来便是将第一个数、0、14作为参数调用 <code>func4</code> ,得到的结果不是6就爆炸。再将第二个数和6比较,也是不相等的话就爆炸!所以要想不爆炸,就要第一个数经过 <code>func4</code> 处理得到6,第二个数就是6.</p><p>再看 <code>func4</code> 函数,根据反汇编代码可以得到 <code>func4</code> 函数的定义。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">func4</span><span class="params">(<span class="keyword">int</span> x, <span class="keyword">int</span> a, <span class="keyword">int</span> b)</span> </span>{</span><br><span class="line"><span class="comment">// a = 0, b = 14</span></span><br><span class="line"><span class="keyword">int</span> c = b - a; <span class="comment">// 14 in %eax</span></span><br><span class="line">c += c >> <span class="number">31</span>; <span class="comment">// 14 in %eax, 0 in %ecx</span></span><br><span class="line">c = (<span class="keyword">unsigned</span>)c >> <span class="number">1</span>; <span class="comment">// 7 in %eax</span></span><br><span class="line"><span class="keyword">int</span> d = a + c; <span class="comment">// 7 in %ecx</span></span><br><span class="line"><span class="comment">// d = a + (b - a) / 2 = (a + b) / 2</span></span><br><span class="line"><span class="keyword">if</span>(x < d) { <span class="comment">// x < 7</span></span><br><span class="line"><span class="keyword">return</span> <span class="number">2</span> * func4(x, a, d - <span class="number">1</span>);</span><br><span class="line">} <span class="keyword">else</span> <span class="keyword">if</span> (x > d) { <span class="comment">// x > 7</span></span><br><span class="line"><span class="keyword">return</span> <span class="number">2</span> * func4(x, d + <span class="number">1</span>, b) + <span class="number">1</span>;</span><br><span class="line">} <span class="keyword">else</span> { <span class="comment">// x = 7</span></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>如何传入 (x, 0, 14) 得到6呢?</p><p>可以发现其中的d就是a和b的平均值,也就是x小于平均值是返回一个偶数,大于平均值时返回一个奇数,等于平均值时返回0;那么第一次调用要输入的必然是小于7;</p><p>那么接下来就要调用 <code>func4(x, 0, 6)</code> 得到3,x应该大于3;</p><p>依次类推 <code>func4(x, 4, 6)</code> 得到1,x应该大于5, <code>func4(x, 6, 6)</code> 得到0,则x应该是6。</p><p>所以输入的两个数应该是6 6。</p><p>(至于隐藏阶段呢,暂时还没有发现)</p><h3 id="phase-5"><a href="#phase-5" class="headerlink" title="phase_5"></a>phase_5</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">0000000000401092 <phase_5>:</span><br><span class="line"> 401092:48 83 ec 18 sub $0x18,%rsp</span><br><span class="line"> 401096:64 48 8b 04 25 28 00 mov %fs:0x28,%rax</span><br><span class="line"> 40109d:00 00 </span><br><span class="line"> 40109f:48 89 44 24 08 mov %rax,0x8(%rsp)</span><br><span class="line"> 4010a4:31 c0 xor %eax,%eax</span><br><span class="line"> 4010a6:48 8d 4c 24 04 lea 0x4(%rsp),%rcx</span><br><span class="line"> 4010ab:48 89 e2 mov %rsp,%rdx</span><br><span class="line"> 4010ae:be cf 25 40 00 mov $0x4025cf,%esi</span><br><span class="line"> 4010b3:e8 f8 fa ff ff callq 400bb0 <__isoc99_sscanf@plt></span><br><span class="line"> 4010b8:83 f8 01 cmp $0x1,%eax</span><br><span class="line"> 4010bb:7f 05 jg 4010c2 <phase_5+0x30></span><br><span class="line"> 4010bd:e8 8d 03 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 4010c2:8b 04 24 mov (%rsp),%eax</span><br><span class="line"> 4010c5:83 e0 0f and $0xf,%eax</span><br><span class="line"> 4010c8:89 04 24 mov %eax,(%rsp)</span><br><span class="line"> 4010cb:83 f8 0f cmp $0xf,%eax</span><br><span class="line"> 4010ce:74 2f je 4010ff <phase_5+0x6d></span><br><span class="line"> 4010d0:b9 00 00 00 00 mov $0x0,%ecx</span><br><span class="line"> 4010d5:ba 00 00 00 00 mov $0x0,%edx</span><br><span class="line"> 4010da:83 c2 01 add $0x1,%edx</span><br><span class="line"> 4010dd:48 98 cltq </span><br><span class="line"> 4010df:8b 04 85 80 24 40 00 mov 0x402480(,%rax,4),%eax</span><br><span class="line"> 4010e6:01 c1 add %eax,%ecx</span><br><span class="line"> 4010e8:83 f8 0f cmp $0xf,%eax</span><br><span class="line"> 4010eb:75 ed jne 4010da <phase_5+0x48></span><br><span class="line"> 4010ed:c7 04 24 0f 00 00 00 movl $0xf,(%rsp)</span><br><span class="line"> 4010f4:83 fa 0f cmp $0xf,%edx</span><br><span class="line"> 4010f7:75 06 jne 4010ff <phase_5+0x6d></span><br><span class="line"> 4010f9:3b 4c 24 04 cmp 0x4(%rsp),%ecx</span><br><span class="line"> 4010fd:74 05 je 401104 <phase_5+0x72></span><br><span class="line"> 4010ff:e8 4b 03 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 401104:48 8b 44 24 08 mov 0x8(%rsp),%rax</span><br><span class="line"> 401109:64 48 33 04 25 28 00 xor %fs:0x28,%rax</span><br><span class="line"> 401110:00 00 </span><br><span class="line"> 401112:74 05 je 401119 <phase_5+0x87></span><br><span class="line"> 401114:e8 e7 f9 ff ff callq 400b00 <__stack_chk_fail@plt></span><br><span class="line"> 401119:48 83 c4 18 add $0x18,%rsp</span><br><span class="line"> 40111d:c3 retq</span><br></pre></td></tr></table></figure><p>同样先看一下 <code>scanf</code> 函数要求输入的格式是什么。可以看到依旧是两个 <code>int</code> 整数。</p><p>由第14-18行可知,输入的第一个数为15则爆炸。</p><p>接下来的21-26行是一个循环,由第28、29行可知,要循环15次才行。而第二个数要和最终的 <code>%ecx</code> 相等, <code>%ecx</code> 则是每次循环 <code>%eax</code> 的和,每次循环时 <code>%eax</code> 不能等于15,只有最后一次循环 <code>%eax</code> 才能等于15。</p><p>所以重点就在 <code>mov 0x402480(,%rax,4),%eax</code> 这一句,要经过15次将 <code>%eax</code> ,也就是输入的第一个数,变成15。</p><p>而 <code>0x402480(,%rax,4)</code> 则是在 <code>0x402480</code> 偏移 <code>4 * %rax</code> 处的值,应该是一个 <code>int</code> 数组。</p><p>打印一下看看:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/binary_bomb/phase_5.png" alt=""></p><p>果然是一个数组,顺藤摸瓜,便可得到输入的第一个数就是5,那么第二个数就是 $\frac{(1+15) * 15}{2} - 5 = 115$ 。</p><h3 id="phase-6"><a href="#phase-6" class="headerlink" title="phase_6"></a>phase_6</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line">000000000040111e <phase_6>:</span><br><span class="line"> 40111e:41 55 push %r13</span><br><span class="line"> 401120:41 54 push %r12</span><br><span class="line"> 401122:55 push %rbp</span><br><span class="line"> 401123:53 push %rbx</span><br><span class="line"> 401124:48 83 ec 68 sub $0x68,%rsp</span><br><span class="line"> 401128:64 48 8b 04 25 28 00 mov %fs:0x28,%rax</span><br><span class="line"> 40112f:00 00 </span><br><span class="line"> 401131:48 89 44 24 58 mov %rax,0x58(%rsp)</span><br><span class="line"> 401136:31 c0 xor %eax,%eax</span><br><span class="line"> 401138:48 89 e6 mov %rsp,%rsi</span><br><span class="line"> 40113b:e8 31 03 00 00 callq 401471 <read_six_numbers></span><br><span class="line"> 401140:49 89 e4 mov %rsp,%r12</span><br><span class="line"> 401143:41 bd 00 00 00 00 mov $0x0,%r13d</span><br><span class="line"> 401149:4c 89 e5 mov %r12,%rbp</span><br><span class="line"> 40114c:41 8b 04 24 mov (%r12),%eax</span><br><span class="line"> 401150:83 e8 01 sub $0x1,%eax</span><br><span class="line"> 401153:83 f8 05 cmp $0x5,%eax</span><br><span class="line"> 401156:76 05 jbe 40115d <phase_6+0x3f></span><br><span class="line"> 401158:e8 f2 02 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 40115d:41 83 c5 01 add $0x1,%r13d</span><br><span class="line"> 401161:41 83 fd 06 cmp $0x6,%r13d</span><br><span class="line"> 401165:74 3d je 4011a4 <phase_6+0x86></span><br><span class="line"> 401167:44 89 eb mov %r13d,%ebx</span><br><span class="line"> 40116a:48 63 c3 movslq %ebx,%rax</span><br><span class="line"> 40116d:8b 04 84 mov (%rsp,%rax,4),%eax</span><br><span class="line"> 401170:39 45 00 cmp %eax,0x0(%rbp)</span><br><span class="line"> 401173:75 05 jne 40117a <phase_6+0x5c></span><br><span class="line"> 401175:e8 d5 02 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 40117a:83 c3 01 add $0x1,%ebx</span><br><span class="line"> 40117d:83 fb 05 cmp $0x5,%ebx</span><br><span class="line"> 401180:7e e8 jle 40116a <phase_6+0x4c></span><br><span class="line"> 401182:49 83 c4 04 add $0x4,%r12</span><br><span class="line"> 401186:eb c1 jmp 401149 <phase_6+0x2b></span><br><span class="line"> 401188:48 8b 52 08 mov 0x8(%rdx),%rdx</span><br><span class="line"> 40118c:83 c0 01 add $0x1,%eax</span><br><span class="line"> 40118f:39 c8 cmp %ecx,%eax</span><br><span class="line"> 401191:75 f5 jne 401188 <phase_6+0x6a></span><br><span class="line"> 401193:48 89 54 74 20 mov %rdx,0x20(%rsp,%rsi,2)</span><br><span class="line"> 401198:48 83 c6 04 add $0x4,%rsi</span><br><span class="line"> 40119c:48 83 fe 18 cmp $0x18,%rsi</span><br><span class="line"> 4011a0:75 07 jne 4011a9 <phase_6+0x8b></span><br><span class="line"> 4011a2:eb 19 jmp 4011bd <phase_6+0x9f></span><br><span class="line"> 4011a4:be 00 00 00 00 mov $0x0,%esi</span><br><span class="line"> 4011a9:8b 0c 34 mov (%rsp,%rsi,1),%ecx</span><br><span class="line"> 4011ac:b8 01 00 00 00 mov $0x1,%eax</span><br><span class="line"> 4011b1:ba f0 32 60 00 mov $0x6032f0,%edx</span><br><span class="line"> 4011b6:83 f9 01 cmp $0x1,%ecx</span><br><span class="line"> 4011b9:7f cd jg 401188 <phase_6+0x6a></span><br><span class="line"> 4011bb:eb d6 jmp 401193 <phase_6+0x75></span><br><span class="line"> 4011bd:48 8b 5c 24 20 mov 0x20(%rsp),%rbx</span><br><span class="line"> 4011c2:48 8d 44 24 20 lea 0x20(%rsp),%rax</span><br><span class="line"> 4011c7:48 8d 74 24 48 lea 0x48(%rsp),%rsi</span><br><span class="line"> 4011cc:48 89 d9 mov %rbx,%rcx</span><br><span class="line"> 4011cf:48 8b 50 08 mov 0x8(%rax),%rdx</span><br><span class="line"> 4011d3:48 89 51 08 mov %rdx,0x8(%rcx)</span><br><span class="line"> 4011d7:48 83 c0 08 add $0x8,%rax</span><br><span class="line"> 4011db:48 89 d1 mov %rdx,%rcx</span><br><span class="line"> 4011de:48 39 f0 cmp %rsi,%rax</span><br><span class="line"> 4011e1:75 ec jne 4011cf <phase_6+0xb1></span><br><span class="line"> 4011e3:48 c7 42 08 00 00 00 movq $0x0,0x8(%rdx)</span><br><span class="line"> 4011ea:00 </span><br><span class="line"> 4011eb:bd 05 00 00 00 mov $0x5,%ebp</span><br><span class="line"> 4011f0:48 8b 43 08 mov 0x8(%rbx),%rax</span><br><span class="line"> 4011f4:8b 00 mov (%rax),%eax</span><br><span class="line"> 4011f6:39 03 cmp %eax,(%rbx)</span><br><span class="line"> 4011f8:7e 05 jle 4011ff <phase_6+0xe1></span><br><span class="line"> 4011fa:e8 50 02 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 4011ff:48 8b 5b 08 mov 0x8(%rbx),%rbx</span><br><span class="line"> 401203:83 ed 01 sub $0x1,%ebp</span><br><span class="line"> 401206:75 e8 jne 4011f0 <phase_6+0xd2></span><br><span class="line"> 401208:48 8b 44 24 58 mov 0x58(%rsp),%rax</span><br><span class="line"> 40120d:64 48 33 04 25 28 00 xor %fs:0x28,%rax</span><br><span class="line"> 401214:00 00 </span><br><span class="line"> 401216:74 05 je 40121d <phase_6+0xff></span><br><span class="line"> 401218:e8 e3 f8 ff ff callq 400b00 <__stack_chk_fail@plt></span><br><span class="line"> 40121d:48 83 c4 68 add $0x68,%rsp</span><br><span class="line"> 401221:5b pop %rbx</span><br><span class="line"> 401222:5d pop %rbp</span><br><span class="line"> 401223:41 5c pop %r12</span><br><span class="line"> 401225:41 5d pop %r13</span><br><span class="line"> 401227:c3 retq</span><br></pre></td></tr></table></figure><p>可以看到又有 <code>read_six_numbers</code> 函数,输入也是6个整数。</p><p>接下来15-34行是一个循环判断要求6个数字均不重复且不大于6,那么就是0-6的一个排列。</p><p>35-50行又是一个循环,可以看到将内存 <code>0x6032f0</code> 处的内容移到了栈中,看一下这些是什么内容:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/binary_bomb/phase_6.png" alt=""></p><p>发现是一个链表,所以这段就是依次将链表中的 <code>Node* next</code> 按照输入的六个数字的顺序存入栈中。(猜想这个炸弹可能是要将链表的 <code>long data</code> 按顺序排列,第二个数据应该是 <code>int index</code> ,第三个自然就是 <code>next</code> 指针)</p><p>51-61行是将节点按照在栈中的顺序重新连接。</p><p>然后可以看到第66、67行要求每个节点存储的数值都应该比上一个节点大才不会触发炸弹,所以按照节点的内容,答案应该是:2 4 1 3 6 5。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/binary_bomb/congratulations.png" alt=""></p><h3 id="secret-stage"><a href="#secret-stage" class="headerlink" title="secret_stage"></a>secret_stage</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line">0000000000401228 <fun7>:</span><br><span class="line"> 401228:48 83 ec 08 sub $0x8,%rsp</span><br><span class="line"> 40122c:48 85 ff test %rdi,%rdi</span><br><span class="line"> 40122f:74 2b je 40125c <fun7+0x34></span><br><span class="line"> 401231:8b 17 mov (%rdi),%edx</span><br><span class="line"> 401233:39 f2 cmp %esi,%edx</span><br><span class="line"> 401235:7e 0d jle 401244 <fun7+0x1c></span><br><span class="line"> 401237:48 8b 7f 08 mov 0x8(%rdi),%rdi</span><br><span class="line"> 40123b:e8 e8 ff ff ff callq 401228 <fun7></span><br><span class="line"> 401240:01 c0 add %eax,%eax</span><br><span class="line"> 401242:eb 1d jmp 401261 <fun7+0x39></span><br><span class="line"> 401244:b8 00 00 00 00 mov $0x0,%eax</span><br><span class="line"> 401249:39 f2 cmp %esi,%edx</span><br><span class="line"> 40124b:74 14 je 401261 <fun7+0x39></span><br><span class="line"> 40124d:48 8b 7f 10 mov 0x10(%rdi),%rdi</span><br><span class="line"> 401251:e8 d2 ff ff ff callq 401228 <fun7></span><br><span class="line"> 401256:8d 44 00 01 lea 0x1(%rax,%rax,1),%eax</span><br><span class="line"> 40125a:eb 05 jmp 401261 <fun7+0x39></span><br><span class="line"> 40125c:b8 ff ff ff ff mov $0xffffffff,%eax</span><br><span class="line"> 401261:48 83 c4 08 add $0x8,%rsp</span><br><span class="line"> 401265:c3 retq </span><br><span class="line"></span><br><span class="line">0000000000401266 <secret_phase>:</span><br><span class="line"> 401266:53 push %rbx</span><br><span class="line"> 401267:e8 44 02 00 00 callq 4014b0 <read_line></span><br><span class="line"> 40126c:ba 0a 00 00 00 mov $0xa,%edx</span><br><span class="line"> 401271:be 00 00 00 00 mov $0x0,%esi</span><br><span class="line"> 401276:48 89 c7 mov %rax,%rdi</span><br><span class="line"> 401279:e8 12 f9 ff ff callq 400b90 <strtol@plt></span><br><span class="line"> 40127e:48 89 c3 mov %rax,%rbx</span><br><span class="line"> 401281:8d 40 ff lea -0x1(%rax),%eax</span><br><span class="line"> 401284:3d e8 03 00 00 cmp $0x3e8,%eax</span><br><span class="line"> 401289:76 05 jbe 401290 <secret_phase+0x2a></span><br><span class="line"> 40128b:e8 bf 01 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 401290:89 de mov %ebx,%esi</span><br><span class="line"> 401292:bf 10 31 60 00 mov $0x603110,%edi</span><br><span class="line"> 401297:e8 8c ff ff ff callq 401228 <fun7></span><br><span class="line"> 40129c:83 f8 07 cmp $0x7,%eax</span><br><span class="line"> 40129f:74 05 je 4012a6 <secret_phase+0x40></span><br><span class="line"> 4012a1:e8 a9 01 00 00 callq 40144f <explode_bomb></span><br><span class="line"> 4012a6:bf 00 24 40 00 mov $0x402400,%edi</span><br><span class="line"> 4012ab:e8 30 f8 ff ff callq 400ae0 <puts@plt></span><br><span class="line"> 4012b0:e8 21 03 00 00 callq 4015d6 <phase_defused></span><br><span class="line"> 4012b5:5b pop %rbx</span><br><span class="line"> 4012b6:c3 retq</span><br></pre></td></tr></table></figure><p>接下来就是隐藏阶段了,要想破解隐藏阶段,就要知道在哪里调用了它,在代码中查找 <code>secret_phase</code> 可以发现只在 <code>phase_defused</code> 函数中调用它,那么毫无疑问就是这里:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">00000000004015d6 <phase_defused>:</span><br><span class="line"> 4015d6:48 83 ec 78 sub $0x78,%rsp</span><br><span class="line"> 4015da:64 48 8b 04 25 28 00 mov %fs:0x28,%rax</span><br><span class="line"> 4015e1:00 00 </span><br><span class="line"> 4015e3:48 89 44 24 68 mov %rax,0x68(%rsp)</span><br><span class="line"> 4015e8:31 c0 xor %eax,%eax</span><br><span class="line"> 4015ea:83 3d 9b 21 20 00 06 cmpl $0x6,0x20219b(%rip) # 60378c <num_input_strings></span><br><span class="line"> 4015f1:75 5e jne 401651 <phase_defused+0x7b></span><br><span class="line"> 4015f3:4c 8d 44 24 10 lea 0x10(%rsp),%r8</span><br><span class="line"> 4015f8:48 8d 4c 24 0c lea 0xc(%rsp),%rcx</span><br><span class="line"> 4015fd:48 8d 54 24 08 lea 0x8(%rsp),%rdx</span><br><span class="line"> 401602:be 19 26 40 00 mov $0x402619,%esi</span><br><span class="line"> 401607:bf 90 38 60 00 mov $0x603890,%edi</span><br><span class="line"> 40160c:e8 9f f5 ff ff callq 400bb0 <__isoc99_sscanf@plt></span><br><span class="line"> 401611:83 f8 03 cmp $0x3,%eax</span><br><span class="line"> 401614:75 31 jne 401647 <phase_defused+0x71></span><br><span class="line"> 401616:be 22 26 40 00 mov $0x402622,%esi</span><br><span class="line"> 40161b:48 8d 7c 24 10 lea 0x10(%rsp),%rdi</span><br><span class="line"> 401620:e8 2b fd ff ff callq 401350 <strings_not_equal></span><br><span class="line"> 401625:85 c0 test %eax,%eax</span><br><span class="line"> 401627:75 1e jne 401647 <phase_defused+0x71></span><br><span class="line"> 401629:bf f8 24 40 00 mov $0x4024f8,%edi</span><br><span class="line"> 40162e:e8 ad f4 ff ff callq 400ae0 <puts@plt></span><br><span class="line"> 401633:bf 20 25 40 00 mov $0x402520,%edi</span><br><span class="line"> 401638:e8 a3 f4 ff ff callq 400ae0 <puts@plt></span><br><span class="line"> 40163d:b8 00 00 00 00 mov $0x0,%eax</span><br><span class="line"> 401642:e8 1f fc ff ff callq 401266 <secret_phase></span><br><span class="line"> 401647:bf 58 25 40 00 mov $0x402558,%edi</span><br><span class="line"> 40164c:e8 8f f4 ff ff callq 400ae0 <puts@plt></span><br><span class="line"> 401651:48 8b 44 24 68 mov 0x68(%rsp),%rax</span><br><span class="line"> 401656:64 48 33 04 25 28 00 xor %fs:0x28,%rax</span><br><span class="line"> 40165d:00 00 </span><br><span class="line"> 40165f:74 05 je 401666 <phase_defused+0x90></span><br><span class="line"> 401661:e8 9a f4 ff ff callq 400b00 <__stack_chk_fail@plt></span><br><span class="line"> 401666:48 83 c4 78 add $0x78,%rsp</span><br><span class="line"> 40166a:c3 retq</span><br></pre></td></tr></table></figure><p>可以发现只在第六个炸弹结束后才会触发调用隐藏阶段的函数。</p><p>可以看到第12、13、14行是将第四个炸弹输入的内容重新作为标准输入来用,而第17-21行则是将输入的两个数字之后的字符串和内存中固定的字符串进行比较,查看该字符串:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/binary_bomb/secret_phase.png" alt=""></p><p>那么触发隐藏阶段的密码就是 <code>DrEvil</code>。</p><p>接下来看 <code>secret_phase</code> ,看起来不是很复杂。</p><p>先调用 <code>read_line</code> 读入内容,接下来是调用 <code>strtol</code> 将 <code>char*</code> 转为 <code>long</code> 和非数字部分,</p><p>接下来第32行则是判断输入的数字减 1 后是否大于1000,大于1000则爆炸,即输入的数不大于1001。</p><p>之后便是调用 <code>fun7</code> ,参数是存在 <code>0x603110</code> 处的 <code>n1</code> 和输入的数,结果要得到7。</p><p>查看n1的内容:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/binary_bomb/tree.png" alt=""></p><p>猜测其结构:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">long</span> data;</span><br><span class="line"> Node* left;</span><br><span class="line"> Node* right;</span><br><span class="line">} Node;</span><br></pre></td></tr></table></figure><p>整理得到如下的二叉树(后来发现这一步其实没必要)</p><div class="mermaid"> graph TDn1[n1,data=36] --> n21[n21,data=8]n1 --> n22[n22,data=50]n21 --> n31[n31,data=6]n21 --> n32[n32,data=22]n22 --> n33[n33,data=45]n22 --> n34[n34,data=107]n31 --> n41,data=1n31 --> n42,data=7n32 --> n43,data=20n32 --> n44,data=35n33 --> n45,data=40n33 --> n46,data=47n34 --> n47,data=99n34 --> n48,data=1001 </div><p>再看 <code>fun7</code> ,根据反汇编代码写出伪代码,看起来是 phase_4 的一个拓展:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">fun7</span><span class="params">(Node* n, <span class="keyword">long</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(n) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (x < n->data) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">2</span> * fun7(n->left, x);</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (x == n->data) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">2</span> * fun7(n->right, x) + <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>要得到7,就要$x>36$ , <code>fun7(n22, x) == 3</code> ;</p><p>依此类推,$x>50$ , <code>fun7(n34, x) == 1</code> ;</p><p>这里要得到1有两种方式,一种就是 <code>n34 == NULL</code> ,显然不成立,另一种就是:</p><p>$x > 107$ , <code>fun7(n48) == 0</code> ;</p><p>所以 <code>x = n48->data</code> ,即1001。</p><h3 id="拆弹成功"><a href="#拆弹成功" class="headerlink" title="拆弹成功:"></a>拆弹成功:</h3><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/binary_bomb/final.png" alt=""></p>]]></content>
<categories>
<category> 作业 </category>
<category> 深入理解计算机系统 </category>
</categories>
<tags>
<tag> 深入理解计算机系统 </tag>
<tag> 二进制炸弹 </tag>
</tags>
</entry>
<entry>
<title>mysql如何查看用户及其权限</title>
<link href="/posts/sql-users-grants/"/>
<url>/posts/sql-users-grants/</url>
<content type="html"><![CDATA[<h3 id="【1】查看mysql数据库中的所有用户"><a href="#【1】查看mysql数据库中的所有用户" class="headerlink" title="【1】查看mysql数据库中的所有用户"></a>【1】查看mysql数据库中的所有用户</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="keyword">DISTINCT</span> <span class="keyword">CONCAT</span>(<span class="string">'User: '''</span>,<span class="keyword">user</span>,<span class="string">'''@'''</span>,host,<span class="string">''';'</span>) <span class="keyword">AS</span> <span class="keyword">query</span> <span class="keyword">FROM</span> mysql.user;</span><br></pre></td></tr></table></figure><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/sql-users-grants/20190708122447933.png" alt=""></p><h3 id="【2】查看某个用户的权限"><a href="#【2】查看某个用户的权限" class="headerlink" title="【2】查看某个用户的权限"></a>【2】查看某个用户的权限</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">show</span> <span class="keyword">grants</span> <span class="keyword">for</span> <span class="string">'nextcloud'</span>@<span class="string">'%'</span>; </span><br><span class="line"><span class="comment">-- or</span></span><br><span class="line"><span class="keyword">select</span> * <span class="keyword">from</span> mysql.user <span class="keyword">where</span> <span class="keyword">user</span>=<span class="string">'root'</span> \G;</span><br></pre></td></tr></table></figure><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/sql-users-grants/20190708122715379.png" alt=""></p><h3 id="【3】查看当前用户"><a href="#【3】查看当前用户" class="headerlink" title="【3】查看当前用户"></a>【3】查看当前用户</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">select user();</span><br></pre></td></tr></table></figure><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/sql-users-grants/20190708122842656.png" alt=""></p><h3 id="【4】修改用户密码"><a href="#【4】修改用户密码" class="headerlink" title="【4】修改用户密码"></a>【4】修改用户密码</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">use mysql;</span><br><span class="line">UPDATE user SET password=PASSWORD('新密码') WHERE user='用户';</span><br><span class="line">flush privileges;</span><br></pre></td></tr></table></figure><h3 id="【5】修改用户权限及密码"><a href="#【5】修改用户权限及密码" class="headerlink" title="【5】修改用户权限及密码"></a>【5】修改用户权限及密码</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- grant 权限 on 库名.表名 to '用户名'@’网段‘ identified by "该用户的密码";</span></span><br><span class="line"><span class="keyword">grant</span> <span class="keyword">all</span> <span class="keyword">privileges</span> <span class="keyword">on</span> nextcloud.* <span class="keyword">to</span> <span class="string">'nextcloud'</span>@<span class="string">'%'</span> <span class="keyword">identified</span> <span class="keyword">by</span> <span class="string">'du..olctx..entest.1'</span>;</span><br></pre></td></tr></table></figure><h3 id="【6】删除用户"><a href="#【6】删除用户" class="headerlink" title="【6】删除用户"></a>【6】删除用户</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">drop</span> <span class="keyword">user</span> <span class="string">'nextcloud'</span>@<span class="string">'%'</span>;</span><br></pre></td></tr></table></figure><p>转载自:</p><p><a href="https://blog.csdn.net/GX_1_11_real/article/details/95052475" target="_blank" rel="noopener">https://blog.csdn.net/GX_1_11_real/article/details/95052475</a></p>]]></content>
<categories>
<category> mysql </category>
</categories>
<tags>
<tag> mysql </tag>
<tag> 用户 </tag>
<tag> 权限 </tag>
</tags>
</entry>
<entry>
<title>震撼心灵,催人泪下-《向南2:会飞的梦》南京大学2020年招生微电影</title>
<link href="/posts/xiangnan2/"/>
<url>/posts/xiangnan2/</url>
<content type="html"><![CDATA[<style type="text/css">.main-inner {opacity: 1;}</style><div class="bilibili"> <iframe src="//player.bilibili.com/player.html?aid=796612681&bvid=BV1MC4y187fF&cid=217732226&page=1&high_quality=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" class="bilibili-video"> </iframe></div>]]></content>
<categories>
<category> NJU </category>
</categories>
<tags>
<tag> NJU </tag>
</tags>
</entry>
<entry>
<title>深入理解计算机系统作业五</title>
<link href="/posts/csapp/homework5/"/>
<url>/posts/csapp/homework5/</url>
<content type="html"><![CDATA[<h1 id="作业5"><a href="#作业5" class="headerlink" title="作业5"></a>作业5</h1><h3 id="3-32"><a href="#3-32" class="headerlink" title="3.32"></a>3.32</h3><table border="1"> <tr><td colspan="3" align="center">指令</td><td colspan="6" align="center">状态值(指令执行前)</td></tr> <tr><td align="center">标号</td><td align="center">PC</td><td align="center">指令</td><td align="center">%rdi</td><td align="center">%rsi</td><td align="center">%rax</td><td align="center">%rsp</td><td align="center">*%rsp</td><td align="center">描述</td></tr> <tr><td align="center">M1</td><td align="center">0x400560</td><td align="center">callq</td><td align="center">10</td><td align="center">—</td><td align="center">—</td><td align="center">0x7fffffffe820</td><td align="center">—</td><td align="center">调用first (10)</td></tr> <tr><td align="center">F1</td><td align="center">0x400548</td><td align="center">lea</td><td align="center">10</td><td align="center">—</td><td align="center">—</td><td align="center">0x7fffffffe818</td><td align="center">0x400565</td><td align="center">first函数入口</td></tr> <tr><td align="center">F2</td><td align="center">0x40054c</td><td align="center">sub</td><td align="center">10</td><td align="center">11</td><td align="center">—</td><td align="center">0x7fffffffe818</td><td align="center">0x400565</td><td align="center"></td></tr> <tr><td align="center">F3</td><td align="center">0x400550</td><td align="center">callq</td><td align="center">9</td><td align="center">11</td><td align="center">—</td><td align="center">0x7fffffffe818</td><td align="center">0x400565</td><td align="center">调用last (9, 11)</td></tr> <tr><td align="center">L1</td><td align="center">0x400540</td><td align="center">mov</td><td align="center">9</td><td align="center">11</td><td align="center">—</td><td align="center">0x7fffffffe810</td><td align="center">0x400555</td><td align="center">last函数入口</td></tr> <tr><td align="center">L2</td><td align="center">0x400543</td><td align="center">imul</td><td align="center">9</td><td align="center">11</td><td align="center">9</td><td align="center">0x7fffffffe810</td><td align="center">0x400555</td><td align="center"></td></tr> <tr><td align="center">L3</td><td align="center">0x400547</td><td align="center">retq</td><td align="center">9</td><td align="center">11</td><td align="center">99</td><td align="center">0x7fffffffe810</td><td align="center">0x400555</td><td align="center">last返回值 99</td></tr> <tr><td align="center">F4</td><td align="center">0x400555</td><td align="center">repz</td><td align="center">9</td><td align="center">11</td><td align="center">99</td><td align="center">0x7fffffffe818</td><td align="center">0x400565</td><td align="center">first返回值99</td></tr> <tr><td align="center">M2</td><td align="center">0x400565</td><td align="center">mov</td><td align="center">9</td><td align="center">11</td><td align="center">99</td><td align="center">0x7fffffffe820</td><td align="center">—</td><td align="center">main函数后续</td></tr></table><h3 id="3-33"><a href="#3-33" class="headerlink" title="3.33"></a>3.33</h3><p>情况1:假设 <code>3 addq %rdi, (%rdx)</code> 是实现 <code>*u += a</code> ,</p><p>则易知 <code>a in %edi</code> , <code>u in %rdx</code></p><p>从而 <code>4 addb %silm, (%rcx)</code> 是实现 <code>*v += b</code> </p><p>从而 <code>b in %si</code> , <code>v in %rcx</code> ,</p><p>即四个参数的顺序为 <code>int procprobl(int a, short b, long *u, char *v)</code>;</p><br/><p>情况2:反之,假设 <code>3 addq %rdi, (%rdx)</code> 实现 <code>*v += b</code>,</p><p>则有 <code>b in %edi</code> , <code>*v in %rdx</code></p><p>从而 <code>4 addb %silm, (%rcx)</code> 是实现 <code>*u += a</code></p><p>从而 <code>a in %si</code> , <code>u in rcx</code></p><p>即 <code>int procprobl(int b, short a, long *v, char *u)</code></p><h3 id="3-35"><a href="#3-35" class="headerlink" title="3.35"></a>3.35</h3><p>A. 保存参数x的值,用来计算表达式结果,保存当前状态</p><p>B. </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">rfun</span><span class="params">(<span class="keyword">unsigned</span> <span class="keyword">long</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (x == <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> nx = x >> <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">long</span> rv = rfun(nx);</span><br><span class="line"> <span class="keyword">return</span> x + rv;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-38"><a href="#3-38" class="headerlink" title="3.38"></a>3.38</h3><p>由</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">leaq0(,%rdi,8), %rdx#8i</span><br><span class="line">subq%rdi, %rdx#7i</span><br><span class="line">addq%rsi, %rdx#7i+j</span><br></pre></td></tr></table></figure><p>可知P为7列,即N=7</p><p>由</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">leaq(%rsi,%rsi,4), %rax#5j</span><br><span class="line">addq%rax, %rdi#5j+i</span><br></pre></td></tr></table></figure><p>可知,Q为5列,即M=5</p><p>综上,M=5,N=7</p><h3 id="3-41"><a href="#3-41" class="headerlink" title="3.41"></a>3.41</h3><p>A.</p><p>p: 0</p><p>s.x: 8</p><p>s.y: 12</p><p>next: 16</p><p>B. 24</p><p>C.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">sp_init</span><span class="params">(struct prob *sp)</span> </span>{</span><br><span class="line"> sp->s.x = sp->s.y;</span><br><span class="line"> sp->p = &(sp->s.x);</span><br><span class="line"> sp->next = sp;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-45"><a href="#3-45" class="headerlink" title="3.45"></a>3.45</h3><p>A.</p><table><thead><tr><th align="center">a</th><th align="center">b</th><th align="center">c</th><th align="center">d</th><th align="center">e</th><th align="center">f</th><th align="center">g</th><th align="center">h</th></tr></thead><tbody><tr><td align="center">0</td><td align="center">8</td><td align="center">16</td><td align="center">24</td><td align="center">28</td><td align="center">32</td><td align="center">40</td><td align="center">48</td></tr></tbody></table><p>B. 56</p><p>C. </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"><span class="keyword">char</span> d;</span><br><span class="line"><span class="keyword">char</span> f;</span><br><span class="line">short b;</span><br><span class="line"><span class="keyword">float</span> e;</span><br><span class="line"><span class="keyword">int</span> h;</span><br><span class="line"><span class="keyword">char</span> *a;</span><br><span class="line"><span class="keyword">double</span> c;</span><br><span class="line"><span class="keyword">long</span> g;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>重排的偏移量</p><table><thead><tr><th align="center">d</th><th align="center">f</th><th align="center">b</th><th align="center">e</th><th align="center">h</th><th align="center">a</th><th align="center">c</th><th align="center">g</th></tr></thead><tbody><tr><td align="center">0</td><td align="center">1</td><td align="center">2</td><td align="center">4</td><td align="center">8</td><td align="center">16</td><td align="center">24</td><td align="center">32</td></tr></tbody></table><p>大小:40</p><h3 id="3-48"><a href="#3-48" class="headerlink" title="3.48"></a>3.48</h3><p>A.不带保护者:buf: 0, v: 24;带保护者:buf: 16, v: 8, 金丝雀: 40;</p><p>B. 带保护者的模式由于v比buf更接近栈顶,即使缓存区溢出也不会破坏v的值。</p><h3 id="3-69"><a href="#3-69" class="headerlink" title="3.69"></a>3.69</h3><p>A.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">mov0x120(%rsi),%ecx# bp->last</span><br><span class="line">add(%rsi),%ecx# bp->firsst + bp->last</span><br><span class="line">lea(%rdi,%rdi,4),%rax# 5i</span><br><span class="line">lea(%rsi,%rax,8),%rax# bp+8*5i # a_struct的大小为40</span><br><span class="line">mov0x8(%rax),%rdx# bp+8*5i+8 # ap相对bp的偏移量为8 # %rdx即ap->idx</span><br><span class="line">movslq%ecx,%rcx# (int)n => (long)</span><br><span class="line">mov%rcx,0x10(%rax,%rdx,8)</span><br><span class="line"> # 8(ap->idx) + bp + 40*i + 0x10 = ap + 8(ap->idx) + 0x8 # ap->x[ap->idx]</span><br><span class="line"> # idx是long型,x是long数组</span><br><span class="line"> # 40 = 8 + 4 * 8,x数组的长度为4 </span><br><span class="line"> # 0x120=288=8+40*7,CNT=7</span><br><span class="line">retq</span><br></pre></td></tr></table></figure><p>CNT=7</p><p>B.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line"> <span class="keyword">long</span> idx;</span><br><span class="line"> <span class="keyword">long</span> x[<span class="number">4</span>];</span><br><span class="line">} a_struct;</span><br></pre></td></tr></table></figure><h3 id="3-70"><a href="#3-70" class="headerlink" title="3.70"></a>3.70</h3><p>A. </p><table><thead><tr><th align="center">e1.p</th><th align="center">e1.y</th><th align="center">e2.x</th><th align="center">e2.next</th></tr></thead><tbody><tr><td align="center">0</td><td align="center">8</td><td align="center">0</td><td align="center">8</td></tr></tbody></table><p>B. 16</p><p>C. </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">proc</span><span class="params">(<span class="keyword">union</span> ele *up)</span> </span>{</span><br><span class="line"> up->e2.x = *(*(up->e2.next).e1.p) - *(up->e2.next).e1.y</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 作业 </category>
<category> 深入理解计算机系统 </category>
</categories>
<tags>
<tag> 深入理解计算机系统 </tag>
</tags>
</entry>
<entry>
<title>解决coding利用pages搭建博客没有“持续部署-静态网站”页的问题</title>
<link href="/posts/coding-pages/"/>
<url>/posts/coding-pages/</url>
<content type="html"><![CDATA[<p>coding总是改来改去,很多教程几乎都是博主发了以后就不再更新,而新手们看着别人的教程总是摸不着头脑。最近有人说coding找不到静态网页的部署,本篇就来介绍如何找到“静态网站”页面。</p><a id="more"></a><p>首先打开coding主页,选择博客项目打开,大概长这样</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/coding-pages/front.png" alt=""></p><p>点击左下角“项目设置”,找到“功能开关”</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/coding-pages/Functions.png" alt=""></p><p>打开持续部署,再次返回项目主页,可以看到已经有了“持续部署”一项,展开“持续部署”,</p><p>就可以找到“静态网页”啦~</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/coding-pages/success.png" alt=""></p><p>(又水完一篇文章)</p>]]></content>
<categories>
<category> blog </category>
</categories>
<tags>
<tag> coding </tag>
<tag> blog </tag>
</tags>
</entry>
<entry>
<title>解决gdb调试run时的warning问题</title>
<link href="/posts/gdbwarning/"/>
<url>/posts/gdbwarning/</url>
<content type="html"><![CDATA[<p>这几天做汇编实验,总是跳出这个warning,就想着找时间解决掉它。今天就来看看这个问题到底怎么解决。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">(gdb) r</span><br><span class="line">Starting program: xxxxxxxxx </span><br><span class="line">warning: the debug information found <span class="keyword">in</span> <span class="string">"/usr/lib/debug//lib64/ld-2.17.so.debug"</span> does not match <span class="string">"/lib64/ld-linux-x86-64.so.2"</span> (CRC mismatch).</span><br><span class="line"></span><br><span class="line">warning: the debug information found <span class="keyword">in</span> <span class="string">"/usr/lib/debug/usr/lib64/ld-2.17.so.debug"</span> does not match <span class="string">"/lib64/ld-linux-x86-64.so.2"</span> (CRC mismatch).</span><br><span class="line"></span><br><span class="line">warning: the debug information found <span class="keyword">in</span> <span class="string">"/usr/lib/debug//usr/lib64/ld-2.17.so.debug"</span> does not match <span class="string">"/lib64/ld-linux-x86-64.so.2"</span> (CRC mismatch).</span><br><span class="line"></span><br><span class="line">warning: the debug information found <span class="keyword">in</span> <span class="string">"/usr/lib/debug/usr/lib64//ld-2.17.so.debug"</span> does not match <span class="string">"/lib64/ld-linux-x86-64.so.2"</span> (CRC mismatch).</span><br><span class="line"></span><br><span class="line">warning: the debug information found <span class="keyword">in</span> <span class="string">"/usr/lib/debug//lib64/libc-2.17.so.debug"</span> does not match <span class="string">"/lib64/libc.so.6"</span> (CRC mismatch).</span><br><span class="line"></span><br><span class="line">warning: the debug information found <span class="keyword">in</span> <span class="string">"/usr/lib/debug/usr/lib64/libc-2.17.so.debug"</span> does not match <span class="string">"/lib64/libc.so.6"</span> (CRC mismatch).</span><br><span class="line"></span><br><span class="line">warning: the debug information found <span class="keyword">in</span> <span class="string">"/usr/lib/debug//usr/lib64/libc-2.17.so.debug"</span> does not match <span class="string">"/lib64/libc.so.6"</span> (CRC mismatch).</span><br><span class="line"></span><br><span class="line">warning: the debug information found <span class="keyword">in</span> <span class="string">"/usr/lib/debug/usr/lib64//libc-2.17.so.debug"</span> does not match <span class="string">"/lib64/libc.so.6"</span> (CRC mismatch).</span><br></pre></td></tr></table></figure><p>同时运行结束还有这样应该报错</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Missing separate debuginfos, use: debuginfo-install glibc-2.17-307.el7.1.x86_64</span><br></pre></td></tr></table></figure><a id="more"></a><br/><p>先百度一波 <code>CRC mismatch</code> </p><p>半小时过去,无果。</p><p>算了还是先看后面一句 <code>Missing separate debuginfos</code></p><p>按照他的说法执行 <code>sudo debuginfo-install glibc-2.17-307.el7.1.x86_64</code></p><p>漫长的等待…</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/gdbwarning/download.png" alt=""></p><p>大概二十几分钟过去了,安装结束,再次运行gdb发现前面的warning也没有了!</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/gdbwarning/ttuccqhrhx.jpeg" alt=""></p><p>原因是什么呢?</p><p>有时间再更吧,先抓紧时间做实验了~</p>]]></content>
<categories>
<category> linux </category>
</categories>
<tags>
<tag> linux </tag>
<tag> CentOS 7 </tag>
<tag> gdb </tag>
</tags>
</entry>
<entry>
<title>祖安神器(仅供娱乐)</title>
<link href="/posts/zuan/"/>
<url>/posts/zuan/</url>
<content type="html"><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>今天早上起来出去锻炼,公交车上闲来无事,刷空间,看到朋友打王者被骂,对面叫嚣加QQ要喷爆他,不能忍!回家后拿起电脑就开始敲,写了这个祖安神器准备帮朋友一把。</p><a id="more"></a><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/01.jpg" style="zoom:40%;" /><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/02.jpg" style="zoom:40%;" /><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/03.jpg" style="zoom:40%;" /><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/04.jpg" style="zoom:40%;" /><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/05.jpg" style="zoom:40%;" /><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/06.jpg" style="zoom:40%;" /><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/07.jpg" style="zoom:40%;" /><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/08.jpg" style="zoom:40%;" /><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/09.jpg" style="zoom:40%;" /></p><h3 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h3><p>先得准备语料,咱这不会骂人,也没积累啥语料,网上找找吧。先百度一下祖安,找到这个<a href="https://nmsl.shadiao.app/" target="_blank" rel="noopener">“骂人宝典”</a>,顺手嫖了一个api,正写着,发现api有访问频率的限制,咱是去对线,速度慢可不行呀(滑稽)。果断改变方法,github上搜祖安看能不能找到别人的库</p><p>果然不出所料,找到了这个</p><p><a href="https://github.com/Oohuo/rubbish" target="_blank" rel="noopener">脏话爬取\垃圾话\祖安对线\quicker动作</a></p><p>下载其中的 sql.sql 文件,导入自己的mysql中,语料准备完成。</p><h3 id="用到的功能"><a href="#用到的功能" class="headerlink" title="用到的功能"></a>用到的功能</h3><ol><li>监听键盘快捷键<code>pynput</code></li><li>模拟键盘按键 <code>pykeyboard</code></li><li>多线程 <code>threading</code></li><li>操作剪贴板 <code>pyperclip</code></li></ol><h3 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h3><h4 id="从数据库读数据"><a href="#从数据库读数据" class="headerlink" title="从数据库读数据"></a>从数据库读数据</h4><p>为了减少连接数据库的时间消耗,采用封装的方法一次性连接</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SQL</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line"> user = <span class="string">''</span> <span class="comment"># mysql用户名</span></span><br><span class="line"> password = <span class="string">''</span> <span class="comment"># mysql密码</span></span><br><span class="line"> <span class="comment"># 数据库来源:https://github.com/Oohuo/rubbish/blob/master/sql/sql.sql</span></span><br><span class="line"> self.db = pymysql.connect(<span class="string">'localhost'</span>, user, password, <span class="string">'zanghua'</span>, charset=<span class="string">'utf8'</span>)</span><br><span class="line"> self.cursor = self.db.cursor()</span><br><span class="line"> random.seed(a=<span class="literal">None</span>, version=<span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># name: 被骂人的名字,默认为空</span></span><br><span class="line"> <span class="comment"># id: 指定哪一条,默认为0不指定用随机id</span></span><br><span class="line"> <span class="comment"># level: 1表示口吐莲花,2表示火力全开</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">get_zuan</span><span class="params">(self, name=<span class="string">''</span>, id=<span class="number">0</span>, level=<span class="number">1</span>)</span>:</span></span><br><span class="line"> table = <span class="string">'lajihuamin'</span></span><br><span class="line"> max_id = <span class="number">416</span> <span class="comment"># 口吐莲花416条</span></span><br><span class="line"> <span class="keyword">if</span> level == <span class="number">2</span>:</span><br><span class="line"> table = <span class="string">'lajihuamax'</span></span><br><span class="line"> max_id = <span class="number">690</span> <span class="comment"># 火力全开690条</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> id:</span><br><span class="line"> id = random.randint(<span class="number">1</span>, max_id) <span class="comment"># 不指定,随机id</span></span><br><span class="line"> sql = <span class="string">'select msg from %s where id=%d'</span> % (table, id)</span><br><span class="line"> self.cursor.execute(sql)</span><br><span class="line"> res = self.cursor.fetchall()[<span class="number">0</span>][<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">if</span> name <span class="keyword">is</span> <span class="keyword">not</span> <span class="string">''</span>:</span><br><span class="line"> res = res.replace(<span class="string">'xx'</span>, name) <span class="comment"># 把xx换成名字</span></span><br><span class="line"> res = re.sub(<span class="string">r'^\n'</span>, <span class="string">''</span>, res) <span class="comment"># 去首字符换行</span></span><br><span class="line"> res = re.sub(<span class="string">r'(.*)'</span>, <span class="string">''</span>, res) <span class="comment"># 去除括号</span></span><br><span class="line"> res = re.sub(<span class="string">r'\n$'</span>, <span class="string">''</span>, res) <span class="comment"># 去末尾换行</span></span><br><span class="line"> <span class="keyword">return</span> res</span><br></pre></td></tr></table></figure><h4 id="创建线程"><a href="#创建线程" class="headerlink" title="创建线程"></a>创建线程</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">create_thread</span><span class="params">(target, args=<span class="params">()</span>, thread_num=<span class="number">5</span>)</span>:</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(thread_num):</span><br><span class="line"> t = threading.Thread(target=target, args=args)</span><br><span class="line"> t.start()</span><br></pre></td></tr></table></figure><h4 id="发送消息"><a href="#发送消息" class="headerlink" title="发送消息"></a>发送消息</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">send_zuan</span><span class="params">(sleep_time, name=<span class="string">''</span>, id=<span class="number">0</span>, level=<span class="number">1</span>)</span>:</span></span><br><span class="line"> sql = SQL()</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">send</span><span class="params">()</span>:</span></span><br><span class="line"> res = sql.get_zuan(name=name, id=id, level=level)</span><br><span class="line"> lock.acquire() <span class="comment"># 线程锁,防止剪贴板混乱</span></span><br><span class="line"> pyperclip.copy(res)</span><br><span class="line"> print(res)</span><br><span class="line"> k = PyKeyboard()</span><br><span class="line"> k.press_keys([k.control_r_key, <span class="string">'v'</span>])</span><br><span class="line"> k.press_keys([k.control_r_key, k.enter_key])</span><br><span class="line"> lock.release()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> <span class="keyword">if</span> flag:</span><br><span class="line"> send()</span><br><span class="line"> <span class="keyword">if</span> sleep_time:</span><br><span class="line"> time.sleep(sleep_time)</span><br></pre></td></tr></table></figure><h4 id="监听快捷键(我这里设置的是-左Ctrl-B)"><a href="#监听快捷键(我这里设置的是-左Ctrl-B)" class="headerlink" title="监听快捷键(我这里设置的是 左Ctrl + B)"></a>监听快捷键(我这里设置的是 左<code>Ctrl</code> + <code>B</code>)</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">listening_keykoard</span><span class="params">()</span>:</span></span><br><span class="line"> pressed = set()</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">on_press</span><span class="params">(key)</span>:</span></span><br><span class="line"> pressed.add(key)</span><br><span class="line"> <span class="comment"># print('pressed:', pressed)</span></span><br><span class="line"> <span class="keyword">global</span> flag</span><br><span class="line"> <span class="keyword">if</span> pressed == {keyboard.Key.ctrl_l, keyboard.KeyCode(char=<span class="string">"\x02"</span>)}:</span><br><span class="line"> <span class="keyword">if</span> flag: <span class="comment"># 开启状态按快捷键停止</span></span><br><span class="line"> print(<span class="string">'stop'</span>)</span><br><span class="line"> flag = <span class="number">0</span></span><br><span class="line"> <span class="keyword">else</span>: <span class="comment"># 停止状态按快捷键开始</span></span><br><span class="line"> print(<span class="string">"begin"</span>)</span><br><span class="line"> flag = <span class="number">1</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">on_release</span><span class="params">(key)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> key <span class="keyword">in</span> pressed:</span><br><span class="line"> pressed.remove(key)</span><br><span class="line"></span><br><span class="line"> print(<span class="string">"start up"</span>)</span><br><span class="line"> <span class="keyword">with</span> keyboard.Listener(on_press=on_press, on_release=on_release) <span class="keyword">as</span> listener:</span><br><span class="line"> listener.join()</span><br><span class="line"> print(<span class="string">"shutdown"</span>)</span><br></pre></td></tr></table></figure><h4 id="最后,启动"><a href="#最后,启动" class="headerlink" title="最后,启动"></a>最后,启动</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line"> <span class="comment"># target: 目标函数,不要修改</span></span><br><span class="line"> <span class="comment"># args: </span></span><br><span class="line"> <span class="comment"># 第一个参数 sleep_time 是每个线程内两次发消息的间隔,经过多次尝试,线程太多或者间隔太短都不太行,可能是我电脑不行</span></span><br><span class="line"> <span class="comment"># 第二个参数 name 对方名字</span></span><br><span class="line"> <span class="comment"># 第三个参数 id 不为0时指定固定的一句,为0时随机</span></span><br><span class="line"> <span class="comment"># 第四个参数 level 1级口吐莲花,2级火力全开</span></span><br><span class="line"> <span class="comment"># thread_num: 线程数</span></span><br><span class="line"> create_thread(target=send_zuan, args=(<span class="number">0.1</span>,), thread_num=<span class="number">1</span>)</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># 创建监听快捷键的线程</span></span><br><span class="line"> threading.Thread(target=listening_keykoard).start()</span><br></pre></td></tr></table></figure><h3 id="github-项目地址:"><a href="#github-项目地址:" class="headerlink" title="github 项目地址:"></a>github 项目地址:</h3><p><strong><a href="https://github.com/Roc136/zuan" target="_blank" rel="noopener">https://github.com/Roc136/zuan</a></strong></p><p><strong>欢迎star~</strong></p><h3 id="展示:"><a href="#展示:" class="headerlink" title="展示:"></a>展示:</h3><p><video src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/zuan/zuan.mp4" controls="controls" style="max-width: 100%; display: block; margin-left: auto; margin-right: auto;"> your browser does not support the video tag </video></p><h3 id="结语:"><a href="#结语:" class="headerlink" title="结语:"></a>结语:</h3><p>当然最后没有和对方对线,毕竟狗咬咱一口咱没必要还一口~</p><p>写这个纯属娱乐和学习新知识,但是祖安可不好哦~</p>]]></content>
<categories>
<category> 乱七八糟 </category>
</categories>
<tags>
<tag> 祖安神器 </tag>
</tags>
</entry>
<entry>
<title>深入理解计算机系统作业四</title>
<link href="/posts/csapp/homework4/"/>
<url>/posts/csapp/homework4/</url>
<content type="html"><![CDATA[<h1 id="作业4"><a href="#作业4" class="headerlink" title="作业4"></a>作业4</h1><h3 id="3-24"><a href="#3-24" class="headerlink" title="3.24"></a>3.24</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">lopp_while</span><span class="params">(<span class="keyword">long</span> a, <span class="keyword">long</span> b)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">long</span> result = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span> (a < b) {</span><br><span class="line"> result = result * (a + b);</span><br><span class="line"> a = a + <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-25"><a href="#3-25" class="headerlink" title="3.25"></a>3.25</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">loop_while2</span><span class="params">(<span class="keyword">long</span> a, <span class="keyword">long</span> b)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">long</span> result = b;</span><br><span class="line"> <span class="keyword">while</span> (b > <span class="number">0</span>) {</span><br><span class="line"> result = result * a;</span><br><span class="line"> b = b - a</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-28"><a href="#3-28" class="headerlink" title="3.28"></a>3.28</h3><p>A. </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">fun_b</span><span class="params">(<span class="keyword">unsigned</span> <span class="keyword">long</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">long</span> val = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">long</span> i;</span><br><span class="line"> <span class="keyword">for</span>(i = <span class="number">64</span>; i != <span class="number">0</span>; i--) {</span><br><span class="line"> val <<= <span class="number">1</span>;</span><br><span class="line"> val |= (x & <span class="number">1</span>);</span><br><span class="line"> x >>= <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> val;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>B. <code>i</code> 的初始值为64,一定满足 <code>i != 0</code> ,所以不必测试</p><p>C. 将 x 的各位做对称变换存在 val 中</p><h3 id="3-30"><a href="#3-30" class="headerlink" title="3.30"></a>3.30</h3><p>A. -1 0 1 2 4 5 7<br>B. .L5 的标号为0和7</p><p>C. .L7 的标号为2和4</p><h3 id="3-31"><a href="#3-31" class="headerlink" title="3.31"></a>3.31</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">switcher</span><span class="params">(<span class="keyword">long</span> a, <span class="keyword">long</span> b, <span class="keyword">long</span> c, <span class="keyword">long</span> *dest)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">long</span> val;</span><br><span class="line"> <span class="keyword">switch</span>(a) { <span class="comment">/*0 2 4 5 7*/</span></span><br><span class="line"> <span class="keyword">case</span> <span class="number">5</span>: <span class="comment">/* Case A */</span></span><br><span class="line"> c = b ^ <span class="number">15</span>;</span><br><span class="line"> <span class="comment">/* Fall through */</span></span><br><span class="line"> <span class="keyword">case</span> <span class="number">0</span>: <span class="comment">/* Case B */</span></span><br><span class="line"> val = c + <span class="number">112</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">2</span>: <span class="comment">/* Case C */</span></span><br><span class="line"> <span class="keyword">case</span> <span class="number">7</span>: <span class="comment">/* Case D */</span></span><br><span class="line"> val = (b + c) << <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">4</span>: <span class="comment">/* Case E */</span></span><br><span class="line"> val = a;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> val = b;</span><br><span class="line"> }</span><br><span class="line"> *dest = val;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-64"><a href="#3-64" class="headerlink" title="3.64"></a>3.64</h3><p>A. </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">TYPE D[R][S][T]</span><br><span class="line">&D[i][j][k] = Xd + L(S*T*i + T*j + k)</span><br></pre></td></tr></table></figure><p>B.</p><p>R = 7</p><p>S = 5</p><p>T = 13</p><h3 id="3-67"><a href="#3-67" class="headerlink" title="3.67"></a>3.67</h3><p>A. </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">104 +------------------+</span><br><span class="line"> | |</span><br><span class="line"> · ·</span><br><span class="line"> · ·</span><br><span class="line"> · ·</span><br><span class="line"> | |</span><br><span class="line"> 64 +------------------+ <-- %rdi</span><br><span class="line"> | |</span><br><span class="line"> 56 +------------------+</span><br><span class="line"> | |</span><br><span class="line"> 48 +------------------+</span><br><span class="line"> | |</span><br><span class="line"> 40 +------------------+</span><br><span class="line"> | |</span><br><span class="line"> 32 +------------------+</span><br><span class="line"> | z |</span><br><span class="line"> 24 +------------------+</span><br><span class="line"> | &z |</span><br><span class="line"> 16 +------------------+</span><br><span class="line"> | y |</span><br><span class="line"> 8 +------------------+</span><br><span class="line"> | x |</span><br><span class="line"> 0 +------------------+ <-- %rsp</span><br></pre></td></tr></table></figure><p>B. %rsp+64</p><p>C. 使用 <code>%rsp</code> 加偏移量的方式访问元素</p><p>D. 从参数 <code>%res+64</code> 开始存放 r 的字段</p><p>E.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">104 +------------------+</span><br><span class="line"> | |</span><br><span class="line"> · ·</span><br><span class="line"> · ·</span><br><span class="line"> · ·</span><br><span class="line"> | |</span><br><span class="line"> 88 +------------------+</span><br><span class="line"> | z |</span><br><span class="line"> 80 +------------------+</span><br><span class="line"> | x |</span><br><span class="line"> 72 +------------------+</span><br><span class="line"> | y |</span><br><span class="line"> 64 +------------------+ <-- %rdi(eval传递的)(%rax(process返回的))</span><br><span class="line"> | |</span><br><span class="line"> 56 +------------------+</span><br><span class="line"> | |</span><br><span class="line"> 48 +------------------+</span><br><span class="line"> | |</span><br><span class="line"> 40 +------------------+</span><br><span class="line"> | |</span><br><span class="line"> 32 +------------------+</span><br><span class="line"> | z |</span><br><span class="line"> 24 +------------------+</span><br><span class="line"> | &z |</span><br><span class="line"> 16 +------------------+</span><br><span class="line"> | y |</span><br><span class="line"> 8 +------------------+</span><br><span class="line"> | x |</span><br><span class="line"> 0 +------------------+ <-- %rsp(eval函数)</span><br><span class="line"> | |</span><br><span class="line"> -8 +------------------+ <-- %rsp(process函数内)</span><br></pre></td></tr></table></figure><p>F. 原函数将空间的地址作为参数传给被调用的函数,被调用的函数将数据存放在给定的空间内,返回该空间地址。</p><h3 id="3-68"><a href="#3-68" class="headerlink" title="3.68"></a>3.68</h3><p>由 <code>8(%rsi)</code> 指向 <code>q->t</code> 可知,4 < B <= 8;</p><p>又由 <code>32(%rsi)</code> 指向 <code>q->u</code> 知,24 < 8 + 4 + A * 2 <= 32,即 5 < A <= 10</p><p>又 <code>184(%rdi)</code> 指向 <code>p->y</code> 知,176 < A*B*4 <= 184,即 44 < A*B <= 46</p><p>可得</p><p>A = 9</p><p>B = 5</p>]]></content>
<categories>
<category> 作业 </category>
<category> 深入理解计算机系统 </category>
</categories>
<tags>
<tag> 深入理解计算机系统 </tag>
</tags>
</entry>
<entry>
<title>深入理解计算机系统作业三</title>
<link href="/posts/csapp/homework3/"/>
<url>/posts/csapp/homework3/</url>
<content type="html"><![CDATA[<h1 id="作业3"><a href="#作业3" class="headerlink" title="作业3"></a>作业3</h1><h3 id="3-3"><a href="#3-3" class="headerlink" title="3.3"></a>3.3</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">movb $0xF, (ebx) # %ebx是调用者保存的信息,不能用 %ebx 作为目标地址</span><br><span class="line">movl %rax, (%rap) # 指令后缀与寄存器不匹配,应为movl %eax, (%rsp) 或 movq %rax, (%rsp)</span><br><span class="line">movw (%rax), 4(%rsp) # 的两个操作数不能同时为内存引用</span><br><span class="line">movb %al, %sl # %sl不存在</span><br><span class="line">movq %rax, $0x123 # 不能用立即数作为目标地址</span><br><span class="line">movl %eax, %rdx # 应为 movl %eax, %edx</span><br><span class="line">movb %si, 8(%rbp) # 指令后缀与寄存器不匹配,应为movb %sil, 8(%rbp) 或者 movw %si, 8(%rbp)</span><br></pre></td></tr></table></figure><h3 id="3-5"><a href="#3-5" class="headerlink" title="3.5"></a>3.5</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">decode1</span><span class="params">(<span class="keyword">long</span> *xp, <span class="keyword">long</span> *yp, <span class="keyword">long</span> *zp)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">long</span> x = *xp;</span><br><span class="line"> <span class="keyword">long</span> y = *yp;</span><br><span class="line"> <span class="keyword">long</span> z = *zp;</span><br><span class="line"> *yp = x;</span><br><span class="line"> *zp = y;</span><br><span class="line"> *xp = z;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-7"><a href="#3-7" class="headerlink" title="3.7"></a>3.7</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">long</span> t = <span class="number">5</span> * x + <span class="number">2</span> * y + <span class="number">8</span> * z</span><br></pre></td></tr></table></figure><h3 id="3-10"><a href="#3-10" class="headerlink" title="3.10"></a>3.10</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">arith2</span><span class="params">(<span class="keyword">long</span> x, <span class="keyword">long</span> y, <span class="keyword">long</span> z)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">long</span> t1 = x | y;</span><br><span class="line"> <span class="keyword">long</span> t2 = t1 >> <span class="number">3</span>;</span><br><span class="line"> <span class="keyword">long</span> t3 = ~t2;</span><br><span class="line"> <span class="keyword">long</span> t4 = z - t3;</span><br><span class="line"> <span class="keyword">return</span> t4;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-15"><a href="#3-15" class="headerlink" title="3.15"></a>3.15</h3><p>A. <code>0x4003fe</code></p><p>B. <code>0x400425</code></p><p>C. <code>400543</code> <code>400545</code></p><p>D. <code>0x400560</code></p><h3 id="3-18"><a href="#3-18" class="headerlink" title="3.18"></a>3.18</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">test</span><span class="params">(<span class="keyword">long</span> x, <span class="keyword">long</span> y, <span class="keyword">long</span> z)</span> </span>{</span><br><span class="line"> <span class="keyword">long</span> val = x + y + z;</span><br><span class="line"> <span class="keyword">if</span> (x < <span class="number">-3</span>) {</span><br><span class="line"> <span class="keyword">if</span> (y < z)</span><br><span class="line"> val = x * y;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> val = y * z;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (x > <span class="number">2</span>)</span><br><span class="line"> val = x * z;</span><br><span class="line"> <span class="keyword">return</span> val;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-21"><a href="#3-21" class="headerlink" title="3.21"></a>3.21</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">test</span><span class="params">(<span class="keyword">long</span> x, <span class="keyword">long</span> y)</span> </span>{</span><br><span class="line"> <span class="keyword">long</span> val = <span class="number">8</span> * x + <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span> (y > <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">if</span> (x < y)</span><br><span class="line"> val = y - x;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> val = x & y;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (y <= <span class="number">-2</span>)</span><br><span class="line"> val = x + y;</span><br><span class="line"> <span class="keyword">return</span> val;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-60"><a href="#3-60" class="headerlink" title="3.60"></a>3.60</h3><p>A. <code>%rdi</code>, <code>%esi</code>, <code>%rax</code>, <code>%rdx</code></p><p>B. <code>result = 0; mask = 1;</code></p><p>C. <code>mask != 0</code></p><p>D. <code>mask <<= n</code></p><p>E. <code>result |= (x & mask)</code></p><p>F.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">loop</span><span class="params">(<span class="keyword">long</span> x, <span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">long</span> result = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">long</span> mask;</span><br><span class="line"> <span class="keyword">for</span>(mask = <span class="number">1</span>; mask != <span class="number">0</span>; mask <<= n) {</span><br><span class="line"> result |= (x & mask)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-61"><a href="#3-61" class="headerlink" title="3.61"></a>3.61</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">long</span> <span class="title">cread_alt</span><span class="params">(<span class="keyword">long</span> *xp)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> (!xp ? <span class="number">0</span> : *xp);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 作业 </category>
<category> 深入理解计算机系统 </category>
</categories>
<tags>
<tag> 深入理解计算机系统 </tag>
</tags>
</entry>
<entry>
<title>gdb调试命令</title>
<link href="/posts/notes/gdb/"/>
<url>/posts/notes/gdb/</url>
<content type="html"><![CDATA[<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">layout regs //打开寄存器窗口</span><br><span class="line">layout asm //打开汇编代码窗口</span><br><span class="line">disassemble //查看汇编代码</span><br><span class="line">set disassemble-next-line on //可以查看下一条指令的汇编代码</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">查看当前程序栈的内容: x/10x $sp-->打印stack的前10个元素</span><br><span class="line">查看当前程序栈的信息: info frame----list general info about the frame</span><br><span class="line">查看当前程序栈的参数: info args---lists arguments to the function</span><br><span class="line">查看当前程序栈的局部变量: info locals---list variables stored in the frame</span><br><span class="line">查看当前寄存器的值:info registers(不包括浮点寄存器) info all-registers(包括浮点寄存器)</span><br><span class="line">查看当前栈帧中的异常处理器:info catch(exception handlers)</span><br></pre></td></tr></table></figure><p>待补充…</p>]]></content>
<categories>
<category> 笔记 </category>
<category> 汇编 </category>
</categories>
<tags>
<tag> gdb </tag>
</tags>
</entry>
<entry>
<title>深入理解计算机系统作业二</title>
<link href="/posts/csapp/homework2/"/>
<url>/posts/csapp/homework2/</url>
<content type="html"><![CDATA[<h1 id="作业2"><a href="#作业2" class="headerlink" title="作业2"></a>作业2</h1><h3 id="2-61"><a href="#2-61" class="headerlink" title="2.61"></a>2.61</h3><p>A. <code>!(~x)</code></p><p>B. <code>!x</code></p><p>C. <code>!(~(x|0xffffff00))</code></p><p>D. <code>!(~(x|0x00ffffff))</code></p><h3 id="2-63"><a href="#2-63" class="headerlink" title="2.63"></a>2.63</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*逻辑右移与算术右移只有当最高位为1时不同*/</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">unsigned</span> <span class="title">srl</span><span class="params">(<span class="keyword">unsigned</span> x,<span class="keyword">int</span> k)</span></span>{</span><br><span class="line"><span class="comment">/* Perform shift arithmetically */</span></span><br><span class="line"><span class="keyword">unsigned</span> xsra=(<span class="keyword">int</span>)x>>k;</span><br><span class="line"> </span><br><span class="line"> <span class="comment">/* 得到位数 */</span></span><br><span class="line"><span class="keyword">int</span> w=<span class="keyword">sizeof</span>(<span class="keyword">int</span>)<<<span class="number">3</span>;</span><br><span class="line"> <span class="comment">/*如果最高位是1,就把前 k 位与1进行异或操作*/</span></span><br><span class="line"><span class="keyword">if</span>(x&<span class="number">0x80000000</span>)</span><br><span class="line"> xsra^=(<span class="number">-1</span>)<<(w-k); <span class="comment">//利用(-1)<<(w-k) 得到前 k 位均为1的数</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> xsra;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">sra</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> k)</span></span>{</span><br><span class="line"><span class="comment">/* Perform shift logically */</span></span><br><span class="line"><span class="keyword">int</span> xshl=(<span class="keyword">unsigned</span>)x>>k;</span><br><span class="line"> </span><br><span class="line"> <span class="comment">/* 得到位数 */</span></span><br><span class="line"><span class="keyword">int</span> w=<span class="keyword">sizeof</span>(<span class="keyword">int</span>)<<<span class="number">3</span>;</span><br><span class="line"> <span class="comment">/*如果最高位是1,就把前(w-k)位与1进行或操作*/</span></span><br><span class="line"><span class="keyword">if</span>(x&<span class="number">0x80000000</span>)</span><br><span class="line"> xshl|=(<span class="number">-1</span>)<<(w-k);</span><br><span class="line"> </span><br><span class="line"><span class="keyword">return</span> xshl;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="2-65"><a href="#2-65" class="headerlink" title="2.65"></a>2.65</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* Return 1 when x contains an odd number of 1s; 0 otherwise.</span></span><br><span class="line"><span class="comment"> Assune w=32 */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/***************************************************************</span></span><br><span class="line"><span class="comment"> * 在所有的1中去掉偶数个1对结果不会产生影响,所以将32位依次折半前半部分与后 *</span></span><br><span class="line"><span class="comment"> * 半部分进行异或可以去除偶数个1,循环进行直到最后一位,如果最后一位是1则是 *</span></span><br><span class="line"><span class="comment"> * 奇数,为0则是偶数。 *</span></span><br><span class="line"><span class="comment"> ***************************************************************/</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">odd_ones</span><span class="params">(<span class="keyword">unsigned</span> x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">unsigned</span> y;</span><br><span class="line"> <span class="keyword">unsigned</span> w = <span class="number">16</span>;</span><br><span class="line"> <span class="keyword">for</span>(;w >= <span class="number">1</span>; w >>= <span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> y = x >> w;</span><br><span class="line"> x ^= y;</span><br><span class="line"> }</span><br><span class="line"><span class="keyword">return</span> x & <span class="number">1</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="2-71"><a href="#2-71" class="headerlink" title="2.71"></a>2.71</h3><p>A. packed_t是无符号数,而它包装的4个字节都是有符号数,1byte的包装在无符号数中的有符号数扩展后符号位并没有扩展。</p><p>B.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">xbyte</span><span class="params">(<span class="keyword">packed_t</span> <span class="keyword">word</span>, <span class="keyword">int</span> byteum)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">size</span> = <span class="keyword">sizeof</span>(<span class="keyword">unsigned</span>);</span><br><span class="line"> <span class="keyword">int</span> left = (<span class="built_in">size</span> - <span class="number">1</span> - bytenum) << <span class="number">3</span>;</span><br><span class="line"> <span class="keyword">int</span> right = (<span class="built_in">size</span> - <span class="number">1</span>) << <span class="number">3</span>;</span><br><span class="line"> <span class="keyword">return</span> (<span class="keyword">int</span>) <span class="keyword">word</span> << left >> right;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="2-72"><a href="#2-72" class="headerlink" title="2.72"></a>2.72</h3><p>A. <code>sizeof</code> 的返回值 <code>size_t</code> 是无符号类型,在做减法 <code>maxbytes-sizeof(val)</code> 时得到的结果被提升为无符号型,总是大于0.</p><p>B. </p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">copy_int</span><span class="params">(<span class="keyword">int</span> val, <span class="keyword">void</span>* buf, <span class="keyword">int</span> maxbytes)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(maxbytes >= (<span class="keyword">int</span>)<span class="keyword">sizeof</span>(val))</span><br><span class="line"> <span class="built_in">memcpy</span>(buf, (<span class="keyword">void</span>*)&val, <span class="keyword">sizeof</span>(val));</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="2-77"><a href="#2-77" class="headerlink" title="2.77"></a>2.77</h3><p>A. <code>(x << 4) + x</code></p><p>B. <code>-(x << 3 - x)</code></p><p>C. <code>(x << 6) - (x << 2)</code></p><p>D. <code>(x << 4) - (x << 7)</code></p><h3 id="2-87"><a href="#2-87" class="headerlink" title="2.87"></a>2.87</h3><table><thead><tr><th>描述</th><th align="center">Hex</th><th align="center">M</th><th align="center">E</th><th align="center">V</th><th align="center">D</th></tr></thead><tbody><tr><td>-0</td><td align="center"><strong>8000</strong></td><td align="center"><strong>0</strong></td><td align="center"><strong>-14</strong></td><td align="center">-0</td><td align="center">-0.0</td></tr><tr><td>最小的 $>2$ 的值</td><td align="center"><strong>4001</strong></td><td align="center"><strong>$\frac{1025}{1024}$</strong></td><td align="center"><strong>1</strong></td><td align="center"><strong>$\frac{1025}{512}$</strong></td><td align="center"><strong>2.00195312</strong></td></tr><tr><td>512</td><td align="center"><strong>6000</strong></td><td align="center"><strong>1</strong></td><td align="center"><strong>9</strong></td><td align="center">512</td><td align="center">512.0</td></tr><tr><td>最大的非规格化数</td><td align="center"><strong>03FF</strong></td><td align="center"><strong>$\frac{1023}{1024}$</strong></td><td align="center"><strong>-14</strong></td><td align="center"><strong>$\frac{1023}{2^{24}}$</strong></td><td align="center"><strong>6.09755516e-5</strong></td></tr><tr><td>$-\infty$</td><td align="center"><strong>FC00</strong></td><td align="center">—</td><td align="center">—</td><td align="center">$-\infty$</td><td align="center">$-\infty$</td></tr><tr><td>十六进制表示为3BB0的数</td><td align="center">3BB0</td><td align="center"><strong>$\frac{123}{64}$</strong></td><td align="center"><strong>-1</strong></td><td align="center"><strong>$\frac{123}{128}$</strong></td><td align="center"><strong>0.9609375</strong></td></tr></tbody></table><h3 id="2-90"><a href="#2-90" class="headerlink" title="2.90"></a>2.90</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><assert.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><math.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">float</span> <span class="title">u2f</span><span class="params">(<span class="keyword">unsigned</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> *(<span class="keyword">float</span>*) &x;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">float</span> <span class="title">fpwr2</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="comment">/* Result exponent and fraction */</span></span><br><span class="line"> <span class="keyword">unsigned</span> <span class="built_in">exp</span>, frac;</span><br><span class="line"> <span class="keyword">unsigned</span> u;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (x < <span class="number">2</span>-<span class="built_in">pow</span>(<span class="number">2</span>,<span class="number">7</span>)<span class="number">-23</span>) {</span><br><span class="line"> <span class="comment">/* Too small. Return 0.0 */</span></span><br><span class="line"> <span class="built_in">exp</span> = <span class="number">0</span>;</span><br><span class="line"> frac = <span class="number">0</span>;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (x < <span class="number">2</span>-<span class="built_in">pow</span>(<span class="number">2</span>,<span class="number">7</span>)) {</span><br><span class="line"> <span class="comment">/* Denormalized result */</span></span><br><span class="line"> <span class="comment">/* 非规格化表示,阶码编码全为0,E=1-Bias(Bias = 2 ^ (k - 1) - 1);</span></span><br><span class="line"><span class="comment"> * 最小值0.000(23个0)001 * 2 ^ E = 2 ^ (2 - 2 ^ 7); */</span></span><br><span class="line"> <span class="built_in">exp</span> = <span class="number">0</span>;</span><br><span class="line"> frac = <span class="number">1</span> << (<span class="keyword">unsigned</span>)(x - (<span class="number">2</span>-<span class="built_in">pow</span>(<span class="number">2</span>,<span class="number">7</span>)<span class="number">-23</span>));</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (x < <span class="built_in">pow</span>(<span class="number">2</span>,<span class="number">7</span>)<span class="number">-1</span>+<span class="number">1</span>) {</span><br><span class="line"> <span class="comment">/* Normalized result */</span></span><br><span class="line"> <span class="comment">/* 规格化表示,最小值1.00...00 * 2 ^ (1 - (2 ^ 7 - 1)) = 2 ^ (2 - 2 ^ 7)</span></span><br><span class="line"><span class="comment"> 最大值1.00...00 * 2 ^ ((2^8-1) - (2^7-1)) = 2 ^ 2 ^ 7*/</span></span><br><span class="line"> <span class="built_in">exp</span> = <span class="built_in">pow</span>(<span class="number">2</span>,<span class="number">7</span>)<span class="number">-1</span>+x;</span><br><span class="line"> frac = <span class="number">0</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">/* Too big, Return +oo */</span></span><br><span class="line"> <span class="built_in">exp</span> = <span class="number">0xFF</span>;</span><br><span class="line"> frac = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* Pack exp and frac into 32 bits */</span></span><br><span class="line"> u = <span class="built_in">exp</span> << <span class="number">23</span> | frac;</span><br><span class="line"> <span class="comment">/* Return as float */</span></span><br><span class="line"> <span class="keyword">return</span> u2f(u);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 作业 </category>
<category> 深入理解计算机系统 </category>
</categories>
<tags>
<tag> 深入理解计算机系统 </tag>
</tags>
</entry>
<entry>
<title>Hexo+Next+GitHub博客搭建超详细教程--补充篇</title>
<link href="/posts/blog-building/end/"/>
<url>/posts/blog-building/end/</url>
<content type="html"><![CDATA[<h2 id="结语:"><a href="#结语:" class="headerlink" title="结语:"></a>结语:</h2><p>博客搭建的教程就到此结束了,但我后面还会对博客进行修改而可能不会更新教程,对于我的博客上的任何东西,可以在评论区向我提问,如果我会做的话,就会更新到这篇补充内容里面。感谢大家的阅读~</p><a id="more"></a><hr><h2 id="补充内容:"><a href="#补充内容:" class="headerlink" title="补充内容:"></a>补充内容:</h2><p>暂无</p>]]></content>
<categories>
<category> blog </category>
<category> 4.补充 </category>
</categories>
<tags>
<tag> blog </tag>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>Hexo+Next+GitHub博客搭建超详细教程--提升篇(2)</title>
<link href="/posts/blog-building/high-2/"/>
<url>/posts/blog-building/high-2/</url>
<content type="html"><![CDATA[<h3 id="一、添加热度"><a href="#一、添加热度" class="headerlink" title="一、添加热度"></a>一、添加热度</h3><p>打开<strong>主题配置文件</strong>,查找 <code>leancloud_visitors</code> ,修改 <code>enable</code> 为 <code>true</code> ,自行添加 <code>app_id</code> 和 <code>app_key</code> (和评论使用的leancloud相同)</p><p>打开 <code>./themes/next/layout/_macro/post.swig</code> 文件,查找 <code>leancloud</code></p><p>找到如下内容</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">{% if theme.leancloud_visitors.enable %}</span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">id</span>=<span class="string">"{{ url_for(post.path) }}"</span> <span class="attr">class</span>=<span class="string">"leancloud_visitors"</span> <span class="attr">data-flag-title</span>=<span class="string">"{{ post.title }}"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"post-meta-divider"</span>></span>|<span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"post-meta-item-icon"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"fa fa-eye"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> {% if theme.post_meta.item_text %}</span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"post-meta-item-text"</span>></span>{{__('post.visitors')}}<span class="symbol">&#58;</span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"leancloud-visitors-count"</span>></span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">span</span>></span></span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><p>在 <code><span class="leancloud-visitors-count"></span></code> 下面添加 <code><span>°C</span></code></p><p>打开语言文件 <code>./themes/next/languages/zh-Hans.yml</code> 文件,查找 <code>post</code></p><p>将 <code>visitors</code> 的值改为 <code>热度</code> 即可。</p><p>注:如果使用其他语言就对应修改其他的语言文件。</p><h3 id="二、添加文章字数统计、阅读时长"><a href="#二、添加文章字数统计、阅读时长" class="headerlink" title="二、添加文章字数统计、阅读时长"></a>二、添加文章字数统计、阅读时长</h3><p><del>在博客根目录运行cmd,执行</del></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install hexo-wordcount --save</span><br></pre></td></tr></table></figure><p>打开<strong>主题配置文件</strong>,查找 <code>post_wordcount</code> 修改以下内容</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Post wordcount display settings</span></span><br><span class="line"><span class="comment"># Dependencies: https://github.com/willin/hexo-wordcount</span></span><br><span class="line"><span class="attr">post_wordcount:</span></span><br><span class="line"> <span class="attr">item_text:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">wordcount:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">min2read:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> blog </category>
<category> 3.提升 </category>
</categories>
<tags>
<tag> blog </tag>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>Hexo+Next+GitHub博客搭建超详细教程--提升篇(1)</title>
<link href="/posts/blog-building/high-1/"/>
<url>/posts/blog-building/high-1/</url>
<content type="html"><![CDATA[<h3 id="一、添加评论"><a href="#一、添加评论" class="headerlink" title="一、添加评论"></a>一、添加评论</h3><h4 id="1-注册leancloud"><a href="#1-注册leancloud" class="headerlink" title="1. 注册leancloud"></a>1. 注册leancloud</h4><p>在 <a href="https://www.leancloud.cn/" target="_blank" rel="noopener">leancloud</a> 上注册账号,新建应用,选择开发版,应用名称随意。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/high-1/create_app.png" alt=""></p><p>打开应用,在 <code>存储</code> 的 <code>结构化数据</code> 点击 <code>创建Class</code> 。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/high-1/create_clsss.png" alt=""></p><p>输入名字为 <code>Comment</code></p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/high-1/create_class_2.png" alt=""></p><p>再创建一个名字为 <code>Counter</code> Class(后面做文章阅读量统计用)</p><p>点击设置-安全中心,找到 <code>Web安全域名</code> ,添加自己的博客地址。</p><p>点击 <code>应用Keys</code> ,复制其中的 <code>appid</code> 和 <code>appkey</code> 备用。</p><h4 id="2-添加到博客"><a href="#2-添加到博客" class="headerlink" title="2. 添加到博客"></a>2. 添加到博客</h4><p>打开<strong>主题配置文件</strong>,查找 <code>valine</code> ,将内容替换为以下内容,其中 <code>appid</code> 和 <code>appkey</code> 填入自己的。</p><p>master为自己的邮箱地址的md5值,点击这里<a href="https://md5jiami.51240.com/" target="_blank" rel="noopener">在线获取md5</a></p><p>(部分配置目前不生效,在后续的修改中会逐渐生效)</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Valine.</span></span><br><span class="line"><span class="comment"># You can get your appid and appkey from https://leancloud.cn</span></span><br><span class="line"><span class="comment"># more info please open https://valine.js.org</span></span><br><span class="line"><span class="attr">valine:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">appid:</span> <span class="comment"># your appid</span></span><br><span class="line"> <span class="attr">appkey:</span> <span class="comment"># your appkey</span></span><br><span class="line"> <span class="attr">notify:</span> <span class="literal">true</span> <span class="comment"># mail notifier , https://github.com/xCss/Valine/wiki</span></span><br><span class="line"> <span class="attr">verify:</span> <span class="literal">false</span> <span class="comment"># Verification code</span></span><br><span class="line"> <span class="attr">placeholder:</span> <span class="string">ヾノ≧∀≦)o来啊,快活啊!\nTips:\n1.这里可以支持Markdown语法哦~\n2.请尽量使用主流邮件地址,例如QQ、网易、谷歌等等,使用不常见的邮箱地址(例如@cr.cx)可能收不到回复通知哦~\n3.使用QQ邮箱可以自动获取QQ头像~</span> <span class="comment"># comment box placeholder</span></span><br><span class="line"> <span class="attr">avatar:</span> <span class="string">monsterid</span> <span class="comment"># gravatar style</span></span><br><span class="line"> <span class="attr">guest_info:</span> <span class="string">nick,mail,link</span> <span class="comment"># custom comment header</span></span><br><span class="line"> <span class="attr">pageSize:</span> <span class="number">10</span> <span class="comment"># pagination size</span></span><br><span class="line"> <span class="attr">master:</span> <span class="string">["your</span> <span class="string">email(md5)"]</span></span><br><span class="line"> <span class="attr">friends:</span> <span class="string">["your</span> <span class="string">friend's</span> <span class="string">email(md5)",</span> <span class="string">"your friend's email(md5)"</span><span class="string">]</span></span><br><span class="line"> <span class="attr">tagMeta_master:</span> <span class="string">"博主"</span></span><br><span class="line"> <span class="attr">tagMeta_friends:</span> <span class="string">"小伙伴"</span></span><br><span class="line"> <span class="attr">tagMeta_visters:</span> <span class="string">"访客"</span></span><br><span class="line"> <span class="attr">enableQQ:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h4 id="3-修改评论区样式"><a href="#3-修改评论区样式" class="headerlink" title="3. 修改评论区样式"></a>3. 修改评论区样式</h4><p>打开 <code>./themes/next/source/css/_custom/custom.styl</code> 文件,在末尾添加以下内容</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//评论区卡片样式</span></span><br><span class="line"><span class="selector-class">.comments</span> <span class="selector-class">.vcards</span> <span class="selector-class">.vcard</span> {</span><br><span class="line"><span class="attribute">padding</span>: <span class="number">15px</span> <span class="number">20px</span> <span class="number">0</span> <span class="number">20px</span>;</span><br><span class="line"><span class="attribute">border-radius</span>: <span class="number">10px</span>;</span><br><span class="line"><span class="attribute">margin-bottom</span>: <span class="number">15px</span>;</span><br><span class="line">box-shadow: 0 0 4px 1px rgba(0, 0, 0, .12);</span><br><span class="line">transition: all .3s</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.comments</span> <span class="selector-class">.vcards</span> <span class="selector-class">.vcard</span>:hover {</span><br><span class="line">box-shadow: 0 0 8px 3px rgba(0, 0, 0, .12)</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.comments</span> <span class="selector-class">.vcards</span> <span class="selector-class">.vcard</span> <span class="selector-class">.vh</span> <span class="selector-class">.vcard</span> {</span><br><span class="line"><span class="attribute">border</span>: none;</span><br><span class="line"><span class="attribute">box-shadow</span>: none;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//评论头像旋转</span></span><br><span class="line"><span class="selector-tag">img</span><span class="selector-class">.vimg</span> {</span><br><span class="line"> <span class="attribute">transition</span>: all <span class="number">1.5s</span> <span class="comment">/* 旋转时间为 1s */</span></span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">img</span><span class="selector-class">.vimg</span>:hover {</span><br><span class="line"> <span class="attribute">transform</span>: rotate(<span class="number">360deg</span>);</span><br><span class="line"> -webkit-<span class="attribute">transform</span>: rotate(<span class="number">360deg</span>);</span><br><span class="line"> -moz-<span class="attribute">transform</span>: rotate(<span class="number">360deg</span>);</span><br><span class="line"> -o-<span class="attribute">transform</span>: rotate(<span class="number">360deg</span>);</span><br><span class="line"> -ms-<span class="attribute">transform</span>: rotate(<span class="number">360deg</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="4-添加背景图"><a href="#4-添加背景图" class="headerlink" title="4. 添加背景图"></a>4. 添加背景图</h4><p>仍然是 <code>custom.styl</code> 文件,在末尾添加</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-id">#veditor</span> {</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">300px</span>;</span><br><span class="line">background-image: url(https://cdn.jsdelivr.net/gh/drew233/cdn/20200409110727.webp);</span><br><span class="line"><span class="comment">// background-size: contain;</span></span><br><span class="line"><span class="attribute">background-repeat</span>: no-repeat;</span><br><span class="line"><span class="attribute">background-position</span>: bottom right;</span><br><span class="line"><span class="attribute">background-color</span>: rgba(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>, <span class="number">0</span>);</span><br><span class="line"><span class="attribute">resize</span>: vertical</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>获取焦点时背景图消失:</p><p>添加</p><figure class="highlight styl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-id">#veditor</span>:focus{</span><br><span class="line"><span class="attribute">background-position</span>-y: <span class="number">10000px</span>;</span><br><span class="line"><span class="attribute">transition</span>: all <span class="number">5s</span> ease-in-out <span class="number">0s</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="5-添加博主、小伙伴和浏览器标识"><a href="#5-添加博主、小伙伴和浏览器标识" class="headerlink" title="5. 添加博主、小伙伴和浏览器标识"></a>5. 添加博主、小伙伴和浏览器标识</h4><p>这个功能需要修改原生的js文件,使用魔改的js。与原生的js相比,增加以下功能</p><ol><li>添加博主,小伙伴,访客标签</li><li>添加浏览器和操作系统图标,需引入 <code>fontawesome v5.0+</code> 的 CSS 样式</li><li>邮箱检测更严格</li><li>增加 QQ 邮箱识别(原版只能通过昵称栏输入 QQ 号识别)</li><li>meta placeholder 可自定义</li></ol><p>点击 <a href="https://cdn.jsdelivr.net/gh/HCLonely/Valine@latest/dist/Valine.min.js" target="_blank" rel="noopener">魔改的valine.min.js</a> 将其保存在 <code>./themes/next/source/js/src</code> 文件夹下。</p><p>打开 <code>./themes/next/layout/_third-party/comments/valine.swig</code> 文件,修改其中的</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><script src=<span class="string">"//unpkg.com/valine/dist/Valine.min.js"</span>><<span class="regexp">/script></span></span><br></pre></td></tr></table></figure><p>为</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><script src=<span class="string">"/js/src/Valine.min.js"</span>><<span class="regexp">/script></span></span><br></pre></td></tr></table></figure><p>将其中的 <code>new Valine</code> (一整段)修改为</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> Valine({</span><br><span class="line"> el: <span class="string">'#comments'</span> ,</span><br><span class="line"> verify: {{ theme.valine.verify }},</span><br><span class="line"> notify: {{ theme.valine.notify }},</span><br><span class="line"> appId: <span class="string">'{{ theme.valine.appid }}'</span>,</span><br><span class="line"> appKey: <span class="string">'{{ theme.valine.appkey }}'</span>,</span><br><span class="line"> placeholder: <span class="string">'{{ theme.valine.placeholder }}'</span>,</span><br><span class="line"> avatar:<span class="string">'{{ theme.valine.avatar }}'</span>,</span><br><span class="line"> guest_info:guest,</span><br><span class="line"> pageSize:<span class="string">'{{ theme.valine.pageSize }}'</span> || <span class="number">10</span>,</span><br><span class="line"> master: <span class="string">"{{ theme.valine.master }}"</span>,</span><br><span class="line"> friends: <span class="string">"{{ theme.valine.friends }}"</span>,</span><br><span class="line"> tagMeta: [<span class="string">"{{ theme.valine.tagMeta_master }}"</span>, <span class="string">"{{ theme.valine.tagMeta_friends }}"</span>, <span class="string">"{{ theme.valine.tagMeta_visters }}"</span>],</span><br><span class="line"> metaPlaceholder: {<span class="string">"nick"</span>: <span class="string">"昵称/QQ号(必填)"</span>,<span class="string">"mail"</span>: <span class="string">"邮箱(会收到回复哦~)"</span>,<span class="string">"link"</span>: <span class="string">"网址(放上你的博客地址~)"</span>},</span><br><span class="line"> enableQQ: <span class="string">"{{ theme.valine.enableQQ }}"</span>,</span><br><span class="line">});</span><br></pre></td></tr></table></figure><p>打开 <code>./themes/next/layout/_layout.swg</code> 文件,</p><p>在 <code>head</code> 标签内添加</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><link href=<span class="string">"https://cdn.bootcdn.net/ajax/libs/font-awesome/5.13.0/css/all.min.css"</span> rel=<span class="string">"stylesheet"</span>></span><br></pre></td></tr></table></figure><h4 id="6-添加自定义表情"><a href="#6-添加自定义表情" class="headerlink" title="6. 添加自定义表情"></a>6. 添加自定义表情</h4><p>打开前面下载的 <code>Valine.min.js</code> 文件,</p><p>查找 <code>//img.t.sinajs.cn/t4/appstyle/expression/ext/normal/</code> ,将其剪贴到粘贴板。</p><p>查找 <code>smile</code> (由于默认表情第一个是smile),找到 <code>function(e,t){e.exports={smile:</code>,</p><p>在每个链接的前面添加刚刚剪贴的内容</p><p>(较多,可以使用正则替换):</p><p><code>:"(.*?)"</code>-><code>"//img.t.sinajs.cn/t4/appstyle/expression/ext/normal/$1"</code></p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/high-1/replace.png" alt=""></p><p>在 <code>smile</code> 前面添加自己的表情。</p><p>格式:<名字>:”<图片地址>”,例如:</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">smile:"https://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/e3/2018new_weixioa02_org.png",</span><br></pre></td></tr></table></figure><p>这里有别人整理的一些表情包,我将其整理为可用的json格式:</p><p>原仓库地址:<a href="https://github.com/blogimg/emotion" target="_blank" rel="noopener">https://github.com/blogimg/emotion</a></p><p>我的仓库地址:<a href="https://github.com/Roc136/emotion" target="_blank" rel="noopener">https://github.com/Roc136/emotion</a></p><p>可以从我的仓库的README中复制喜欢的表情的地址,也可以将仓库克隆到自己的github里,将链接中的Roc136换成自己的名字。</p><p>这里没有使用CDN,不建议放入过多的自定义表情,因为会让表情的加载变得很慢。</p><h4 id="效果图:"><a href="#效果图:" class="headerlink" title="效果图:"></a>效果图:</h4><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/high-1/valine_final.png" alt=""></p><h4 id="7-添加评论邮件通知"><a href="#7-添加评论邮件通知" class="headerlink" title="7. 添加评论邮件通知"></a>7. 添加评论邮件通知</h4><p>在 leancloud 控制台,点击云引擎-部署-部署项目</p><p>点击 Git部署,输入地址:<a href="https://github.com/zhaojun1998/Valine-Admin" target="_blank" rel="noopener">https://github.com/zhaojun1998/Valine-Admin</a></p><p>点击手动部署-部署,等待部署完成。</p><p>点击设置,添加环境变量如下</p><table><thead><tr><th align="center">变量</th><th align="center">值</th></tr></thead><tbody><tr><td align="center">ADMIN_URL</td><td align="center"># 你的评论管理地址</td></tr><tr><td align="center">SENDER_NAME</td><td align="center"># 名字</td></tr><tr><td align="center">SITE_NAME</td><td align="center"># 站点名字</td></tr><tr><td align="center">SITE_URL</td><td align="center"># 站点url</td></tr><tr><td align="center">SMTP_HOST</td><td align="center"># 邮箱服务器 例如QQ邮箱填 smtp.qq.com</td></tr><tr><td align="center">SMTP_PASS</td><td align="center"># 邮箱密码,不是登陆邮箱使用的密码,在邮箱的smtp设置中查找</td></tr><tr><td align="center">SMTP_PORT</td><td align="center"># 端口</td></tr><tr><td align="center">SMTP_SERVICE</td><td align="center"># 邮箱服务商</td></tr><tr><td align="center">SMTP_USER</td><td align="center"># 发送邮箱,用于发送通知邮件,包括评论通知和回复通知</td></tr><tr><td align="center">TEMPLATE_NAME</td><td align="center"># 主题,目前有rainbow和default两种</td></tr><tr><td align="center">TO_EMAIL</td><td align="center"># 主人邮箱,用于接收评论通知</td></tr></tbody></table><p>如下</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/high-1/var.png" alt=""></p><p>详见 <a href="http://www.zhaojun.im/hexo-valine-admin/" target="_blank" rel="noopener">http://www.zhaojun.im/hexo-valine-admin/</a></p><h3 id="二、变化的背景"><a href="#二、变化的背景" class="headerlink" title="二、变化的背景"></a>二、变化的背景</h3><p>(包括修改背景随时间变化,标题栏字体、背景颜色随背景变化,页面底部信息随背景变化)</p><p>打开 <code>./themes/next/source/css/_custom/custom.styl</code> 文件,在 <code>body</code> 前面添加</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">:root {</span><br><span class="line"> --bgurl: ;</span><br><span class="line"> --brand-<span class="attribute">color</span>: rgb(<span class="number">106</span>,<span class="number">0</span>,<span class="number">95</span>);</span><br><span class="line"> --site-meta-<span class="attribute">color</span>: black;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>(这里需要做过前面的美化教程中的添加背景图和修改标题颜色背景的工作,见<a href="/posts/blog-building/beautify-1/#2-添加静态背景图">Hexo+Next+GitHub博客搭建超详细教程–美化篇(1)</a>)</p><p>将 <code>body</code> 中的 <code>background</code> 的链接修改为 <code>var(--bgurl)</code></p><p>将 <code>.site-meta</code> 中的 <code>background</code> 的链接修改为 <code>var(--site-meta-color)</code> </p><p>将 <code>brand</code> 中的 <code>color</code> 修改为 <code>var(--brand-color)</code></p><p>打开 <code>./theme/snext/css/_common/components/footer/footer.styl</code> 文件</p><p>在最前面添加</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">:root {</span><br><span class="line"> --footer-<span class="attribute">color</span>: <span class="number">#1e1e1e</span>; </span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>将 <code>footer</code> 中的 <code>color</code> 改为 <code>var(--footer-color)</code></p><br/><p>在 <code>./themes/next/source/js/src/</code> 文件夹下新建文件 <code>color.js</code> ,在其中添加以下内容</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> bg_num=<span class="number">31</span>,time=<span class="number">600000</span>,bg_id=(<span class="built_in">Math</span>.ceil(<span class="keyword">new</span> <span class="built_in">Date</span>().getTime() / time) % bg_num + <span class="number">1</span>).toString();</span><br><span class="line"><span class="comment">// var url="https://blog-roc.oss-cn-hongkong.aliyuncs.com/background/bj" + bg_id + ".jpg";</span></span><br><span class="line"><span class="keyword">var</span> url=<span class="string">"/images/background/bj"</span> + bg_id + <span class="string">".jpg"</span>;</span><br><span class="line"><span class="built_in">document</span>.documentElement.style.setProperty(<span class="string">'--bgurl'</span>, <span class="string">"url("</span>+url+<span class="string">")"</span>);</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"背景id(每"</span>+time/<span class="number">60000</span>+<span class="string">"分钟改变一次):"</span>+bg_id);</span><br><span class="line"></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> root = <span class="built_in">document</span>.documentElement;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> TEXTColor = <span class="function"><span class="keyword">function</span>(<span class="params">obj</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span>(obj <span class="keyword">instanceof</span> TEXTColor) <span class="keyword">return</span> obj;</span><br><span class="line"> <span class="keyword">if</span>(!(<span class="keyword">this</span> <span class="keyword">instanceof</span> TEXTColor)) <span class="keyword">return</span> <span class="keyword">new</span> TEXTColor(obj);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span>(<span class="keyword">typeof</span> exports !== <span class="string">'undefined'</span>) {</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> <span class="built_in">module</span> !== <span class="string">'undefined'</span> && <span class="built_in">module</span>.exports) {</span><br><span class="line"> exports = <span class="built_in">module</span>.exports = TEXTColor;</span><br><span class="line"> }</span><br><span class="line"> exports.TEXTColor = TEXTColor;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> root.TEXTColor = TEXTColor;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">resBgColor</span>(<span class="params">rgbArr</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> color = <span class="number">0.213</span> * rgbArr[<span class="number">0</span>] + <span class="number">0.715</span> * rgbArr[<span class="number">1</span>] + <span class="number">0.072</span> * rgbArr[<span class="number">2</span>] > <span class="number">255</span> / <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">return</span> color? <span class="string">'#000000'</span>: <span class="string">'#ffffff'</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> TEXTColor.findTextColor = <span class="function"><span class="keyword">function</span> <span class="title">findTextColor</span>(<span class="params">colorValue</span>) </span>{</span><br><span class="line"> <span class="comment">// #123456或者rgb(12,34,56)转为rgb数组[12,34,56]</span></span><br><span class="line"> <span class="keyword">const</span> reg = <span class="regexp">/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/</span>;</span><br><span class="line"> <span class="keyword">var</span> that = colorValue;</span><br><span class="line"> <span class="keyword">if</span> (<span class="regexp">/^(rgb|RGB)/</span>.test(that)) {</span><br><span class="line"> <span class="comment">// 处理rgb转为数组</span></span><br><span class="line"> <span class="keyword">var</span> aColor = that.replace(<span class="regexp">/(?:\(|\)|rgb|RGB)*/g</span>, <span class="string">""</span>).split(<span class="string">","</span>);</span><br><span class="line"> <span class="keyword">return</span> resBgColor(aColor);</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (reg.test(that)) {</span><br><span class="line"> <span class="comment">// 处理十六进制色值</span></span><br><span class="line"> <span class="keyword">var</span> sColor = colorValue.toLowerCase();</span><br><span class="line"> <span class="keyword">if</span> (sColor && reg.test(sColor)) {</span><br><span class="line"> <span class="keyword">if</span> (sColor.length === <span class="number">4</span>) {</span><br><span class="line"> <span class="keyword">var</span> sColorNew = <span class="string">"#"</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">1</span>; i < <span class="number">4</span>; i += <span class="number">1</span>) {</span><br><span class="line"> sColorNew += sColor.slice(i, i + <span class="number">1</span>).concat(sColor.slice(i, i + <span class="number">1</span>));</span><br><span class="line"> }</span><br><span class="line"> sColor = sColorNew;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//处理六位的颜色值</span></span><br><span class="line"> <span class="keyword">var</span> sColorChange = [];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">1</span>; i < <span class="number">7</span>; i += <span class="number">2</span>) {</span><br><span class="line"> sColorChange.push(<span class="built_in">parseInt</span>(<span class="string">"0x"</span> + sColor.slice(i, i + <span class="number">2</span>)));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> resBgColor(sColorChange);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">hexToRgb</span>(<span class="params">hex</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> result = <span class="regexp">/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i</span>.exec(hex);</span><br><span class="line"> <span class="keyword">return</span> result ? [</span><br><span class="line"> <span class="built_in">parseInt</span>(result[<span class="number">1</span>], <span class="number">16</span>),</span><br><span class="line"> <span class="built_in">parseInt</span>(result[<span class="number">2</span>], <span class="number">16</span>),</span><br><span class="line"> <span class="built_in">parseInt</span>(result[<span class="number">3</span>], <span class="number">16</span>)</span><br><span class="line"> ] : <span class="literal">null</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">componentToHex</span>(<span class="params">c</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> hex = c.toString(<span class="number">16</span>);</span><br><span class="line"> <span class="keyword">return</span> hex.length == <span class="number">1</span> ? <span class="string">"0"</span> + hex : hex;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">rgbToHex</span>(<span class="params">r, g, b</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"#"</span> + componentToHex(r) + componentToHex(g) + componentToHex(b);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//some colors from https://gist.github.com/ruanyf/e6c896df1c24d0236eb93d65144f2907</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">hksubcolor</span>(<span class="params">rgbcolor</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> color_list=[<span class="string">"#b51921"</span>,<span class="string">"#b2103e"</span>,<span class="string">"#c41832"</span>,<span class="string">"#ef342a"</span>,<span class="string">"#a84d18"</span>,<span class="string">"#f68f26"</span>,<span class="string">"#faca07"</span>,<span class="string">"#07594a"</span>,<span class="string">"#4ba946"</span>,<span class="string">"#5fc0a7"</span>,<span class="string">"#0376c2"</span>,<span class="string">"#c41832"</span>,<span class="string">"#c41832"</span>,<span class="string">"#be3223"</span>,<span class="string">"#f45f7c"</span>,<span class="string">"#d16f20"</span>,<span class="string">"#ffd00d"</span>,<span class="string">"#076750"</span>,<span class="string">"#7abf45"</span>,<span class="string">"#75c7b9"</span>,<span class="string">"#077cb0"</span>,<span class="string">"#29409a"</span>,<span class="string">"#ee1e4f"</span>,<span class="string">"#d2174a"</span>,<span class="string">"#f79d8b"</span>,<span class="string">"#ce7020"</span>,<span class="string">"#e9a519"</span>,<span class="string">"#fddf55"</span>,<span class="string">"#076a66"</span>,<span class="string">"#a7c299"</span>,<span class="string">"#098ec4"</span>,<span class="string">"#89d2e3"</span>,<span class="string">"#7572a7"</span>,<span class="string">"#f7b1bf"</span>,<span class="string">"#f67e2a"</span>,<span class="string">"#f57125"</span>,<span class="string">"#fbaf37"</span>,<span class="string">"#fde14e"</span>,<span class="string">"#076c53"</span>,<span class="string">"#b2d68c"</span>,<span class="string">"#8fd1cd"</span>,<span class="string">"#0798c7"</span>,<span class="string">"#9597ca"</span>,<span class="string">"#69686d"</span>,<span class="string">"#f47a25"</span>,<span class="string">"#fcba5d"</span>,<span class="string">"#f8d29d"</span>,<span class="string">"#ffe285"</span>,<span class="string">"#077e7a"</span>,<span class="string">"#d0e4a9"</span>,<span class="string">"#81cdc1"</span>,<span class="string">"#22b6ed"</span>,<span class="string">"#b4d6f2"</span>,<span class="string">"#c077af"</span>,<span class="string">"#bbbfc2"</span>,<span class="string">"#fed7a6"</span>,<span class="string">"#fcae62"</span>,<span class="string">"#ffe901"</span>,<span class="string">"#078e82"</span>,<span class="string">"#d7df3f"</span>,<span class="string">"#89d3de"</span>,<span class="string">"#22b6ed"</span>,<span class="string">"#b295c5"</span>,<span class="string">"#c5c4c9"</span>,<span class="string">"#d1d5d8"</span>,<span class="string">"#f2f1f6"</span>,<span class="string">"#efe946"</span>,<span class="string">"#fff455"</span>,<span class="string">"#ffe901"</span>,<span class="string">"#4c7020"</span>,<span class="string">"#c4e0e1"</span>,<span class="string">"#79bce7"</span>,<span class="string">"#b7e1fa"</span>,<span class="string">"#c7a7d2"</span>,<span class="string">"#e5e4e9"</span>,<span class="string">"#f2f1f6"</span>,<span class="string">"#f2f2f6"</span>,<span class="string">"#1fb27f"</span>,<span class="string">"#b5a87f"</span>,<span class="string">"#07b195"</span>,<span class="string">"#d7df3f"</span>,<span class="string">"#6dade2"</span>,<span class="string">"#4dc7ec"</span>,<span class="string">"#a8b7d8"</span>,<span class="string">"#b8a1a9"</span>,<span class="string">"#f8c9cb"</span>,<span class="string">"#f2f1f6"</span>];</span><br><span class="line"> <span class="keyword">var</span> result = hexToRgb(color_list[<span class="number">0</span>]);</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">sum</span>(<span class="params">arr</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> arr[<span class="number">0</span>]+arr[<span class="number">1</span>]+arr[<span class="number">2</span>];</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>;i<color_list.length;i+=<span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">var</span> c=color_list[i];</span><br><span class="line"> <span class="keyword">var</span> rgbc=hexToRgb(c);</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">Math</span>.abs(sum(result)-sum(rgbcolor))><span class="built_in">Math</span>.abs(sum(rgbc)-sum(rgbcolor))) {</span><br><span class="line"> result=rgbc;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> rgbToHex(result[<span class="number">0</span>],result[<span class="number">1</span>],result[<span class="number">2</span>]);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">get_bg_color</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="params">resolve</span> =></span> {</span><br><span class="line"> <span class="keyword">const</span> colorThief = <span class="keyword">new</span> ColorThief();</span><br><span class="line"> <span class="keyword">const</span> bg_img = <span class="keyword">new</span> Image;</span><br><span class="line"> bg_img.crossOrigin = <span class="string">'Anonymous'</span>;</span><br><span class="line"> bg_img.onload = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> result = colorThief.getColor(bg_img)</span><br><span class="line"> <span class="keyword">var</span> bg_color = <span class="string">"#"</span>+result[<span class="number">0</span>].toString(<span class="number">16</span>) + result[<span class="number">1</span>].toString(<span class="number">16</span>) + result[<span class="number">2</span>].toString(<span class="number">16</span>);</span><br><span class="line"> resolve(bg_color);</span><br><span class="line"> <span class="keyword">var</span> level = <span class="number">1</span>;</span><br><span class="line"> <span class="built_in">document</span>.documentElement.style.setProperty(<span class="string">"--brand-color"</span>, <span class="string">"rgb("</span>+result[<span class="number">0</span>]*level+<span class="string">","</span>+result[<span class="number">1</span>]*level+<span class="string">","</span>+result[<span class="number">2</span>]*level+<span class="string">")"</span>);</span><br><span class="line"> <span class="built_in">document</span>.documentElement.style.setProperty(<span class="string">"--site-meta-color"</span>, hksubcolor([<span class="number">255</span>-result[<span class="number">0</span>]*level,<span class="number">255</span>-result[<span class="number">1</span>]*level,<span class="number">255</span>-result[<span class="number">2</span>]*level]));</span><br><span class="line"> }</span><br><span class="line"> bg_img.src = url;</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">set_text_color</span>(<span class="params">bg_color</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">typeof</span> define === <span class="string">'function'</span> && define.amd) {</span><br><span class="line"> define(<span class="string">'color-js'</span> ,[], <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> TEXTColor;</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">var</span> textcolor = TEXTColor.findTextColor(bg_color);</span><br><span class="line"> <span class="built_in">document</span>.documentElement.style.setProperty(<span class="string">"--footer-color"</span>, textcolor);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> (<span class="keyword">async</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> bg_color = <span class="keyword">await</span> get_bg_color();</span><br><span class="line"> set_text_color(bg_color);</span><br><span class="line"> })();</span><br><span class="line">})();</span><br></pre></td></tr></table></figure><p><strong>其中第一行的 <code>bg_num</code> 是背景图的数量,<code>time</code> 是切换时间,以毫秒为单位,可以根据自己的需求修改。</strong></p><p>打开 <code>./themes/next/layout/_layout.swig</code> 文件,在head标签内添加</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><!--根据背景切换footer颜色--></span><br><span class="line"><script src=<span class="string">"https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js"</span>><<span class="regexp">/script></span></span><br><span class="line"><span class="regexp"><script type="module" src="/</span>js/src/color.js<span class="string">"></script></span></span><br></pre></td></tr></table></figure><p>接下来将背景图存放到 <code>./themes/next/source/images/background/</code> 文件夹下,并依次重命名为 <code>bj+编号.jpg</code> (如 <code>bj1.jpg</code>、<code>bj2.jpg</code>)即可。</p>]]></content>
<categories>
<category> blog </category>
<category> 3.提升 </category>
</categories>
<tags>
<tag> blog </tag>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>深入理解计算机系统作业一</title>
<link href="/posts/csapp/homework1/"/>
<url>/posts/csapp/homework1/</url>
<content type="html"><![CDATA[<h1 id="作业1"><a href="#作业1" class="headerlink" title="作业1"></a>作业1</h1><h3 id="2-9"><a href="#2-9" class="headerlink" title="2.9"></a>2.9</h3><p>A. </p><table><thead><tr><th align="center">颜色(RGB)</th><th align="center">补(RGB)</th></tr></thead><tbody><tr><td align="center">黑色(000)</td><td align="center">白色(111)</td></tr><tr><td align="center">蓝色(001)</td><td align="center">黄色(110)</td></tr><tr><td align="center">绿色(010)</td><td align="center">红紫色(101)</td></tr><tr><td align="center">蓝绿色(011)</td><td align="center">红色(100)</td></tr><tr><td align="center">红色(100)</td><td align="center">蓝绿色(011)</td></tr><tr><td align="center">红紫色(101)</td><td align="center">绿色(010)</td></tr><tr><td align="center">黄色(110)</td><td align="center">蓝色(001)</td></tr><tr><td align="center">白色(111)</td><td align="center">黑色(000)</td></tr></tbody></table><p>B.</p><p>蓝色 | 绿色 = 蓝绿色(001|010=011)</p><p>黄色 & 蓝绿色 = 绿色(110&011=010)</p><p>红色 ^ 红紫色 = 蓝色(100^101=001)</p><h3 id="2-14"><a href="#2-14" class="headerlink" title="2.14"></a>2.14</h3><p>x = 0x66 = 0110 0110<sub>(2)</sub></p><p>y = 0x39 = 0011 1001<sub>(2)</sub></p><p>x & y = 0010 0000<sub>(2)</sub> = 0x20</p><p>x | y = 0111 1111<sub>(2)</sub> = 0x7f</p><p>~x | ~y = 1101 1111<sub>(2)</sub> = 0xdf</p><table><thead><tr><th align="center">表达式</th><th align="center">值</th><th align="center">表达式</th><th align="center">值</th></tr></thead><tbody><tr><td align="center">x & y</td><td align="center">0x20</td><td align="center">x && y</td><td align="center">0x01</td></tr><tr><td align="center">x | y</td><td align="center">0x7f</td><td align="center">x || y</td><td align="center">0x01</td></tr><tr><td align="center">-x | -y</td><td align="center">0xdf</td><td align="center">!x || !y</td><td align="center">0x00</td></tr><tr><td align="center">x & !y</td><td align="center">0x00</td><td align="center">x && -y</td><td align="center">0x01</td></tr></tbody></table><h3 id="2-15"><a href="#2-15" class="headerlink" title="2.15"></a>2.15</h3><p>!(x^y),x和y的每一位都相同时返回1.</p><h3 id="2-18"><a href="#2-18" class="headerlink" title="2.18"></a>2.18</h3><p>0x2e0=736</p><p>-0x58=-88</p><p>0x28=40</p><p>-0x30=-48</p><p>0x78=120</p><p>0x88=136</p><p>0x1f8=504</p><p>0x8=8</p><p>0xc0=192</p><p>-0x48=-72</p><h3 id="2-21"><a href="#2-21" class="headerlink" title="2.21"></a>2.21</h3><table><thead><tr><th align="center">表达式</th><th align="center">类型</th><th align="center">求值</th></tr></thead><tbody><tr><td align="center">-2147483647-1 == 2147483648U</td><td align="center">无符号</td><td align="center">1</td></tr><tr><td align="center">-2147483647-1 < 2147483647</td><td align="center">有符号</td><td align="center">1</td></tr><tr><td align="center">-2147483647-1U < 2147483647</td><td align="center">无符号</td><td align="center">0</td></tr><tr><td align="center">-2147483647-1 < -2147483647</td><td align="center">有符号</td><td align="center">1</td></tr><tr><td align="center">-2147483647-1U < -2147483647</td><td align="center">无符号</td><td align="center">1</td></tr></tbody></table><h3 id="2-23"><a href="#2-23" class="headerlink" title="2.23"></a>2.23</h3><p>A.</p><table><thead><tr><th align="center">w</th><th align="center">fun1(w)</th><th align="center">fun2(w)</th></tr></thead><tbody><tr><td align="center">0x00000076</td><td align="center">118</td><td align="center">118</td></tr><tr><td align="center">0x87654321</td><td align="center">33</td><td align="center">33</td></tr><tr><td align="center">0x000000C9</td><td align="center">201</td><td align="center">-55</td></tr><tr><td align="center">0xEDCBA987</td><td align="center">135</td><td align="center">-121</td></tr></tbody></table><p>B.</p><p>fun1从w的低8位中提取值得到一个0~255的整数。fun2从w的低8位中提取值再进行符号扩展,得到一个 -128~127的整数。</p><h3 id="2-25"><a href="#2-25" class="headerlink" title="2.25"></a>2.25</h3><p>当 <code>length</code> 为 <code>0</code> 时,由于 <code>lenght</code> 为无符号数, <code>length-1</code> 为 <code>UMax</code> ,<code>i <= length-1</code> 为 <code>1</code> ,循环体会被执行,于是会出现 <code>a[1]</code> 等,发生内存错误。</p><h3 id="2-26"><a href="#2-26" class="headerlink" title="2.26"></a>2.26</h3><p>A. 当 s 比 t 短时,会返回1</p><p>B. 当 s 比 t 短时, <code>strlen(s) - strlen(t)</code> 结果为负数,但由于是无符号数,会被认为是很大的一个正数,于是返回1</p><p>C. 将 <code>return strlen(s) - strlen(t) > 0;</code> 改为 <code>return strlen(s) > strlen(t);</code></p>]]></content>
<categories>
<category> 作业 </category>
<category> 深入理解计算机系统 </category>
</categories>
<tags>
<tag> 深入理解计算机系统 </tag>
</tags>
</entry>
<entry>
<title>CentOS 7 设置定时任务</title>
<link href="/posts/crontab/"/>
<url>/posts/crontab/</url>
<content type="html"><![CDATA[<h3 id="概述"><a href="#概述" class="headerlink" title="概述 "></a>概述 </h3><p> 就像在windows上有计划任务一样,centos7 自然也有计划任务,而且设置更为灵活,好用。在centos7 上可以利用crontab 来执行计划任务, 依赖与 crond 的系统服务,这个服务是系统自带的,可以直接查看状态,启动,停止。</p><a id="more"></a><h3 id="安装-crontabs服务并设置开机自启"><a href="#安装-crontabs服务并设置开机自启" class="headerlink" title="安装 crontabs服务并设置开机自启"></a>安装 crontabs服务并设置开机自启</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">yum install crontabs</span><br><span class="line">systemctl <span class="built_in">enable</span> crond (设为开机启动)</span><br><span class="line">systemctl start crond(启动crond服务)</span><br><span class="line">systemctl status crond (查看状态)</span><br></pre></td></tr></table></figure><h3 id="设置用户自定义定时任务"><a href="#设置用户自定义定时任务" class="headerlink" title="设置用户自定义定时任务"></a>设置用户自定义定时任务</h3><p><code>vi /etc/crontab</code><br>可以看到:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Example of job definition:</span><br><span class="line">.---------------- minute (0 - 59)</span><br><span class="line">| .------------- hour (0 - 23)</span><br><span class="line">| | .---------- day of month (1 - 31)</span><br><span class="line">| | | .------- month (1 - 12) OR jan,feb,mar,apr ...</span><br><span class="line">| | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat</span><br><span class="line">| | | | |</span><br><span class="line">* * * * * user-name command to be executed</span><br></pre></td></tr></table></figure><p>即:<br>分钟(0-59) 小时(0-23) 日(1-31) 月(11-12) 星期(0-6,0表示周日) 用户名 要执行的命令</p><ul><li><code>*/30 * * * root /usr/local/mycommand.sh</code> (每天,每30分钟执行一次 mycommand命令)</li><li><code>* 3 * * * root /usr/local/mycommand.sh</code> (每天凌晨三点,执行命令脚本,PS:这里由于第一个的分钟没有设置,那么就会每天凌晨3点的每分钟都执行一次命令)</li><li><code>0 3 * * * root /usr/local/mycommand.sh</code> (这样就是每天凌晨三点整执行一次命令脚本)</li><li><code>*/10 11-13 * * * root /usr/local/mycommand.sh</code> (每天11点到13点之间,每10分钟执行一次命令脚本,这一种用法也很常用)</li><li><code>10-30 * * * * root /usr/local/mycommand.sh</code> (每小时的10-30分钟,每分钟执行一次命令脚本,共执行20次)</li><li><code>10,30 * * * * * root /usr/local/mycommand.sh</code> (每小时的10,30分钟,分别执行一次命令脚本,共执行2次)</li></ul><h3 id="保存生效"><a href="#保存生效" class="headerlink" title="保存生效"></a>保存生效</h3><p>加载任务,使之生效:<code>crontab /etc/crontab</code></p><p>查看任务:<code>crontab -l</code><br>$ crontab -u 用户名 -l (列出用户的定时任务列表)</p><p>PS:特别注意,crond的任务计划, 有并不会调用用户设置的环境变量,它有自己的环境变量,当你用到一些命令时,比如mysqldump等需要环境变量的命令,手工执行脚本时是正常的,但用crond执行的时候就会不行,这时你要么写完整的绝对路径,要么将环境变量添加到 /etc/crontab 中。</p><p>好了,计划任务就是这么简单了,但是计划任务,执行的语句如果是多条,则需要用药shell脚本,自己先写一个shell脚本,然后在计划任务中,执行这个脚本即可。至于shell脚本的写法, 这里不赘述。</p><hr><p>参考链接</p><p><a href="https://blog.csdn.net/qianxing111/article/details/80091187" target="_blank" rel="noopener">https://blog.csdn.net/qianxing111/article/details/80091187</a></p>]]></content>
<categories>
<category> linux </category>
</categories>
<tags>
<tag> linux </tag>
<tag> CentOS 7 </tag>
<tag> 定时任务 </tag>
</tags>
</entry>
<entry>
<title>超好用的PC端pdf做笔记软件</title>
<link href="/posts/recommend/drawboardpdf/"/>
<url>/posts/recommend/drawboardpdf/</url>
<content type="html"><![CDATA[<h3 id="一、下载"><a href="#一、下载" class="headerlink" title="一、下载"></a>一、下载</h3><p>在微软应用商店搜索 DrawboardPDF, 即可下载这款软件。</p><p>也可以直接点击 <a href="https://www.drawboard.com/pdf/" target="_blank" rel="noopener">DradboardPDF</a> 下载。</p><p>软件有免费版和付费版两种,不过免费版已经可以满足我们的大部分需求。</p><h3 id="二、简介"><a href="#二、简介" class="headerlink" title="二、简介"></a>二、简介</h3><h4 id="1-界面"><a href="#1-界面" class="headerlink" title="1. 界面"></a>1. 界面</h4><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/recommend/jiemian.png" alt=""></p><p>整体界面一看就是UWP的风格,还算比较简洁。</p><h4 id="2-功能"><a href="#2-功能" class="headerlink" title="2. 功能"></a>2. 功能</h4><p>可以看到右上角的圆盘,其中有很多常用的编辑功能(可惜其他很多PDF查看器没有),包括画笔,荧光笔,橡皮擦,文本添加,图片添加,形状,书签,注释,签名的添加等等(部分收在工具的下一层),还有激光笔功能,并且各种画笔可以调节粗细颜色等等。基本上已经能够满足我的所有需求。</p><p>此外,可以看到左侧还有一个快捷工具栏,可以把自己常用的工具收藏在左侧的快捷工具栏。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/recommend/gongneng.png" alt=""></p><p>可以说是为数不多的良心软件~</p><h4 id="3-不足"><a href="#3-不足" class="headerlink" title="3. 不足"></a>3. 不足</h4><p>启动时较慢,建议只是看的时候使用老版edge或者Sumatra PDF,需要编辑的时候再使用drawboard PDF。</p>]]></content>
<categories>
<category> recommend </category>
</categories>
<tags>
<tag> PDF </tag>
</tags>
</entry>
<entry>
<title>Hexo+Next+GitHub博客搭建超详细教程--美化篇(4)</title>
<link href="/posts/blog-building/beautify-4/"/>
<url>/posts/blog-building/beautify-4/</url>
<content type="html"><![CDATA[<h3 id="一、添加"><a href="#一、添加" class="headerlink" title="一、添加"></a>一、添加</h3><p>从GitHub上下载张书樵大佬的<a href="https://github.com/stevenjoezhang/live2d-widget" target="_blank" rel="noopener">live2d-widget</a> ,保存到 <code>./themes/next/source</code> 文件夹下,也可以直接在博客文件夹执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git <span class="built_in">clone</span> https://github.com/stevenjoezhang/live2d-widget.git themes/next/<span class="built_in">source</span>/live2d-widget</span><br></pre></td></tr></table></figure><p>打开其中的 <code>autoload.js</code> 文件,将第一行</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> live2d_path = <span class="string">"https://cdn.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/"</span>;</span><br></pre></td></tr></table></figure><p>注释掉,将</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">//const live2d_path = "/live2d-widget/";</span><br></pre></td></tr></table></figure><p>取消注释。</p><p>查找 <code>apiPath</code> ,将其取消注释,并将 <code>cdnPath</code> 一行注释掉</p><p>在<strong>主题配置文件</strong>添加 </p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># live2d</span></span><br><span class="line"><span class="attr">live2d:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>在 <code>./themes/next/layout/_layout.swig</code> 文件的 <code><head></code> 标签内添加</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--看板娘--></span></span><br><span class="line">{% if theme.live2d.enable %}</span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"/live2d-widget/autoload.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><h3 id="二、修改配置"><a href="#二、修改配置" class="headerlink" title="二、修改配置"></a>二、修改配置</h3><h4 id="1-移到右侧"><a href="#1-移到右侧" class="headerlink" title="1. 移到右侧"></a>1. 移到右侧</h4><p>默认是在左侧,如果想要移到右侧,可以点击 <a href="/live2d-widget/waifu-right.css">右侧配置css</a> 保存到本地 <code>./themes/next/source/live2d-widget</code> 文件夹下,并将原来的 <code>waifu.css</code> 重命名为 <code>waifu-left.css</code> 。</p><p>在 <code>autoload.js</code> 文件中查找 <code>waifu.css</code> ,修改为 <code>waifu-right.css</code> 即可。</p><h4 id="2-修改其他的一些配置"><a href="#2-修改其他的一些配置" class="headerlink" title="2. 修改其他的一些配置"></a>2. 修改其他的一些配置</h4><p>张书樵大佬的配置本身已经不错了,但是有一些个人觉得不太好,于是稍作修改</p><h5 id="1)修改默认模型和材质"><a href="#1)修改默认模型和材质" class="headerlink" title="1)修改默认模型和材质"></a>1)修改默认模型和材质</h5><p>在 <code>waifu-tips.js</code> 文件中找到以下内容</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (modelId === <span class="literal">null</span>) {</span><br><span class="line"><span class="comment">// 首次访问加载 指定模型 的 指定材质</span></span><br><span class="line">modelId = <span class="number">1</span>; <span class="comment">// 模型 ID</span></span><br><span class="line">modelTexturesId = <span class="number">53</span>; <span class="comment">// 材质 ID</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>修改编号为自己喜欢的模型和材质</p><h5 id="2)删去”一言“的“来自”信息"><a href="#2)删去”一言“的“来自”信息" class="headerlink" title="2)删去”一言“的“来自”信息"></a>2)删去”一言“的“来自”信息</h5><p>因为这一句的显示很迷惑,连续点击几次“一言”按钮“来自”信息才慢慢出现,与前面的”一言“不匹配。</p><p>在 <code>waifu-tips.js</code> 文件中查找以下内容</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 增加 hitokoto.cn 的 API</span></span><br><span class="line">fetch(<span class="string">"https://v1.hitokoto.cn"</span>)</span><br><span class="line">.then(<span class="function"><span class="params">response</span> =></span> response.json())</span><br><span class="line">.then(<span class="function"><span class="params">result</span> =></span> {</span><br><span class="line"><span class="keyword">let</span> text = <span class="string">`这句一言来自 <span>「<span class="subst">${result.<span class="keyword">from</span>}</span>」</span>,是 <span><span class="subst">${result.creator}</span></span> 在 hitokoto.cn 投稿的。`</span>;</span><br><span class="line">showMessage(result.hitokoto, <span class="number">6000</span>, <span class="number">9</span>);</span><br><span class="line">setTimeout(<span class="function"><span class="params">()</span> =></span> {</span><br><span class="line">showMessage(text, <span class="number">4000</span>, <span class="number">9</span>);</span><br><span class="line">}, <span class="number">6000</span>);</span><br><span class="line">});</span><br></pre></td></tr></table></figure><p>将其中第5 7 8 9 行注释掉,如下</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 增加 hitokoto.cn 的 API</span></span><br><span class="line">fetch(<span class="string">"https://v1.hitokoto.cn"</span>)</span><br><span class="line">.then(<span class="function"><span class="params">response</span> =></span> response.json())</span><br><span class="line">.then(<span class="function"><span class="params">result</span> =></span> {</span><br><span class="line"><span class="comment">//let text = `这句一言来自 <span>「${result.from}」</span>,是 <span>${result.creator}</span> 在 hitokoto.cn 投稿的。`;</span></span><br><span class="line">showMessage(result.hitokoto, <span class="number">6000</span>, <span class="number">9</span>);</span><br><span class="line"><span class="comment">//setTimeout(() => {</span></span><br><span class="line"><span class="comment">//showMessage(text, 4000, 9);</span></span><br><span class="line"><span class="comment">//}, 6000);</span></span><br><span class="line">});</span><br></pre></td></tr></table></figure><p>最终效果与本站相同</p>]]></content>
<categories>
<category> blog </category>
<category> 2.美化 </category>
</categories>
<tags>
<tag> blog </tag>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>Hexo+Next+GitHub博客搭建超详细教程--美化篇(3)</title>
<link href="/posts/blog-building/beautify-3/"/>
<url>/posts/blog-building/beautify-3/</url>
<content type="html"><![CDATA[<h3 id="一、代码块美化"><a href="#一、代码块美化" class="headerlink" title="一、代码块美化"></a>一、代码块美化</h3><p>打开 <code>./themes/next/source/css/_custom/custom.styl</code> 文件,在末尾添加以下内容</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 小代码块样式</span></span><br><span class="line"><span class="selector-tag">code</span> {</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#CE8349</span>; <span class="comment">//小代码块的字体颜色</span></span><br><span class="line"> <span class="attribute">background</span>: <span class="number">#21252b</span>; <span class="comment">//背景颜色</span></span><br><span class="line"> <span class="attribute">opacity</span>: <span class="number">0.8</span>; <span class="comment">//透明度</span></span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">2px</span>; <span class="comment">//边距</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">//大代码块的自定义样式</span></span><br><span class="line"><span class="selector-class">.highlight</span>, pre {</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">30px</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">0px</span> <span class="number">0px</span> <span class="number">0px</span> <span class="number">0px</span>; <span class="comment">//上 右 下 左</span></span><br><span class="line"> <span class="attribute">border-radius</span>: <span class="number">0px</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.highlight</span>, <span class="selector-tag">code</span>, pre {</span><br><span class="line"> <span class="attribute">border</span>: -<span class="number">5px</span> solid <span class="number">#d6d6d6</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 代码框样式</span></span><br><span class="line"><span class="selector-class">.highlight-wrap</span>[data-rel] {</span><br><span class="line"> <span class="attribute">position</span>: relative;</span><br><span class="line"> <span class="attribute">overflow</span>: hidden;</span><br><span class="line"> <span class="attribute">border-radius</span>: <span class="number">5px</span>;</span><br><span class="line"> <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">0px</span> <span class="number">30px</span> <span class="number">0px</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.3</span>);</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">0px</span> <span class="number">0</span>;</span><br><span class="line"> <span class="comment">//代码块滚动条</span></span><br><span class="line"> ::-webkit-scrollbar {</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">10px</span>;</span><br><span class="line"> }</span><br><span class="line"> ::-webkit-scrollbar-track {</span><br><span class="line"> -webkit-<span class="attribute">box-shadow</span>: inset <span class="number">0</span> <span class="number">0</span> <span class="number">6px</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.3</span>);</span><br><span class="line"> <span class="attribute">border-radius</span>: <span class="number">10px</span>;</span><br><span class="line"> }</span><br><span class="line"> ::-webkit-scrollbar-thumb {</span><br><span class="line"> <span class="attribute">border-radius</span>: <span class="number">10px</span>;</span><br><span class="line"> -webkit-<span class="attribute">box-shadow</span>: inset <span class="number">0</span> <span class="number">0</span> <span class="number">6px</span> rgba(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> &::before {</span><br><span class="line"> <span class="attribute">color</span>: white;</span><br><span class="line"> <span class="attribute">content</span>: attr(data-rel);</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">30px</span>;</span><br><span class="line"> <span class="attribute">line-height</span>: <span class="number">30px</span>;</span><br><span class="line"> <span class="attribute">background</span>: <span class="number">#21252b</span>;</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#fff</span>;</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">16px</span>;</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="comment">// position: relative;</span></span><br><span class="line"> <span class="attribute">top</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">100%</span>;</span><br><span class="line"> <span class="attribute">font-family</span>: <span class="string">'Source Sans Pro'</span>, sans-serif;</span><br><span class="line"> <span class="attribute">font-weight</span>: bold;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">0px</span> <span class="number">80px</span>;</span><br><span class="line"> <span class="attribute">text-indent</span>: <span class="number">15px</span>; <span class="comment">//文本类型(如PLAIN)左端距离</span></span><br><span class="line"> <span class="attribute">float</span>: left;</span><br><span class="line"> }</span><br><span class="line"> &::after {</span><br><span class="line"> <span class="attribute">content</span>: <span class="string">' '</span>;</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="comment">// position: relative;</span></span><br><span class="line"> -webkit-<span class="attribute">border-radius</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">border-radius</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">background</span>: <span class="number">#fc625d</span>;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">12px</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">12px</span>;</span><br><span class="line"> <span class="attribute">top</span>: <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">20px</span>;</span><br><span class="line"> <span class="attribute">margin-top</span>: <span class="number">10px</span>;</span><br><span class="line"> -webkit-<span class="attribute">box-shadow</span>: <span class="number">20px</span> <span class="number">0px</span> <span class="number">#fdbc40</span>, <span class="number">40px</span> <span class="number">0px</span> <span class="number">#35cd4b</span>;</span><br><span class="line"> <span class="attribute">box-shadow</span>: <span class="number">20px</span> <span class="number">0px</span> <span class="number">#fdbc40</span>, <span class="number">40px</span> <span class="number">0px</span> <span class="number">#35cd4b</span>;</span><br><span class="line"> <span class="attribute">z-index</span>: <span class="number">3</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在 <code>./themes/next/scripts/</code> 下创建文件 <code>codeblock.js</code> 将以下内容粘贴进去</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> attributes = [</span><br><span class="line"> <span class="string">'autocomplete="off"'</span>,</span><br><span class="line"> <span class="string">'autocorrect="off"'</span>,</span><br><span class="line"> <span class="string">'autocapitalize="off"'</span>,</span><br><span class="line"> <span class="string">'spellcheck="false"'</span>,</span><br><span class="line"> <span class="string">'contenteditable="true"'</span></span><br><span class="line">]</span><br><span class="line"><span class="keyword">var</span> attributesStr = attributes.join(<span class="string">' '</span>)</span><br><span class="line"></span><br><span class="line">hexo.extend.filter.register(<span class="string">'after_post_render'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">data</span>) </span>{</span><br><span class="line"> <span class="keyword">while</span> (<span class="regexp">/<figure class="highlight ([a-zA-Z]+)">.*?<\/figure>/</span>.test(data.content)) {</span><br><span class="line"> data.content = data.content.replace(<span class="regexp">/<figure class="highlight ([a-zA-Z]+)">.*?<\/figure>/</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> language = <span class="built_in">RegExp</span>.$<span class="number">1</span> || <span class="string">'plain'</span></span><br><span class="line"> <span class="keyword">var</span> lastMatch = <span class="built_in">RegExp</span>.lastMatch</span><br><span class="line"> lastMatch = lastMatch.replace(<span class="regexp">/<figure class="highlight /</span>, <span class="string">'<figure class="iseeu highlight /'</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'<div class="highlight-wrap"'</span> + attributesStr + <span class="string">'data-rel="'</span> + language.toUpperCase() + <span class="string">'">'</span> + lastMatch + <span class="string">'</div>'</span></span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> data</span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>在<strong>主题配置文件</strong>内查找 <code>highlight_theme</code> 修改其值为以下内容:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">highlight_theme:</span> <span class="string">night</span> <span class="string">eighties</span></span><br></pre></td></tr></table></figure><p>重新生成即可</p><p>效果和本文相同</p><h3 id="二、底部隐藏powered-by,添加访问统计,字数统计等"><a href="#二、底部隐藏powered-by,添加访问统计,字数统计等" class="headerlink" title="二、底部隐藏powered by,添加访问统计,字数统计等"></a>二、底部隐藏powered by,添加访问统计,字数统计等</h3><h4 id="1-隐藏powered-by"><a href="#1-隐藏powered-by" class="headerlink" title="1. 隐藏powered by"></a>1. 隐藏powered by</h4><p>打开<strong>主题配置文件</strong>,查找 <code>footer</code> 字段,修改其中 <code>powered</code> 和 <code>theme.enable</code> 为 <code>false</code></p><h4 id="2-添加访问统计"><a href="#2-添加访问统计" class="headerlink" title="2. 添加访问统计"></a>2. 添加访问统计</h4><p>打开 <code>./themes/next/layout/_partials/footer.swig</code> 文件,在第一行添加</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">async</span> <span class="attr">src</span>=<span class="string">"https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br></pre></td></tr></table></figure><p>查找 <code>theme.post_wordcount.totalcount</code> ,在前面添加</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">br</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">span</span> <span class="attr">id</span>=<span class="string">"busuanzi_container_site_uv"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"fa fa-user"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> 本站访客数:<span class="tag"><<span class="name">span</span> <span class="attr">id</span>=<span class="string">"busuanzi_value_site_uv"</span>></span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"><span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"busuanzi_container_site_pv"</span>></span>|<span class="tag"></<span class="name">span</span>></span></span><br><span class="line"><span class="tag"><<span class="name">span</span> <span class="attr">id</span>=<span class="string">"busuanzi_container_site_pv"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"fa fa-eye"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> 累计访问次数:<span class="tag"><<span class="name">span</span> <span class="attr">id</span>=<span class="string">"busuanzi_value_site_pv"</span>></span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"><span class="tag"></<span class="name">span</span>></span></span><br></pre></td></tr></table></figure><p>重新生成即可</p><h4 id="3-添加全站字数统计"><a href="#3-添加全站字数统计" class="headerlink" title="3. 添加全站字数统计"></a>3. 添加全站字数统计</h4><p>在博客根目录下执行命令</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install hexo-wordcount --save</span><br></pre></td></tr></table></figure><p>仍然在 <code>footer.swig</code> 文件内,在刚才的 <code><br/></code> 标签上面添加</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"theme-info"</span>></span>|<span class="tag"></<span class="name">span</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"theme-info"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"powered-by"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"fa fa-bar-chart"</span>></span><span class="tag"></<span class="name">i</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"post-count"</span>></span>博客全站共{{ totalcount(site) }}字<span class="tag"></<span class="name">span</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><p><strong>注:这里发现底部字体看不清楚,可以改为白色</strong></p><p>打开 <code>./themes/next/source/css/_common/components/footer/footer.styl</code> 文件修改其中的 <code>.footer</code> 为</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.footer</span> {</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">14px</span>;</span><br><span class="line"> <span class="comment">// color: $grey-dark;</span></span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#FFFFFF</span>;</span><br><span class="line"> <span class="attribute">opacity</span>: <span class="number">0.9</span></span><br><span class="line"> <span class="selector-tag">img</span> { <span class="attribute">border</span>: none; }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="4-修改作者前面的图标为心形"><a href="#4-修改作者前面的图标为心形" class="headerlink" title="4. 修改作者前面的图标为心形"></a>4. 修改作者前面的图标为心形</h4><p>在<strong>主题配置文件</strong>中查找 <code>footer</code> 字段,修改 <code>icon</code> 为 <code>heart</code> 即可。</p><h3 id="三、添加标签失去焦点后标题改变"><a href="#三、添加标签失去焦点后标题改变" class="headerlink" title="三、添加标签失去焦点后标题改变"></a>三、添加标签失去焦点后标题改变</h3><p>在<strong>主题配置文件</strong>中添加</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># a trick on website title</span></span><br><span class="line"><span class="attr">title_trick:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">leave:</span> <span class="string">"(つェ⊂)我藏好了哦~"</span></span><br><span class="line"> <span class="attr">enter:</span> <span class="string">"(*´∇`*) 被你发现啦~"</span></span><br></pre></td></tr></table></figure><p>其中leave表示失去焦点后得到标题,enter表示重新获取焦点时的标题,可以自己修改。</p><p>在 <code>./themes/next/layout/_custom/</code> 文件夹下,新建文件 <code>custom.swig</code> ,将以下内容填入</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">{# 搞怪网页标题 #} </span><br><span class="line">{% if theme.title_trick.enable %}</span><br><span class="line"><span class="tag"><<span class="name">script</span>></span></span><br><span class="line"><span class="javascript"> <span class="keyword">var</span> OriginTitile = <span class="built_in">document</span>.title;</span></span><br><span class="line"><span class="actionscript"> <span class="keyword">var</span> titleTime;</span></span><br><span class="line"><span class="javascript"> <span class="built_in">document</span>.addEventListener(<span class="string">"visibilitychange"</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span></span><br><span class="line"><span class="javascript"> <span class="keyword">if</span> (<span class="built_in">document</span>.hidden) {</span></span><br><span class="line"><span class="javascript"> <span class="built_in">document</span>.title = <span class="string">"{{ theme.title_trick.leave }}"</span> + OriginTitile;</span></span><br><span class="line"> clearTimeout(titleTime);</span><br><span class="line"><span class="actionscript"> } <span class="keyword">else</span> {</span></span><br><span class="line"><span class="javascript"> <span class="built_in">document</span>.title = <span class="string">"{{ theme.title_trick.enter }}"</span> + OriginTitile;</span></span><br><span class="line"><span class="actionscript"> titleTime = setTimeout(<span class="function"><span class="keyword">function</span><span class="params">()</span> </span>{</span></span><br><span class="line"><span class="javascript"> <span class="built_in">document</span>.title = OriginTitile;</span></span><br><span class="line"> }, 2000);</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"><span class="tag"></<span class="name">script</span>></span></span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><p>在 <code>./themes/next/layout/_layout.swig</code> 中末尾的一堆 <code>include</code> 后面添加</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{% include '_custom/custom.swig' %}</span><br></pre></td></tr></table></figure><h3 id="四、添加打字特效"><a href="#四、添加打字特效" class="headerlink" title="四、添加打字特效"></a>四、添加打字特效</h3><p><strong>注:当前打字特效似乎没什么用,这个会在后续的添加评论的文章中再次提到,主要用于评论区,现在可以在任意一个代码块上测试(发布的文章内的代码块是可以编辑的,刷新后会恢复)</strong></p><p>点击 <a href="/js/src/activate-power-mode.min.js">打字特效</a> 按 <code>Ctrl+S</code> 保存到本地 <code>./themes/next/source/js/scr/</code> 文件夹下</p><p>在<strong>主题配置文件</strong>中添加</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># typing effect</span></span><br><span class="line"><span class="attr">typing_effect:</span></span><br><span class="line"> <span class="attr">colorful:</span> <span class="literal">true</span> <span class="comment"># 礼花特效</span></span><br><span class="line"> <span class="attr">shake:</span> <span class="literal">false</span> <span class="comment"># 震动特效</span></span><br></pre></td></tr></table></figure><p>其中两种效果可以自由选择是否开启</p><p>在前面创建的 <code>./themes/next/layout/_custom/custom.styl</code> 文件末尾添加</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">{# 打字特效 #}</span><br><span class="line">{% if theme.typing_effect %}</span><br><span class="line"> <script src=<span class="string">"/js/src/activate-power-mode.min.js"</span>></script></span><br><span class="line"> <script></span><br><span class="line"> POWERMODE.colorful = {{ theme.typing_effect.colorful }};</span><br><span class="line"> POWERMODE.shake = {{ theme.typing_effect.shake }};</span><br><span class="line"> document.body.addEventListener('input', POWERMODE);</span><br><span class="line"> </script></span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><hr><p>参考内容:</p><p><a href="https://blog.ihoey.com/posts/Hexo/2018-05-27-hexo-code-block.html" target="_blank" rel="noopener">Hexo 博客美化代码块</a></p><p><a href="http://shenzekun.cn/hexo的next主题个性化配置教程.html" target="_blank" rel="noopener">hexo的next主题个性化配置教程</a></p>]]></content>
<categories>
<category> blog </category>
<category> 2.美化 </category>
</categories>
<tags>
<tag> blog </tag>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>Hexo+Next+GitHub博客搭建超详细教程--美化篇(2)</title>
<link href="/posts/blog-building/beautify-2/"/>
<url>/posts/blog-building/beautify-2/</url>
<content type="html"><![CDATA[<h3 id="一、添加背景音乐"><a href="#一、添加背景音乐" class="headerlink" title="一、添加背景音乐"></a>一、添加背景音乐</h3><p><strong>注:本教程是以 <code>NexT</code> 主题的 <code>Gemini</code> 方案为例,修改后不再适用其他方案,若还有修改主题方案的需求请不要按本教程设置。</strong></p><h4 id="1-创建网易云歌单"><a href="#1-创建网易云歌单" class="headerlink" title="1. 创建网易云歌单"></a>1. 创建网易云歌单</h4><p>注册<a href="https://music.163.com/" target="_blank" rel="noopener">网易云</a>账号并登陆,点击上方<strong>我的音乐</strong>,创建的歌单右侧<strong>新建</strong>,输入歌单名等信息,创建成功后打开歌单,地址栏为 <code>https://music.163.com/#/my/m/music/playlist?id=5062858339</code> ,其中 <code>id</code> 后面的就是歌单号,复制下来后面会用到。之后向歌单中添加音乐博客上也可以同步更新,但是有一定的延时。</p><p>当然也可以使用别人的歌单,找到自己喜欢的歌单复制地址中的歌单号即可。</p><h4 id="2-嵌入网页"><a href="#2-嵌入网页" class="headerlink" title="2. 嵌入网页"></a>2. 嵌入网页</h4><p>在<strong>主题配置文件</strong>中添加</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># background music</span></span><br><span class="line"><span class="attr">music:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">Aplayer:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">iframe:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">list_id:</span> <span class="string">'5062858339'</span></span><br><span class="line"> <span class="attr">auto_play:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure><p>其中 <code>Aplayer</code> 和 <code>iframe</code> 是添加背景音乐的<strong>两种方式</strong>,值为 <code>true</code> 表示启用这种方式, <code>liet_id</code> 是网易云的<strong>歌单号</strong>, <code>auto_play</code> 是是否<strong>自动播放</strong>。我这里启用Aplayer,并且不自动播放,你可以选择自己喜欢的样式。</p><p>在 <code>./themes/next/layout/_macro/sidebar.swig</code> 中 <code>{if theme.sierbar.b2t}</code> <strong>前面</strong>添加以下内容</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--背景音乐--></span></span><br><span class="line">{%if theme.music.enable %}</span><br><span class="line"> <span class="tag"><<span class="name">br</span>/></span></span><br><span class="line"> {% if theme.music.iframe %}</span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"music1"</span> ></span></span><br><span class="line"> <span class="tag"><<span class="name">iframe</span> <span class="attr">frameborder</span>=<span class="string">"no"</span> <span class="attr">border</span>=<span class="string">"0"</span> <span class="attr">marginwidth</span>=<span class="string">"0"</span> <span class="attr">marginheight</span>=<span class="string">"0"</span> <span class="attr">width</span>=<span class="string">280</span> <span class="attr">height</span>=<span class="string">350</span> <span class="attr">src</span>=<span class="string">"//music.163.com/outchain/player?type=0&id={{ theme.music.list_id }}&auto={% if theme.music.auto_play %}1{% else %}0{% endif %}&height=330"</span>></span><span class="tag"></<span class="name">iframe</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"> {% if theme.music.Aplayer %}</span><br><span class="line"> <span class="comment"><!-- require APlayer --></span></span><br><span class="line"> <span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"https://cdn.jsdelivr.net/npm/[email protected]/dist/APlayer.min.css"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://cdn.jsdelivr.net/npm/[email protected]/dist/APlayer.min.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> <span class="comment"><!-- require MetingJS--></span></span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://cdn.jsdelivr.net/npm/[email protected]/dist/Meting.min.js"</span>></span><span class="tag"></<span class="name">script</span>></span> </span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"music2"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"aplayer"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-id</span>=<span class="string">"{{ theme.music.list_id }}"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-server</span>=<span class="string">"netease"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-type</span>=<span class="string">"playlist"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-fixed</span>=<span class="string">"false"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-autoplay</span>=<span class="string">"{{ theme.music.auto_play }}"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-list-folded</span>=<span class="string">"true"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-loop</span>=<span class="string">"all"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-mutex</span>=<span class="string">"true"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-order</span>=<span class="string">"list"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-volume</span>=<span class="string">"0.2"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">data-theme</span>=<span class="string">"#FADFA3"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">date-preload</span>=<span class="string">"auto"</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><p>其中Aplayer的一些参数介绍如下。</p><table><thead><tr><th align="left">选项</th><th align="left">默认值</th><th align="left">功能描述</th></tr></thead><tbody><tr><td align="left">id</td><td align="left"><strong>必须值</strong></td><td align="left">歌曲 id / 播放列表 id / 相册 id / 搜索关键字</td></tr><tr><td align="left">server</td><td align="left"><strong>必须值</strong></td><td align="left">音乐平台: <code>netease</code>, <code>tencent</code>, <code>kugou</code>, <code>xiami</code>, <code>baidu</code></td></tr><tr><td align="left">type</td><td align="left"><strong>必须值</strong></td><td align="left"><code>song</code>, <code>playlist</code>, <code>album</code>, <code>search</code>, <code>artist</code></td></tr><tr><td align="left">fixed</td><td align="left"><code>false</code></td><td align="left">开启固定模式</td></tr><tr><td align="left">autoplay</td><td align="left"><code>false</code></td><td align="left">自动播放</td></tr><tr><td align="left">theme</td><td align="left"><code>#2980b9</code></td><td align="left">播放器风格色彩设置</td></tr><tr><td align="left">order</td><td align="left"><code>list</code></td><td align="left">列表播放模式: <code>list</code>, <code>random</code></td></tr><tr><td align="left">preload</td><td align="left"><code>auto</code></td><td align="left">音乐文件预载入模式,可选项: <code>none</code>, <code>metadata</code>, <code>auto</code></td></tr><tr><td align="left">volume</td><td align="left"><code>0.7</code></td><td align="left">播放器音量</td></tr><tr><td align="left">mutex</td><td align="left"><code>true</code></td><td align="left">该选项开启时,如果同页面有其他 aplayer 播放,该播放器会暂停</td></tr><tr><td align="left">list-folded</td><td align="left"><code>false</code></td><td align="left">歌词格式类型</td></tr></tbody></table><p>在 <code>./themes/next/source/css/_schemes/Gemini/index.styl</code> 的<strong>末尾</strong>添加</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.music1</span> {</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">260px</span>;</span><br><span class="line"> <span class="attribute">transform</span>: translate(-<span class="number">7.7%</span>, <span class="number">0%</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.music2</span> {</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">238px</span>;</span><br><span class="line"> <span class="attribute">transform</span>: translate(-<span class="number">4%</span>, <span class="number">0%</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>添加这个的原因是两个音乐标签都比较宽,而侧边栏比较窄,如果按照默认的方式,会改变标签的布局来适应侧边栏的宽度,导致一些按钮位置重叠。这里是<strong>强行加宽</strong>并向左移动至侧边栏中央。</p><p><strong>两种方式的区别</strong>:</p><ul><li>iframe图片显示的是歌单的封面图,名字显示的是歌单名;可以拖动播放进度条;歌单列表默认开启,收回后侧边栏大小不随之改变。</li><li>Aplayer图片是歌曲海报,名字是歌曲名,有歌词;<strong>不可以</strong>拖动进度条(原本可以,这里由于侧边栏太窄牺牲了进度条,可以看到时间左边的小点就是原来的进度条,但是太小以至于无法使用);歌单列表默认关闭,打开后侧边栏随之边长,关闭随之变短。</li></ul><h4 id="3-效果展示"><a href="#3-效果展示" class="headerlink" title="3. 效果展示"></a>3. 效果展示</h4><p>注:这里为了展示两种方法都开启了,实际使用过程只需开启一个即可</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beautify-2/music.png" alt=""></p><h3 id="二、鼠标点击特效"><a href="#二、鼠标点击特效" class="headerlink" title="二、鼠标点击特效"></a>二、鼠标点击特效</h3><p>将以下文件放在 <code>./themes/next/source/js/src</code> 文件夹下。</p><p><a href="/js/src/firework.js">烟花效果</a> <a href="/js/src/clicklove.js">心形</a> <a href="/js/src/text.js">文字</a> <a href="/js/src/explosion.js">爆炸</a></p><p>(打开后按 <code>Ctrl+S</code> 可以保存到本地) </p><p>其中文字内容可以自定义,博主在网上其他教程的基础上加入了颜色随机变化。</p><p>如果某个效果自己不需要也可以不下载</p><p>在<strong>主题配置文件</strong>中添加</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Click effect</span></span><br><span class="line"><span class="attr">click_effect:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">clicklove:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">fireworks:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">text:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">explosion:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure><p>四个效果可以选择其一或者多个开启</p><p>在 <code>./themes/next/layout/_layout.swug</code> 中 <strong><code></body></code></strong> 前添加</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!-- 鼠标点击效果 --></span></span><br><span class="line">{% if theme.click_effect.enable %}</span><br><span class="line"> <span class="comment"><!-- 小红心 --></span></span><br><span class="line"> {% if theme.click_effect.clicklove %}</span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">src</span>=<span class="string">"/js/src/clicklove.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"> <span class="comment"><!-- 烟花 --></span></span><br><span class="line"> {% if theme.click_effect.fireworks %}</span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">src</span>=<span class="string">"/js/src/firework.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"> <span class="comment"><!-- 文字 --></span></span><br><span class="line"> {% if theme.click_effect.text %}</span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">async</span> <span class="attr">src</span>=<span class="string">"/js/src/text.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"> <span class="comment"><!-- 爆炸 --></span></span><br><span class="line"> {% if theme.click_effect.explosion %}</span><br><span class="line"> <span class="tag"><<span class="name">canvas</span> <span class="attr">class</span>=<span class="string">"fireworks"</span> <span class="attr">style</span>=<span class="string">"position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;"</span> ></span><span class="tag"></<span class="name">canvas</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">src</span>=<span class="string">"//cdn.bootcss.com/animejs/2.2.0/anime.min.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">src</span>=<span class="string">"/js/src/explosion.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><h3 id="三、文章底部优化"><a href="#三、文章底部优化" class="headerlink" title="三、文章底部优化"></a>三、文章底部优化</h3><h4 id="1-添加文章结束标志"><a href="#1-添加文章结束标志" class="headerlink" title="1. 添加文章结束标志"></a>1. 添加文章结束标志</h4><p>在 <code>./themes/next/layout/_macro</code> 文件夹中新建 <code>passage-end-tag.swig</code> 文件,将以下内容填入</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span>></span></span><br><span class="line"> {% if not is_index %}</span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">style</span>=<span class="string">"text-align:center;color: #ccc;font-size:14px;"</span>></span>-------------本文结束<span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"fa fa-heartbeat"</span>></span><span class="tag"></<span class="name">i</span>></span>感谢您的阅读-------------<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><p>修改 <code>./themes/next/layout/_macro/post.swig</code>,查找</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">{#####################}</span><br><span class="line">{### END POST BODY ###}</span><br><span class="line">{#####################}</span><br></pre></td></tr></table></figure><p>在<strong>后面</strong>添加以下代码:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">{# end-tag #}</span><br><span class="line">{% if theme.end_tag.enable and not is_index %}</span><br><span class="line"> <div></span><br><span class="line"> {% include 'passage-end-tag.swig' %}</span><br><span class="line"> </div></span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><p>在<strong>主题配置文件</strong>中添加以下内容</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># passage_end_tag</span></span><br><span class="line"><span class="attr">end_tag:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>效果如下:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beautify-2/end-tag.png" alt=""></p><h4 id="2-添加版权信息"><a href="#2-添加版权信息" class="headerlink" title="2. 添加版权信息"></a>2. 添加版权信息</h4><p>在 <code>./themes/next/layout/_macro/</code> 文件夹内新建 <code>my-copyright.swig</code> 文件,将以下内容填入</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">{% if page.copyright %}</span><br><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"my_post_copyright"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"//cdn.bootcss.com/clipboard.js/1.5.10/clipboard.min.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"><!-- JS库 sweetalert 可修改路径 --></span></span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://cdn.bootcss.com/jquery/2.0.0/jquery.min.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://unpkg.com/sweetalert/dist/sweetalert.min.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span><span class="tag"><<span class="name">span</span>></span>本文标题:<span class="tag"></<span class="name">span</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"{{ url_for(page.path) }}"</span>></span>{{ page.title }}<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span><span class="tag"><<span class="name">span</span>></span>文章作者:<span class="tag"></<span class="name">span</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/"</span> <span class="attr">title</span>=<span class="string">"访问 {{ theme.author }} 的个人博客"</span>></span>{{ theme.author }}<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span><span class="tag"><<span class="name">span</span>></span>发布时间:<span class="tag"></<span class="name">span</span>></span>{{ page.date.format("YYYY年MM月DD日 - HH:mm") }}<span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span><span class="tag"><<span class="name">span</span>></span>最后更新:<span class="tag"></<span class="name">span</span>></span>{{ page.updated.format("YYYY年MM月DD日 - HH:mm") }}<span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span><span class="tag"><<span class="name">span</span>></span>原始链接:<span class="tag"></<span class="name">span</span>></span><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"{{ url_for(page.path) }}"</span> <span class="attr">title</span>=<span class="string">"{{ page.title }}"</span>></span>{{ page.permalink }}<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"copy-path"</span> <span class="attr">title</span>=<span class="string">"点击复制文章链接"</span>></span><span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"fa fa-copy"</span> <span class="attr">data-clipboard-text</span>=<span class="string">"{{ page.permalink }}"</span> <span class="attr">aria-label</span>=<span class="string">"复制成功!"</span>></span><span class="tag"></<span class="name">i</span>></span><span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">p</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">p</span>></span><span class="comment"><!--<span>许可协议:</span><i class="fa fa-creative-commons"></i> <a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a>--></span> 转载请保留原文链接及作者。<span class="tag"></<span class="name">p</span>></span> </span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span> </span><br><span class="line"><span class="actionscript"> <span class="keyword">var</span> clipboard = <span class="keyword">new</span> Clipboard(<span class="string">'.fa-copy'</span>);</span></span><br><span class="line"><span class="javascript"> $(<span class="string">".fa-copy"</span>).click(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span></span><br><span class="line"><span class="actionscript"> clipboard.on(<span class="string">'success'</span>, <span class="function"><span class="keyword">function</span><span class="params">()</span></span>{</span></span><br><span class="line"> swal({ </span><br><span class="line"><span class="actionscript"> title: <span class="string">""</span>, </span></span><br><span class="line"><span class="actionscript"> text: <span class="string">'复制成功'</span>,</span></span><br><span class="line"><span class="actionscript"> icon: <span class="string">"success"</span>, </span></span><br><span class="line"><span class="actionscript"> showConfirmButton: <span class="literal">true</span></span></span><br><span class="line"> });</span><br><span class="line">});</span><br><span class="line"> }); </span><br><span class="line"><span class="tag"></<span class="name">script</span>></span></span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><p>在 <code>./themes/next/source/css/_common/post/</code> 文件夹下新建文件 <code>my-post-copyright.styl</code> ,填入以下内容</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.my_post_copyright</span> {</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">85%</span>;</span><br><span class="line"> <span class="attribute">max-width</span>: <span class="number">45em</span>;</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">2.8em</span> auto <span class="number">0</span>;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">0.5em</span> <span class="number">1.0em</span>;</span><br><span class="line"> <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#d3d3d3</span>;</span><br><span class="line"> <span class="attribute">font-size</span>: <span class="number">0.93rem</span>;</span><br><span class="line"> <span class="attribute">line-height</span>: <span class="number">1.6em</span>;</span><br><span class="line"> <span class="attribute">word-break</span>: break-all;</span><br><span class="line"> <span class="attribute">background</span>: rgba(<span class="number">255</span>,<span class="number">255</span>,<span class="number">255</span>,<span class="number">0.4</span>);</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.my_post_copyright</span> p{<span class="attribute">margin</span>:<span class="number">0</span>;}</span><br><span class="line"><span class="selector-class">.my_post_copyright</span> <span class="selector-tag">span</span> {</span><br><span class="line"> <span class="attribute">display</span>: inline-block;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">5.2em</span>;</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#b5b5b5</span>;</span><br><span class="line"> <span class="attribute">font-weight</span>: bold;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.my_post_copyright</span> <span class="selector-class">.raw</span> {</span><br><span class="line"> <span class="attribute">margin-left</span>: <span class="number">1em</span>;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">5em</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.my_post_copyright</span> <span class="selector-tag">a</span> {</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#808080</span>;</span><br><span class="line"> <span class="attribute">border-bottom</span>:<span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.my_post_copyright</span> <span class="selector-tag">a</span>:hover {</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#a3d2a3</span>;</span><br><span class="line"> <span class="attribute">text-decoration</span>: underline;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.my_post_copyright</span>:hover <span class="selector-class">.fa-clipboard</span> {</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#000</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.my_post_copyright</span> <span class="selector-class">.post-url</span>:hover {</span><br><span class="line"> <span class="attribute">font-weight</span>: normal;</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.my_post_copyright</span> <span class="selector-class">.copy-path</span> {</span><br><span class="line"> <span class="attribute">margin-left</span>: <span class="number">1em</span>;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">1em</span>;</span><br><span class="line"> +mobile(){<span class="attribute">display</span>:none;}</span><br><span class="line">}</span><br><span class="line"><span class="selector-class">.my_post_copyright</span> <span class="selector-class">.copy-path</span>:hover {</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#808080</span>;</span><br><span class="line"> <span class="attribute">cursor</span>: pointer;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>修改 <code>./themes/next/layout/_macro/post.swig</code>,在刚才添加文章结束标志的<strong>后面</strong>添加以下代码:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">{# copyright #}</span><br><span class="line">{% if theme.my_copyright.enable and not is_index %}</span><br><span class="line"> <span class="tag"><<span class="name">div</span>></span></span><br><span class="line"> {% include 'my-copyright.swig' %}</span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><p>打开 <code>./themes/next/source/css/_common/components/post/post.styl</code> ,在最后一行增加代码:</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">@import <span class="string">"my-post-copyright"</span></span><br></pre></td></tr></table></figure><p>在<strong>主题配置文件</strong>中添加以下内容</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># my-copyright</span></span><br><span class="line"><span class="attr">my_copyright:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>效果如下:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beautify-2/copyright.png" alt=""></p><p>如果得到的 “原始链接” 像我一样是 <code>http://yoursite.com</code> 开头,那你就要修改<strong>站点配置文件</strong>中 <code>url</code> 字段为你自己的博客地址。</p><h4 id="3-标签添加图标"><a href="#3-标签添加图标" class="headerlink" title="3. 标签添加图标"></a>3. 标签添加图标</h4><p>在文件 <code>./themes/next/layout/_macro/post.swig</code> 中,搜索 <code>rel="tag">#</code> ,将 <code>#</code> 换成 <code><i class="fa fa-tag"></i></code> 。</p><p>效果如下:</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beautify-2/tag.png" alt=""></p><hr><p>参考内容:</p><p><a href="http://shenzekun.cn/hexo的next主题个性化配置教程.html" target="_blank" rel="noopener">hexo的next主题个性化配置教程</a></p><p><a href="https://blog.csdn.net/qq_45533937/article/details/105496572" target="_blank" rel="noopener">Hexo + Next 主题实现全局播放背景音乐</a></p>]]></content>
<categories>
<category> blog </category>
<category> 2.美化 </category>
</categories>
<tags>
<tag> blog </tag>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>Hexo+Next+GitHub博客搭建超详细教程--美化篇(1)</title>
<link href="/posts/blog-building/beautify-1/"/>
<url>/posts/blog-building/beautify-1/</url>
<content type="html"><![CDATA[<h3 id="一、添加背景"><a href="#一、添加背景" class="headerlink" title="一、添加背景"></a>一、添加背景</h3><h4 id="1-添加动态背景"><a href="#1-添加动态背景" class="headerlink" title="1. 添加动态背景"></a>1. 添加动态背景</h4><p>打开 <code>./themes/next/_config.yml</code> 文件,在其中搜索 <code>canvas_nest</code> ,把 <code>false</code> 改为 <code>true</code> ,重新编译就可以看到出现了线条的动态背景。</p><p>进一步美化可以修改线条的参数:</p><p>打开 <code>./themes/next/source/lib/canvas-nest/canvas-nest.min.js</code> 文件,查找以下参数</p><p><code>opacity</code> -透明度,范围0-1,可以改为自己喜欢的参数,我这里设置的是0.8。</p><p><code>color</code> -颜色,可以设定为自己喜欢的RGB颜色,我这里加入了随机颜色</p><p>将原来的<code>“0,0,0”</code> 改为 <code>c()</code> ,在紧接着的 <code>function k()</code> 之前添加以下代码</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">c</span>(<span class="params"></span>)</span>{<span class="keyword">var</span> r=<span class="built_in">Math</span>.ceil(<span class="built_in">Math</span>.random()*<span class="number">256</span>).toString();<span class="keyword">var</span> g=<span class="built_in">Math</span>.ceil(<span class="built_in">Math</span>.random()*<span class="number">256</span>).toString();<span class="keyword">var</span> b=<span class="built_in">Math</span>.ceil(<span class="built_in">Math</span>.random() * <span class="number">256</span>).toString();<span class="keyword">return</span> r+<span class="string">","</span>+g+<span class="string">","</span>+b}</span><br></pre></td></tr></table></figure><p>这个是生成随机颜色的函数,在 <code>color</code> 处调用。</p><p><code>count</code> -数量,修改为自己喜欢的数量,数量越多,打开网页后占用的CPU就越高,我这里使用的是60。</p><h4 id="2-添加静态背景图"><a href="#2-添加静态背景图" class="headerlink" title="2. 添加静态背景图"></a>2. 添加静态背景图</h4><h5 id="1)添加图片"><a href="#1)添加图片" class="headerlink" title="1)添加图片"></a>1)添加图片</h5><p>打开 <code>./themes/next/source/scc/_custom/custom.styl</code> 文件,在其中添加一下内容</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//背景</span></span><br><span class="line"><span class="selector-tag">body</span> {</span><br><span class="line"> background:url(https://images7.alphacoders.com/103/1030338.jpg);</span><br><span class="line"> <span class="attribute">background-size</span>: cover;</span><br><span class="line"> <span class="attribute">background-repeat</span>: no-repeat;</span><br><span class="line"> <span class="attribute">background-attachment</span>: fixed;</span><br><span class="line"> <span class="attribute">background-position</span>: <span class="number">50%</span> <span class="number">50%</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>其中的url可以换成自己喜欢的背景图。但是不建议使用较大的高清图片,否则就会像我这个一样打开很慢(逃</p><p>如果图片被缩放显示的位置不太理想,可以微调 <code>background-position</code> 里的两个数值,每次调整后重新编译查看效果。</p><h5 id="2)修改透明度"><a href="#2)修改透明度" class="headerlink" title="2)修改透明度"></a>2)修改透明度</h5><p>同样在 <code>custom.styl</code> 文件内继续添加</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 修改主体透明度</span></span><br><span class="line"><span class="selector-class">.main-inner</span> {</span><br><span class="line"> <span class="attribute">background</span>: <span class="number">#2078BF</span>;</span><br><span class="line"> <span class="attribute">opacity</span>: <span class="number">0.85</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 修改菜单栏透明度</span></span><br><span class="line"><span class="selector-class">.header-inner</span> {</span><br><span class="line"> <span class="attribute">opacity</span>: <span class="number">0.85</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="3)首页文章添加阴影效果"><a href="#3)首页文章添加阴影效果" class="headerlink" title="3)首页文章添加阴影效果"></a>3)首页文章添加阴影效果</h5><p>在 <code>custom.styl</code> 中继续添加</p><figure class="highlight styl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 主页文章添加阴影效果</span></span><br><span class="line"><span class="selector-class">.post</span> {</span><br><span class="line"> <span class="attribute">margin-top</span>: <span class="number">30px</span>;</span><br><span class="line"> <span class="attribute">margin-bottom</span>: <span class="number">40px</span>;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">5px</span>;</span><br><span class="line"> -webkit-<span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">0</span> <span class="number">5px</span> rgba(<span class="number">202</span>, <span class="number">203</span>, <span class="number">203</span>, <span class="number">1</span>);</span><br><span class="line"> -moz-<span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">0</span> <span class="number">5px</span> rgba(<span class="number">202</span>, <span class="number">203</span>, <span class="number">204</span>, <span class="number">1</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>得到的效果图如下</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beautify-1/background-1.png" alt=""></p><h3 id="二、侧边栏美化"><a href="#二、侧边栏美化" class="headerlink" title="二、侧边栏美化"></a>二、侧边栏美化</h3><h4 id="1-添加作者头像并旋转"><a href="#1-添加作者头像并旋转" class="headerlink" title="1. 添加作者头像并旋转"></a>1. 添加作者头像并旋转</h4><p>打开文件夹 <code>./themes/next/source/images</code> ,将自己的头像放入其中</p><p>在主题配置文件中找到 <code>avator</code> 字段,取消注释,修改 <code>avator.gif</code> 为自己的头像的文件名</p><p>打开<code>./themes/next/source/css/_common/components/sidebar/sidebar-author.styl</code>,在将其中的 <code>site-author-image</code> 替换为以下代码:</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.site-author-image</span> {</span><br><span class="line"> <span class="attribute">display</span>: block;</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">0</span> auto;</span><br><span class="line"> <span class="attribute">padding</span>: <span class="variable">$site</span>-author-image-padding;</span><br><span class="line"> <span class="attribute">max-width</span>: <span class="variable">$site</span>-author-image-width;</span><br><span class="line"> <span class="attribute">height</span>: <span class="variable">$site</span>-author-image-height;</span><br><span class="line"> <span class="attribute">border</span>: <span class="variable">$site</span>-author-image-border-width solid <span class="variable">$site</span>-author-image-border-color;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* 头像圆形 */</span></span><br><span class="line"> <span class="attribute">border-radius</span>: <span class="number">80px</span>;</span><br><span class="line"> -webkit-<span class="attribute">border-radius</span>: <span class="number">80px</span>;</span><br><span class="line"> -moz-<span class="attribute">border-radius</span>: <span class="number">80px</span>;</span><br><span class="line"> <span class="attribute">box-shadow</span>: inset <span class="number">0</span> -<span class="number">1px</span> <span class="number">0</span> <span class="number">#333</span>sf;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* 设置循环动画 [animation: (play)动画名称 (2s)动画播放时长单位秒或微秒 (ase-out)动画播放的速度曲线为以低速结束 </span></span><br><span class="line"><span class="comment"> (1s)等待1秒然后开始动画 (1)动画播放次数(infinite为循环播放) ]*/</span></span><br><span class="line"> </span><br><span class="line"></span><br><span class="line"> <span class="comment">/* 鼠标经过头像旋转360度 */</span></span><br><span class="line"> -webkit-<span class="attribute">transition</span>: -webkit-transform <span class="number">1.0s</span> ease-out;</span><br><span class="line"> -moz-<span class="attribute">transition</span>: -moz-transform <span class="number">1.0s</span> ease-out;</span><br><span class="line"> <span class="attribute">transition</span>: transform <span class="number">1.0s</span> ease-out;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-tag">img</span>:hover {</span><br><span class="line"> <span class="comment">/* 鼠标经过停止头像旋转 </span></span><br><span class="line"><span class="comment"> -webkit-animation-play-state:paused;</span></span><br><span class="line"><span class="comment"> animation-play-state:paused;*/</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/* 鼠标经过头像旋转360度 */</span></span><br><span class="line"> -webkit-<span class="attribute">transform</span>: rotateZ(<span class="number">360deg</span>);</span><br><span class="line"> -moz-<span class="attribute">transform</span>: rotateZ(<span class="number">360deg</span>);</span><br><span class="line"> <span class="attribute">transform</span>: rotateZ(<span class="number">360deg</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Z 轴旋转动画 */</span></span><br><span class="line">@-webkit-keyframes play {</span><br><span class="line"> <span class="number">0%</span> {</span><br><span class="line"> -webkit-<span class="attribute">transform</span>: rotateZ(<span class="number">0deg</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="number">100%</span> {</span><br><span class="line"> -webkit-<span class="attribute">transform</span>: rotateZ(-<span class="number">360deg</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">@-moz-keyframes play {</span><br><span class="line"> <span class="number">0%</span> {</span><br><span class="line"> -moz-<span class="attribute">transform</span>: rotateZ(<span class="number">0deg</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="number">100%</span> {</span><br><span class="line"> -moz-<span class="attribute">transform</span>: rotateZ(-<span class="number">360deg</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">@keyframes play {</span><br><span class="line"> <span class="number">0%</span> {</span><br><span class="line"> <span class="attribute">transform</span>: rotateZ(<span class="number">0deg</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="number">100%</span> {</span><br><span class="line"> <span class="attribute">transform</span>: rotateZ(-<span class="number">360deg</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="2-修改标题颜色背景"><a href="#2-修改标题颜色背景" class="headerlink" title="2. 修改标题颜色背景"></a>2. 修改标题颜色背景</h4><p>依旧在 <code>custom.styl</code> 文件中,添加以下代码</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//题头颜色(背景)</span></span><br><span class="line"><span class="selector-class">.site-meta</span> {</span><br><span class="line"> background:url(https://images5.alphacoders.com/103/1033113.png);</span><br><span class="line"> <span class="attribute">background-size</span>: cover;</span><br><span class="line"> <span class="attribute">background-repeat</span>: no-repeat;</span><br><span class="line"> <span class="attribute">opacity</span>: <span class="number">1</span>;</span><br><span class="line"> <span class="attribute">background-position</span>: <span class="number">50%</span> <span class="number">63%</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">60px</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//主标题颜色</span></span><br><span class="line">.brand{</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#91FAFE</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//副标题颜色</span></span><br><span class="line">.site-subtitle{</span><br><span class="line"> <span class="attribute">color</span>: <span class="number">#91FAFE</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//TOC目录默认全部展开</span></span><br><span class="line"><span class="selector-class">.post-toc</span> <span class="selector-class">.nav</span> <span class="selector-class">.nav-child</span> {</span><br><span class="line"> <span class="attribute">display</span>: block;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>背景的url可以改为自己的图片,同样建议不要太大,否则还是会像我这个一样打开很慢。</p><p>高度可以根据自己的副标题的文字多少调整至可以显示完整。我这里直接去掉了副标题,所以使用40px。</p><h4 id="3-添加阅读进度百分比"><a href="#3-添加阅读进度百分比" class="headerlink" title="3. 添加阅读进度百分比"></a>3. 添加阅读进度百分比</h4><p>在主题配置文件中搜索 <code>scrollpercent</code> 将其值改为 <code>true</code> 即可。</p><p>改为侧边栏显示,可以把上面的 <code>b2t</code> 的值改为 <code>true</code></p><h3 id="三、添加右上角-“fork-me-on-github”"><a href="#三、添加右上角-“fork-me-on-github”" class="headerlink" title="三、添加右上角 “fork me on github”"></a>三、添加右上角 “fork me on github”</h3><p>点击<a href="https://github.com/blog/273-github-ribbons" target="_blank" rel="noopener">这里</a>或者<a href="http://tholman.com/github-corners/" target="_blank" rel="noopener">这里</a>挑选自己喜欢的样式,并复制代码。</p><p>打开 <code>./themes/next/layout/_layout.swig</code> 文件,在 <code><div class="headband"></div></code> 下面粘贴;</p><p>将其中的 <code>href</code> 改为自己的GitHub地址。</p><p>顺便把 <code><div class="headband"></div></code> 这一行注释掉(前面加 <code><!--</code> 后面加 <code>--></code> )这一行就是最上面的那个黑条。</p><p>我这里选择的是</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment"><!--fork me--></span></span><br><span class="line"><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"https://github.com/Roc136"</span> <span class="attr">class</span>=<span class="string">"github-corner"</span> <span class="attr">aria-label</span>=<span class="string">"View source on GitHub"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">svg</span> <span class="attr">width</span>=<span class="string">"80"</span> <span class="attr">height</span>=<span class="string">"80"</span> <span class="attr">viewBox</span>=<span class="string">"0 0 250 250"</span> <span class="attr">style</span>=<span class="string">"fill:#fff; color:#151513; position: absolute; top: 0; border: 0; right: 0;"</span> <span class="attr">aria-hidden</span>=<span class="string">"true"</span> <span class="attr">z-index:</span> <span class="attr">10</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">path</span> <span class="attr">d</span>=<span class="string">"M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"</span> <span class="attr">opacity</span>=<span class="string">0.5</span>></span><span class="tag"></<span class="name">path</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">path</span> <span class="attr">d</span>=<span class="string">"M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"</span> <span class="attr">fill</span>=<span class="string">"currentColor"</span> <span class="attr">style</span>=<span class="string">"transform-origin: 130px 106px;"</span> <span class="attr">class</span>=<span class="string">"octo-arm"</span>></span><span class="tag"></<span class="name">path</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">path</span> <span class="attr">d</span>=<span class="string">"M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"</span> <span class="attr">fill</span>=<span class="string">"currentColor"</span> <span class="attr">class</span>=<span class="string">"octo-body"</span>></span><span class="tag"></<span class="name">path</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">svg</span>></span></span><br><span class="line"><span class="tag"></<span class="name">a</span>></span></span><br></pre></td></tr></table></figure><p>我顺便修改了透明度,在第一个 <code><path></code> 标签内添加 <code>opacity=0.5</code> 。</p><h3 id="四、设置主页只显示缩略内容或描述内容"><a href="#四、设置主页只显示缩略内容或描述内容" class="headerlink" title="四、设置主页只显示缩略内容或描述内容"></a>四、设置主页只显示缩略内容或描述内容</h3><p>在主题配置文件中查找 <code>auto_excerpt</code> 将 <code>enable</code> 字段改为 <code>true</code> ,<code>length</code> 为显示的长度。</p><p>但是官方不推荐自动摘要长度,可以在文章中添加 <code><!--more--></code> 来精确控制摘要长度。</p><p>此外,还可以再文章标题部分添加描述文字(<code>description</code>)。</p><p>当然这几种方法是互相不冲突的,我选择把自动控制摘要长度打开,这样发布文章的时候如果加了描述就显示描述内容,如果不加就使用自动控制摘要长度来显示摘要。</p><p>例如本文的标题部分为</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: 博客搭建超详细教程--美化篇(1)</span><br><span class="line">copyright: true</span><br><span class="line">description: 博客搭建好了,默认的效果自然是不能满足我们的需求的,所以还要对主题进行一些,美化。本文是我们美化的第一步,主要介绍背景和侧边栏的美化,添加右上角 “fork me on github” 已及如何在首页仅显示摘要内容。本文是在上一篇的基础上进行美化,还没有看上一篇的朋友可以先看上一篇。<span class="xml"><span class="tag"><<span class="name">br</span>/></span></span> 博主使用环境:Windows版本:Win10 2004教育版,64位;Node.js 版本:12.18.0-x64</span><br><span class="line">date: 2020-06-17 10:34:33</span><br><span class="line">tags:</span><br><span class="line"><span class="bullet">- </span>Hexo</span><br><span class="line"><span class="bullet">- </span>blog</span><br><span class="line">categories: blog</span><br><span class="line">---</span><br></pre></td></tr></table></figure><p>为了方便每次添加,可以修改文件 <code>./scaffolds/post.md</code> 文件,在其中添加</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">description: 这里显示描述文字</span><br></pre></td></tr></table></figure><p>这样每次new一个新的文章的时候就会自动在标头上加上描述文字的字段。</p><h3 id="最终成果:"><a href="#最终成果:" class="headerlink" title="最终成果:"></a>最终成果:</h3><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beautify-1/forth.png" alt=""></p><hr><p>参考内容:<a href="http://shenzekun.cn/hexo的next主题个性化配置教程.html" target="_blank" rel="noopener">hexo的next主题个性化配置教程</a></p>]]></content>
<categories>
<category> blog </category>
<category> 2.美化 </category>
</categories>
<tags>
<tag> blog </tag>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>Hexo+Next+GitHub博客搭建超详细教程--开始篇</title>
<link href="/posts/blog-building/beginning/"/>
<url>/posts/blog-building/beginning/</url>
<content type="html"><![CDATA[<h3 id="一、环境准备"><a href="#一、环境准备" class="headerlink" title="一、环境准备"></a>一、环境准备</h3><h4 id="1-安装Node-js"><a href="#1-安装Node-js" class="headerlink" title="1. 安装Node.js"></a>1. 安装Node.js</h4><p>由于hexo需要使用npm安装,安装node会附带npm,<a href="https://nodejs.org/zh-cn/" target="_blank" rel="noopener">点击下载Node.js</a>。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beginning/nodejsdownload.png" alt=""></p><p>建议选择长期支持版~</p><p>下载后打开msi格式的安装包,一路点击next即可,如果要改路径的话可以改一下安装路径。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beginning/nodejs_install.png" alt=""></p><h4 id="2-安装git"><a href="#2-安装git" class="headerlink" title="2.安装git"></a>2.安装git</h4><p>Hexo的安装需要使用git,<a href="https://git-scm.com/downloads" target="_blank" rel="noopener">点击下载git</a></p><p>选择Windows版本下载</p><p>具体安装教程详见 <a href="https://www.jianshu.com/p/414ccd423efc" target="_blank" rel="noopener">Git安装教程(Windows安装超详细教程)</a>,这一篇真的是太详细了!</p><h3 id="二、安装Hexo"><a href="#二、安装Hexo" class="headerlink" title="二、安装Hexo"></a>二、安装Hexo</h3><p>创建一个博客专属目录,在当前目录进入命令行</p><p>执行命令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> npm install -g hexo-cli</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> hexo init</span></span><br></pre></td></tr></table></figure><p><code>install</code> 过程可能会出现warning属于正常现象。</p><p><code>init</code> 过程较慢,需耐心等待。</p><p>结束后,该文件夹内出现如下内容则一切正常(版本不同可能会有差别)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">├── .gitignore</span><br><span class="line">├── _config.yml</span><br><span class="line">├── package.json</span><br><span class="line">├── package-lock.json</span><br><span class="line">├── node_modules</span><br><span class="line">| ├── .bin</span><br><span class="line">| ├── @types</span><br><span class="line">|└──...</span><br><span class="line">├── scaffolds</span><br><span class="line">| ├── draft.md</span><br><span class="line">| ├── page.md</span><br><span class="line">|└── post.md</span><br><span class="line">├── source </span><br><span class="line">|└── _posts</span><br><span class="line">└── themes</span><br><span class="line">└──landscape</span><br></pre></td></tr></table></figure><p>继续执行命令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo g</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> hexo s --debug</span></span><br></pre></td></tr></table></figure><p>在浏览器中打开 <a href="http://localhost:4000" target="_blank" rel="noopener">http://localhost:4000</a> 出现如下页面</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beginning/first.png" alt=""></p><p>最开始的博客界面就做好啦~</p><p><code>Ctrl+C</code> 可以结束本地调试。</p><p>但是默认的主题可发挥的空间不大,所以我们要安装一个新的主题Next</p><h3 id="三、安装NexT主题"><a href="#三、安装NexT主题" class="headerlink" title="三、安装NexT主题"></a>三、安装NexT主题</h3><h4 id="1-安装主题"><a href="#1-安装主题" class="headerlink" title="1. 安装主题"></a>1. 安装主题</h4><p>依旧在博客目录下,使用git来clone主题到本地</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> git <span class="built_in">clone</span> https://github.com/iissnan/hexo-theme-next themes/next</span></span><br></pre></td></tr></table></figure><p>过程也会比较慢,耐心等待,结束后会发现 <code>theme</code> 文件夹下多了 <code>next</code> 文件夹</p><p>用文本编辑器(可以使用记事本,这里推荐<a href="https://notepad-plus-plus.org/" target="_blank" rel="noopener">Notepad++</a>或<a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VScode</a>)打开<code>.\_config.yml</code> 文件(以下统称站点配置文件),使用 <code>Ctrl+F</code> 查找 <code>theme</code> 字段,将其值修改为 <code>next</code> 。</p><p>执行命令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo clean</span></span><br></pre></td></tr></table></figure><p>清除上一次编译的缓存</p><p>再执行命令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo g && hexo s</span></span><br></pre></td></tr></table></figure><p>打开 <a href="http://localhost:4000" target="_blank" rel="noopener">http://localhost:4000</a> 检查主题是否改变</p><p>如果显示如下界面则一切正常。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beginning/second.png" alt=""></p><h4 id="2-修改主题方案为Gemini"><a href="#2-修改主题方案为Gemini" class="headerlink" title="2. 修改主题方案为Gemini"></a>2. 修改主题方案为Gemini</h4><p>在主题配置文件中找到 <code>Schemes</code> 字段,将原有 <code>Muse</code> 注释掉,将 <code>Gemini</code> 取消注释,重新编译。</p><h4 id="3-修改标题和作者"><a href="#3-修改标题和作者" class="headerlink" title="3. 修改标题和作者"></a>3. 修改标题和作者</h4><p>打开站点配置文件,找到 <code>Site</code> 字段,修改其中内容</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">title: 博客标题</span><br><span class="line">subtitle: 副标题</span><br><span class="line">descripition: 描述</span><br><span class="line">author: 作者</span><br></pre></td></tr></table></figure><p>重新编译。</p><p><strong>NexT主题的美化会在后续的文章中详细介绍。</strong></p><h3 id="四、增加内容"><a href="#四、增加内容" class="headerlink" title="四、增加内容"></a>四、增加内容</h3><h4 id="1-增加新文章"><a href="#1-增加新文章" class="headerlink" title="1. 增加新文章"></a>1. 增加新文章</h4><p>执行命令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo new your_article_name</span></span><br></pre></td></tr></table></figure><p>会发现 <code>source\_post</code> 文件夹下创建了新文件 <code>your_article_name.md</code> ,编辑文件(支持markdown的文本编辑器有很多,这里推荐 <a href="https://typora.io/" target="_blank" rel="noopener">Typora</a>),写上自己的内容。</p><p>添加标签:</p><p>在标头中的日期下面添加</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">tags:</span><br><span class="line">- Hexo</span><br><span class="line">- blog</span><br><span class="line">categories: blog</span><br></pre></td></tr></table></figure><p>标签可以多个,分类可以多层,均使用 <code>-</code> 标记,。如本文的标签为 <code>Hexo</code> 和 <code>blog</code> ,分类为 <code>blog-搭建</code> 。</p><p>执行命令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo clean && hexo g && hexo s</span></span><br></pre></td></tr></table></figure><p>再次打开 <code>localhost:4000</code> 即可看到自己刚刚写的文章。</p><h4 id="2-增加页面"><a href="#2-增加页面" class="headerlink" title="2. 增加页面"></a>2. 增加页面</h4><p>打开主题配置文件(<code>./theme/next/_config,yml</code>),搜索 <code>menu</code> 字段,将需要添加的页面取消注释,例如about,也可以添加自己的自定义页面,每一行内容分别是 <code>页面名字: /路径/||图标</code>,页面名字会在语言文件(后续会提到)中对应一个显示的名字;路径是在 <code>./source/</code>文件夹中的相对路径, 其中 <code>home</code> 对应 <code>_post</code> 文件夹;图标是在请在 <a href="http://www.fontawesome.com.cn/faicons/" target="_blank" rel="noopener">图标库</a> 中查找。</p><p>注意这里要把路径后面的空格删去。</p><h5 id="1)添加原有页面(以关于页为例):"><a href="#1)添加原有页面(以关于页为例):" class="headerlink" title="1)添加原有页面(以关于页为例):"></a>1)添加原有页面(以关于页为例):</h5><p>取消注释后,执行命令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo new page about</span></span><br></pre></td></tr></table></figure><p>会发现 <code>source</code> 文件夹下多出 <code>about</code> 文件夹,编辑其中的 <code>index.md</code> 文件,写上自己的内容,再次编译即可看到增加了关于页面。</p><p>注:如果是分类和标签页面,需要分别在日期下面添加 <code>type: categories</code> 和 <code>type: tags</code> 字段如下。</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beginning/tags.png" alt=""></p><h5 id="2)添加自定义页面(以留言墙为例):"><a href="#2)添加自定义页面(以留言墙为例):" class="headerlink" title="2)添加自定义页面(以留言墙为例):"></a>2)添加自定义页面(以留言墙为例):</h5><p>在 <code>menu</code> 字段的最后一行添加 <code>wall: /wall/|| pencil-square-o</code></p><p>自行编辑其中内容。</p><p>打开 <code>./theme/next/languages/zh-Hans.yml</code> (简体中文配置文件,其他语言文件类似添加),找到 <code>menu</code> 字段,在下面添加一行 <code>wall: 留言墙</code> 即可。</p><h5 id="3)修改语言(可以不做,默认英文)"><a href="#3)修改语言(可以不做,默认英文)" class="headerlink" title="3)修改语言(可以不做,默认英文)"></a>3)修改语言(可以不做,默认英文)</h5><p>打开站点配置文件,找到 <code>language</code> 字段,修改为想要的语言,例如我这里选择简体中文 <code>zh-Hans</code>,名字就是language文件夹下的文件名。</p><p>清除缓存重新编译发现已经改变语言。</p><h3 id="五、发布到GitHub"><a href="#五、发布到GitHub" class="headerlink" title="五、发布到GitHub"></a>五、发布到GitHub</h3><h4 id="1-注册GitHub账号"><a href="#1-注册GitHub账号" class="headerlink" title="1. 注册GitHub账号"></a>1. 注册GitHub账号</h4><p><a href="https://github.com/" target="_blank" rel="noopener">点击注册</a></p><p>附上一个GitHub<a href="https://www.runoob.com/w3cnote/git-guide.html" target="_blank" rel="noopener">使用教程</a></p><h4 id="2-在GitHub上创建新仓库"><a href="#2-在GitHub上创建新仓库" class="headerlink" title="2. 在GitHub上创建新仓库"></a>2. 在GitHub上创建新仓库</h4><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beginning/create.png" alt=""></p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beginning/create2.png" alt=""></p><p>仓库名字为 <code>username.github.io</code></p><h4 id="3-在本地配置git用户名和密码"><a href="#3-在本地配置git用户名和密码" class="headerlink" title="3. 在本地配置git用户名和密码"></a>3. 在本地配置git用户名和密码</h4><p>执行命令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> git config --global user.name <span class="string">"your username"</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git config --global user.email <span class="string">"you email"</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> ssh-keygen -t rsa -C <span class="string">"your email"</span></span></span><br></pre></td></tr></table></figure><p>连续三次回车(默认路径和无密码)</p><p>在 <code>C:\Users\Yourname\.ssh</code> 下会出现两个文件 <code>id_rsa</code> 和 <code>id_rsa_pub</code> ,用文本编辑器打开 <code>id_rsa.pub</code> ,复制其中的内容</p><p>打开GitHub的 <a href="https://github.com/settings/keys" target="_blank" rel="noopener">SSH key</a> 设置,点击 <code>New SSH key</code>, 在Key栏粘贴刚刚复制的内容,Title可以随意设置</p><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beginning/newssh.png" alt=""></p><p><strong>Tips:</strong> 要配置免密提交,参考:<a href="https://segmentfault.com/a/1190000005125610" target="_blank" rel="noopener">https://segmentfault.com/a/1190000005125610</a></p><h4 id="4-修改本地Hexo配置"><a href="#4-修改本地Hexo配置" class="headerlink" title="4. 修改本地Hexo配置"></a>4. 修改本地Hexo配置</h4><p>打开站点配置文件,找到 <code>deploy</code> 字段,修改内容为</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line"> <span class="attr">type:</span> <span class="string">git</span></span><br><span class="line"> <span class="attr">repo:</span> <span class="string">https://gtihub.com/your_github_username/your_name.github.io.git</span></span><br><span class="line"> <span class="attr">branch:</span> <span class="string">master</span></span><br></pre></td></tr></table></figure><h4 id="5-安装部署工具"><a href="#5-安装部署工具" class="headerlink" title="5. 安装部署工具"></a>5. 安装部署工具</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> npm install hexo-deployer-git --save</span></span><br></pre></td></tr></table></figure><h4 id="6-部署"><a href="#6-部署" class="headerlink" title="6. 部署"></a>6. 部署</h4><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo clean && hexo g <span class="comment">#清除缓存并重新编译</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> hexo d <span class="comment">#发布</span></span></span><br></pre></td></tr></table></figure><p>第一次发布由于文件较多,发布较慢。</p><p>发布过程可能会要求输入用户名和密码,属于正常现象。</p><p>在浏览器输入 <a href="https://yourname.github.io/" target="_blank" rel="noopener">https://yourname.github.io/</a> 就可以看到你的博客了</p><p>至此,博客搭建的基础就完成了,是不是很激动呢~</p><h3 id="最终成果:"><a href="#最终成果:" class="headerlink" title="最终成果:"></a>最终成果:</h3><p><img src= "/img/loading.gif" data-src="https://blog-roc.oss-cn-hongkong.aliyuncs.com/blog/beginning/third.png" alt=""></p>]]></content>
<categories>
<category> blog </category>
<category> 1.搭建 </category>
</categories>
<tags>
<tag> blog </tag>
<tag> Hexo </tag>
</tags>
</entry>
<entry>
<title>Nginx省略index.php及其他index</title>
<link href="/posts/php-hide-index/"/>
<url>/posts/php-hide-index/</url>
<content type="html"><![CDATA[<p>编辑nginx配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/nginx/nginx.conf</span><br></pre></td></tr></table></figure><p>在server中添加index,如下</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">server {</span><br><span class="line"> location / {</span><br><span class="line"> index index.php index.html index.htm l.php;</span><br><span class="line"> autoindex on;</span><br><span class="line"> </span><br><span class="line"> if (!-e $request_filename) {</span><br><span class="line"> #一级目录</span><br><span class="line"> # rewrite ^/(.*)$ /index.php/$1 last;</span><br><span class="line"> #二级目录,这里注意修改成自己的项目目录</span><br><span class="line"> rewrite ^/rent/public/(.*)$ /rent/public/index.php/$1 last;</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000</span><br><span class="line"> #</span><br><span class="line"> location ~ \.php(.*)$ {</span><br><span class="line"> fastcgi_pass 127.0.0.1:9000;</span><br><span class="line"> fastcgi_index index.php;</span><br><span class="line"> fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;</span><br><span class="line"> fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;</span><br><span class="line"> fastcgi_param PATH_INFO $fastcgi_path_info;</span><br><span class="line"> fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;</span><br><span class="line"> include fastcgi_params;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 前端学习 </category>
</categories>
<tags>
<tag> nginx </tag>
</tags>
</entry>
<entry>
<title>live2d看板娘配置的一些坑</title>
<link href="/posts/live2d/"/>
<url>/posts/live2d/</url>
<content type="html"><![CDATA[<p>本文针对GitHub上张书樵大佬(<a href="https://zhangshuqiao.org" target="_blank" rel="noopener">点击打开他的博客</a>)的<a href="https://github.com/stevenjoezhang/live2d-widget" target="_blank" rel="noopener">看板娘</a>的一些可能的坑做一些补充</p><p>具体实现方法网上有很多,这里不做具体介绍,附上这位大佬自己写的:</p><p><a href="https://zhangshuqiao.org/2018-07/在网页中添加Live2D看板娘/" target="_blank" rel="noopener">在网页中添加Live2D看板娘</a></p><h4 id="1、配置好后只显示按钮和文字,不显示人物"><a href="#1、配置好后只显示按钮和文字,不显示人物" class="headerlink" title="1、配置好后只显示按钮和文字,不显示人物"></a>1、配置好后只显示按钮和文字,不显示人物</h4><p>有两种可能性:</p><h5 id="1)自己搭的api服务器不支持跨域"><a href="#1)自己搭的api服务器不支持跨域" class="headerlink" title="1)自己搭的api服务器不支持跨域"></a>1)自己搭的<a href="https://github.com/liandie/live2d_api" target="_blank" rel="noopener">api</a>服务器不支持跨域</h5><p>为服务器增加跨域许可,具体方法可以看我的另一篇文章 <a href="https://roc136.github.io/2020/06/08/cros/#more" target="_blank" rel="noopener">Nginx通过CROS实现跨域</a></p><h5 id="2)This-request-has-been-blocked-the-content-must-be-served-over-HTTPS"><a href="#2)This-request-has-been-blocked-the-content-must-be-served-over-HTTPS" class="headerlink" title="2)This request has been blocked; the content must be served over HTTPS."></a>2)This request has been blocked; the content must be served over HTTPS.</h5><p>自己没有域名,直接使用ip作为api的地址,使用的是http,浏览器不允许https页面加载http的内容</p><p>解决办法:为服务器添加https访问的方式,我这里使用的是nginx</p><p>具体参考:<a href="https://juejin.im/post/5d81906c518825300a3ec7ca#配置-https-证书" target="_blank" rel="noopener">nginx 这一篇就够了</a></p><p>然后将填的api改为https,另外,需要服务器开启443端口。</p><p>但是这种方式不能保证稳定,而且会使你的博客被浏览器标记为“不安全”,最好是可以注册域名,买一个证书。</p><h4 id="2、配置好后显示两个人物,出现重影"><a href="#2、配置好后显示两个人物,出现重影" class="headerlink" title="2、配置好后显示两个人物,出现重影"></a>2、配置好后显示两个人物,出现重影</h4><p>theme/_config.yml中的live2d和/_config.yml中的live2d重复</p><p>将/_config.yml中live2d的enable改为false即可</p><p>原因:使用看板娘就不需要自带的live2d,同时开启就会出现“重影”</p><h4 id="3、待补充"><a href="#3、待补充" class="headerlink" title="3、待补充"></a>3、待补充</h4>]]></content>
<categories>
<category> blog </category>
</categories>
<tags>
<tag> blog </tag>
</tags>
</entry>
<entry>
<title>Nginx通过CROS实现跨域</title>
<link href="/posts/cros/"/>
<url>/posts/cros/</url>
<content type="html"><![CDATA[<h3 id="什么是CORS"><a href="#什么是CORS" class="headerlink" title="什么是CORS"></a>什么是CORS</h3><p>CORS是一个W3C标准,全称是跨域资源共享(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。</p><p>当前几乎所有的浏览器(Internet Explorer 8+, Firefox 3.5+, Safari 4+和 Chrome 3+)都可通过名为跨域资源共享(Cross-Origin Resource Sharing)的协议支持AJAX跨域调用。</p><p>Chrome,Firefox,Opera,Safari都使用的是XMLHttpRequest2对象,IE使用XDomainRequest。</p><p>简单来说就是跨域的目标服务器要返回一系列的Headers,通过这些Headers来控制是否同意跨域。跨域资源共享(CORS)也是未来的跨域问题的标准解决方案。</p><p>CORS提供如下Headers,Request包和Response包中都有一部分。</p><p><strong>HTTP Response Header</strong></p><ul><li>Access-Control-Allow-Origin</li><li>Access-Control-Allow-Credentials</li><li>Access-Control-Allow-Methods</li><li>Access-Control-Allow-Headers</li><li>Access-Control-Expose-Headers</li><li>Access-Control-Max-Age</li></ul><p><strong>HTTP Request Header</strong></p><ul><li>Access-Control-Request-Method</li><li>Access-Control-Request-Headers</li></ul><p>其中最敏感的就是Access-Control-Allow-Origin这个Header, 它是W3C标准里用来检查该跨域请求是否可以被通过。(Access Control Check)。如果需要跨域,解决方法就是在资源的头中加入Access-Control-Allow-Origin 指定你授权的域。</p><h3 id="启用CORS请求"><a href="#启用CORS请求" class="headerlink" title="启用CORS请求"></a>启用CORS请求</h3><p>假设您的应用已经在<a href="example.com">example.com</a>上了,而您想要从 <a href="www.example2.com">www.example2.com</a> 提取数据。一般情况下,如果您尝试进行这种类型的AJAX调用,请求将会失败,而浏览器将会出现源不匹配的错误。利用CORS后只需 <a href="www.example2.com">www.example2.com</a> 服务端添加一个HTTP Response头,就可以允许来自 <a href="example.com">example.com</a> 的请求。</p><p>将Access-Control-Allow-Origin添加到某网站下或整个域中的单个资源</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Access-Control-Allow-Origin: http:<span class="comment">//example.com</span></span><br><span class="line">Access-Control-Allow-Credentials: <span class="keyword">true</span> (可选)</span><br></pre></td></tr></table></figure><p>将允许任何域向您提交请求</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Access-Control-Allow-Origin: *</span><br><span class="line">Access-Control-Allow-Credentials: <span class="keyword">true</span> (可选)</span><br></pre></td></tr></table></figure><h3 id="提交跨域请求"><a href="#提交跨域请求" class="headerlink" title="提交跨域请求"></a>提交跨域请求</h3><p>如果服务器端已启用了CORS,那么提交跨域请求就和普通的XMLHttpRequest请求没什么区别。例如现在 <a href="example.com">example.com</a> 可以向 <a href="www.example2.com">www.example2.com</a> 提交请求。</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> xhr = <span class="keyword">new</span> XMLHttpRequest();</span><br><span class="line"><span class="comment">// xhr.withCredentials = true; //如果需要Cookie等</span></span><br><span class="line">xhr.open(<span class="string">'GET'</span>, <span class="string">'http://www.example2.com/hello.json'</span>);</span><br><span class="line">xhr.onload = <span class="function"><span class="keyword">function</span><span class="params">(e)</span> </span>{</span><br><span class="line"> <span class="keyword">var</span> data = JSON.parse(this.response);</span><br><span class="line"> ...</span><br><span class="line">}</span><br><span class="line">xhr.send();</span><br></pre></td></tr></table></figure><h3 id="服务端Nginx配置"><a href="#服务端Nginx配置" class="headerlink" title="服务端Nginx配置"></a>服务端Nginx配置</h3><p>要实现CORS跨域,服务端需要下图中这样一个流程</p><p><img src= "/img/loading.gif" data-src="https://www.hi-linux.com/img/linux/cors_server_flowchart.png" alt="img"></p><ul><li>对于简单请求,如GET,只需要在HTTP Response后添加Access-Control-Allow-Origin。</li><li>对于非简单请求,比如POST、PUT、DELETE等,浏览器会分两次应答。第一次preflight(method: OPTIONS),主要验证来源是否合法,并返回允许的Header等。第二次才是真正的HTTP应答。所以服务器必须处理OPTIONS应答。</li></ul><p>流程如下</p><ul><li>首先查看http头部有无origin字段;</li><li>如果没有,或者不允许,直接当成普通请求处理,结束;</li><li>如果有并且是允许的,那么再看是否是preflight(method=OPTIONS);</li><li>如果是preflight,就返回Allow-Headers、Allow-Methods等,内容为空;</li><li>如果不是preflight,就返回Allow-Origin、Allow-Credentials等,并返回正常内容。</li></ul><p>用伪代码表示</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">location /pub/(.+) {</span><br><span class="line"> if ($http_origin ~ <允许的域(正则匹配)>) {</span><br><span class="line"> add_header 'Access-Control-Allow-Origin' "$http_origin";</span><br><span class="line"> add_header 'Access-Control-Allow-Credentials' "true";</span><br><span class="line"> if ($request_method = "OPTIONS") {</span><br><span class="line"> add_header 'Access-Control-Max-Age' 86400;</span><br><span class="line"> add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';</span><br><span class="line"> add_header 'Access-Control-Allow-Headers' 'reqid, nid, host, x-real-ip, x-forwarded-ip, event-type, event-id, accept, content-type';</span><br><span class="line"> add_header 'Content-Length' 0;</span><br><span class="line"> add_header 'Content-Type' 'text/plain, charset=utf-8';</span><br><span class="line"> return 204;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> # 正常nginx配置</span><br><span class="line"> ......</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="Nginx配置实例"><a href="#Nginx配置实例" class="headerlink" title="Nginx配置实例"></a>Nginx配置实例</h4><h5 id="实例一:允许example-com的应用在www-example2-com上跨域提取数据"><a href="#实例一:允许example-com的应用在www-example2-com上跨域提取数据" class="headerlink" title="实例一:允许example.com的应用在www.example2.com上跨域提取数据"></a>实例一:允许example.com的应用在<a href="www.example2.com">www.example2.com</a>上跨域提取数据</h5><p>在nginx.conf里找到server项,并在里面添加如下配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">location /{</span><br><span class="line"></span><br><span class="line">add_header 'Access-Control-Allow-Origin' 'http://example.com';</span><br><span class="line">add_header 'Access-Control-Allow-Credentials' 'true';</span><br><span class="line">add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';</span><br><span class="line">add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';</span><br><span class="line">...</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>如果需要允许来自任何域的访问,可以这样配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">add_header Access-Control-Allow-Origin *;</span><br></pre></td></tr></table></figure><p>注释如下</p><blockquote><p>第一条指令:授权从example.com的请求(必需)<br>第二条指令:当该标志为真时,响应于该请求是否可以被暴露(可选)<br>第三条指令:允许脚本访问的返回头(可选)<br>第四条指令:指定请求的方法,可以是GET, POST, OPTIONS, PUT, DELETE等(可选)</p></blockquote><p>重启Nginx</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> service nginx reload</span></span><br></pre></td></tr></table></figure><p>测试跨域请求</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> curl -I -X OPTIONS -H <span class="string">"Origin: http://example.com"</span> http://www.example2.com</span></span><br></pre></td></tr></table></figure><p>成功时,响应头是如下所示</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">HTTP/<span class="number">1.1</span> <span class="number">200</span> OK</span><br><span class="line">Server: nginx</span><br><span class="line">Access-Control-Allow-Origin: example.com</span><br></pre></td></tr></table></figure><h5 id="实例二:Nginx允许多个域名跨域访问"><a href="#实例二:Nginx允许多个域名跨域访问" class="headerlink" title="实例二:Nginx允许多个域名跨域访问"></a>实例二:Nginx允许多个域名跨域访问</h5><p>由于Access-Control-Allow-Origin参数只允许配置单个域名或者<code>*</code>,当我们需要允许多个域名跨域访问时可以用以下几种方法来实现。</p><ul><li>方法一</li></ul><p>如需要允许用户请求来自<a href="www.example.com">www.example.com</a>、<a href="http://m.example.com/" target="_blank" rel="noopener">m.example.com</a>、<a href="wap.example.com">wap.example.com</a> 访问 <a href="www.example2.com">www.example2.com</a>域名时,返回头Access-Control-Allow-Origin,具体配置如下</p><p>在nginx.conf里面,找到server项,并在里面添加如下配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">map $http_origin $corsHost {</span><br><span class="line"> default 0;</span><br><span class="line"> "~http://www.example.com" http://www.example.com;</span><br><span class="line"> "~http://m.example.com" http://m.example.com;</span><br><span class="line"> "~http://wap.example.com" http://wap.example.com;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">server</span><br><span class="line">{</span><br><span class="line"> listen 80;</span><br><span class="line"> server_name www.example2.com;</span><br><span class="line"> root /usr/share/nginx/html;</span><br><span class="line"> location /</span><br><span class="line"> {</span><br><span class="line"> add_header Access-Control-Allow-Origin $corsHost;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>方法二</li></ul><p>如需要允许用户请求来自localhost、<a href="www.example.com">www.example.com</a> 或 <a href="m.example.com">m.example.com</a> 的请求访问 <a href="xxx.example2.com">xxx.example2.com</a> 域名时,返回头Access-Control-Allow-Origin,具体配置如下</p><p>在Nginx配置文件中 <a href="xxx.example2.com">xxx.example2.com</a> 域名的location /下配置以下内容</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">set $cors <span class="string">''</span>;</span><br><span class="line"><span class="keyword">if</span> ($http_origin ~* <span class="string">'https?://(localhost|www\.example\.com|m\.example\.com)'</span>) {</span><br><span class="line"> set $cors <span class="string">'true'</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> ($cors = <span class="string">'true'</span>) {</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Origin'</span> <span class="string">"$http_origin"</span>;</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Credentials'</span> <span class="string">'true'</span>;</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Methods'</span> <span class="string">'GET, POST, PUT, DELETE, OPTIONS'</span>;</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Headers'</span> <span class="string">'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With'</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> ($request_method = <span class="string">'OPTIONS'</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">204</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>方法三</li></ul><p>如需要允许用户请求来自*.example.com访问xxx.example2.com域名时,返回头Access-Control-Allow-Origin,具体配置如下</p><p>在Nginx配置文件中xxx.example2.com域名的location /下配置以下内容</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> ( $http_origin ~ http:<span class="comment">//(.*).example.com){</span></span><br><span class="line"> set $allow_url $http_origin;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">#CORS(Cross Orign Resource-Sharing)跨域控制配置</span></span><br><span class="line"> <span class="comment">#是否允许请求带有验证信息</span></span><br><span class="line"> add_header Access-Control-Allow-Credentials <span class="keyword">true</span>;</span><br><span class="line"> <span class="comment">#允许跨域访问的域名,可以是一个域的列表,也可以是通配符*</span></span><br><span class="line"> add_header Access-Control-Allow-Origin $allow_url;</span><br><span class="line"> <span class="comment">#允许脚本访问的返回头</span></span><br><span class="line"> add_header Access-Control-Allow-Headers <span class="string">'x-requested-with,content-type,Cache-Control,Pragma,Date,x-timestamp'</span>;</span><br><span class="line"> <span class="comment">#允许使用的请求方法,以逗号隔开</span></span><br><span class="line"> add_header Access-Control-Allow-Methods <span class="string">'POST,GET,OPTIONS,PUT,DELETE'</span>;</span><br><span class="line"> <span class="comment">#允许自定义的头部,以逗号隔开,大小写不敏感</span></span><br><span class="line"> add_header Access-Control-Expose-Headers <span class="string">'WWW-Authenticate,Server-Authorization'</span>;</span><br><span class="line"> <span class="comment">#P3P支持跨域cookie操作</span></span><br><span class="line"> add_header P3P <span class="string">'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR BUS IND ONL UNI COM NAV INT LOC"'</span>;</span><br></pre></td></tr></table></figure><ul><li>方法四</li></ul><p>如需要允许用户请求来自xxx1.example.com或xxx1.example1.com访问xxx.example2.com域名时,返回头Access-Control-Allow-Origin,具体配置如下</p><p>在Nginx配置文件中 <a href="xxx.example2.com">xxx.example2.com</a> 域名的location /下配置以下内容</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">location / {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> ( $http_origin ~ .*.(example|example1).com ) {</span><br><span class="line"> add_header Access-Control-Allow-Origin $http_origin;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="实例三:Nginx跨域配置并支持DELETE-PUT请求"><a href="#实例三:Nginx跨域配置并支持DELETE-PUT请求" class="headerlink" title="实例三:Nginx跨域配置并支持DELETE,PUT请求"></a>实例三:Nginx跨域配置并支持DELETE,PUT请求</h5><p>默认Access-Control-Allow-Origin开启跨域请求只支持GET、HEAD、POST、OPTIONS请求,使用DELETE发起跨域请求时,浏览器出于安全考虑会先发起OPTIONS请求,服务器端接收到的请求方式就变成了OPTIONS,所以引起了服务器的405 Method Not Allowed。</p><p>解决方法</p><p>首先要对OPTIONS请求进行处理</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> ($request_method = <span class="string">'OPTIONS'</span>) { </span><br><span class="line"> add_header Access-Control-Allow-Origin *; </span><br><span class="line"> add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;</span><br><span class="line"> <span class="comment">#其他头部信息配置,省略...</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">204</span>; </span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>当请求方式为OPTIONS时设置Allow的响应头,重新处理这次请求。这样发出请求时第一次是OPTIONS请求,第二次才是DELETE请求。</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 完整配置参考</span></span><br><span class="line"><span class="comment"># 将配置文件的放到对应的server {}里</span></span><br><span class="line"></span><br><span class="line">add_header Access-Control-Allow-Origin *;</span><br><span class="line"></span><br><span class="line">location / {</span><br><span class="line"> <span class="keyword">if</span> ($request_method = <span class="string">'OPTIONS'</span>) { </span><br><span class="line"> add_header Access-Control-Allow-Origin *; </span><br><span class="line"> add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">204</span>; </span><br><span class="line"> }</span><br><span class="line"> index index.php;</span><br><span class="line"> try_files $uri @rewriteapp;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="实例四:更多配置示例"><a href="#实例四:更多配置示例" class="headerlink" title="实例四:更多配置示例"></a>实例四:更多配置示例</h5><ul><li>示例一</li></ul><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">The following Nginx configuration enables CORS, with support <span class="keyword">for</span> preflight requests.</span><br><span class="line"></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Wide-open CORS config for nginx</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line">location / {</span><br><span class="line"> <span class="keyword">if</span> ($request_method = <span class="string">'OPTIONS'</span>) {</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Origin'</span> <span class="string">'*'</span>;</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Methods'</span> <span class="string">'GET, POST, OPTIONS'</span>;</span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="comment"># Custom headers and headers various browsers *should* be OK with but aren't</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Headers'</span> <span class="string">'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'</span>;</span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="comment"># Tell client that this pre-flight info is valid for 20 days</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> add_header <span class="string">'Access-Control-Max-Age'</span> <span class="number">1728000</span>;</span><br><span class="line"> add_header <span class="string">'Content-Type'</span> <span class="string">'text/plain charset=UTF-8'</span>;</span><br><span class="line"> add_header <span class="string">'Content-Length'</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">204</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> ($request_method = <span class="string">'POST'</span>) {</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Origin'</span> <span class="string">'*'</span>;</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Methods'</span> <span class="string">'GET, POST, OPTIONS'</span>;</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Headers'</span> <span class="string">'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> ($request_method = <span class="string">'GET'</span>) {</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Origin'</span> <span class="string">'*'</span>;</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Methods'</span> <span class="string">'GET, POST, OPTIONS'</span>;</span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Headers'</span> <span class="string">'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>示例二</li></ul><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> ($request_method = <span class="string">'OPTIONS'</span>) { </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Origin'</span> <span class="string">'https://docs.domain.com'</span>; </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Credentials'</span> <span class="string">'true'</span>; </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Methods'</span> <span class="string">'GET, POST, PUT, DELETE, PATCH, OPTIONS'</span>; </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Headers'</span> <span class="string">'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,token'</span>; </span><br><span class="line"> <span class="keyword">return</span> <span class="number">204</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> ($request_method = <span class="string">'POST'</span>) { </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Origin'</span> <span class="string">'https://docs.domain.com'</span>; </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Credentials'</span> <span class="string">'true'</span>; </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Methods'</span> <span class="string">'GET, POST, PUT, DELETE, PATCH, OPTIONS'</span>; </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Headers'</span> <span class="string">'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,token'</span>; </span><br><span class="line">} </span><br><span class="line"><span class="keyword">if</span> ($request_method = <span class="string">'GET'</span>) { </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Origin'</span> <span class="string">'https://docs.domain.com'</span>; </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Credentials'</span> <span class="string">'true'</span>; </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Methods'</span> <span class="string">'GET, POST, PUT, DELETE, PATCH, OPTIONS'</span>; </span><br><span class="line"> add_header <span class="string">'Access-Control-Allow-Headers'</span> <span class="string">'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,token'</span>; </span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="其它技巧"><a href="#其它技巧" class="headerlink" title="其它技巧"></a>其它技巧</h3><h4 id="Apache中启用CORS"><a href="#Apache中启用CORS" class="headerlink" title="Apache中启用CORS"></a>Apache中启用CORS</h4><p>在httpd配置或.htaccess文件中添加如下语句</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">SetEnvIf Origin "^(.*\.example\.com)$" ORIGIN_SUB_DOMAIN=$1 </span><br><span class="line">Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN</span><br></pre></td></tr></table></figure><h4 id="PHP中启用CORS"><a href="#PHP中启用CORS" class="headerlink" title="PHP中启用CORS"></a>PHP中启用CORS</h4><p>通过在服务端设置Access-Control-Allow-Origin响应头</p><ul><li>允许所有来源访问</li></ul><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line">header(<span class="string">"Access-Control-Allow-Origin: *"</span>);</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><ul><li>允许来自特定源的访问</li></ul><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line">header(<span class="string">'Access-Control-Allow-Origin: '</span>.$_SERVER[<span class="string">'HTTP_ORIGIN'</span>]);</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><ul><li>配置多个访问源</li></ul><p>由于浏览器实现只支持了单个origin、*、null,如果要配置多个访问源,可以在代码中处理如下</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line">$allowed_origins = <span class="keyword">array</span>( </span><br><span class="line"> <span class="string">"http://www.example.com"</span> , </span><br><span class="line"> <span class="string">"http://app.example.com"</span> , </span><br><span class="line"> <span class="string">"http://cms.example.com"</span> , </span><br><span class="line"> ); </span><br><span class="line"><span class="keyword">if</span> (in_array($_SERVER[<span class="string">'HTTP_ORIGIN'</span>], $allowed_origins)){ </span><br><span class="line"> @header(<span class="string">"Access-Control-Allow-Origin: "</span> . $_SERVER[<span class="string">'HTTP_ORIGIN'</span>]); </span><br><span class="line">}</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><h4 id="HTML中启用CORS"><a href="#HTML中启用CORS" class="headerlink" title="HTML中启用CORS"></a>HTML中启用CORS</h4><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><meta http-equiv=<span class="string">"Access-Control-Allow-Origin"</span> content=<span class="string">"*"</span>></span><br></pre></td></tr></table></figure><h3 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h3><p><a href="http://www.google.com/" target="_blank" rel="noopener">http://www.google.com</a><br><a href="http://blog.csdn.net/oyzl68/article/details/18741057" target="_blank" rel="noopener">http://blog.csdn.net/oyzl68/article/details/18741057</a><br><a href="http://www.webyang.net/Html/web/article_135.html" target="_blank" rel="noopener">http://www.webyang.net/Html/web/article_135.html</a><br><a href="http://www.ttlsa.com/nginx/how-to-allow-cross-domain-ajax-requests-on-nginx/" target="_blank" rel="noopener">http://www.ttlsa.com/nginx/how-to-allow-cross-domain-ajax-requests-on-nginx/</a><br><a href="http://www.voidcn.com/blog/lvnian/article/p-5978475.html" target="_blank" rel="noopener">http://www.voidcn.com/blog/lvnian/article/p-5978475.html</a><br><a href="http://to-u.xyz/2016/06/30/nginx-cors/" target="_blank" rel="noopener">http://to-u.xyz/2016/06/30/nginx-cors/</a><br><a href="http://coderq.github.io/2016/05/13/cross-domain/" target="_blank" rel="noopener">http://coderq.github.io/2016/05/13/cross-domain/</a></p><p>转载自:<a href="https://www.hi-linux.com/posts/60405.html" target="_blank" rel="noopener">https://www.hi-linux.com/posts/60405.html</a></p>]]></content>
<categories>
<category> 前端学习 </category>
</categories>
<tags>
<tag> nginx </tag>
<tag> cros </tag>
<tag> 跨域 </tag>
</tags>
</entry>
</search>