<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>情文のBLOG</title>
  
  <subtitle>记录点点滴滴</subtitle>
  <link href="https://www.mingilin.com/atom.xml" rel="self"/>
  
  <link href="https://www.mingilin.com/"/>
  <updated>2026-01-16T09:36:28.090Z</updated>
  <id>https://www.mingilin.com/</id>
  
  <author>
    <name>kingwen0302</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>GPG基础使用</title>
    <link href="https://www.mingilin.com/2026/01/16/shell/shell-gpg/"/>
    <id>https://www.mingilin.com/2026/01/16/shell/shell-gpg/</id>
    <published>2026-01-16T02:59:54.000Z</published>
    <updated>2026-01-16T09:36:28.090Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><blockquote><p>测试环境：alpine:3.22(docker)<br>基础软件：gpg gpg-agent openssl openssh-client monkeysphere bash</p></blockquote><p>第一部分、第二部分相关的文章比较多，第三部分相对较少。这篇文章基本上都是代码，是一篇完全实操过程的记录。</p><blockquote><p><code>GPG</code>windows对应版本是<code>Kleopatra</code><br>文中的一些操作有对应的图形界面，有些没有，比如第三部分（也可能是我没有找到）</p></blockquote><blockquote><p><font color=red><strong>低版本可导入高版本，反过来不行，因此，第一步先确认使用的环境以及版本。</strong></font></p></blockquote><span id="more"></span><h1 id="环境准备"><a href="#环境准备" class="headerlink" title="环境准备"></a>环境准备</h1><p><code>/ #</code> 是命令提示符</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><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">f:/gpgtest&gt; podman run -it -v ./:/app --name gpgtest alpine:3.22 sh</span><br><span class="line">/ # apk add gpg gpg-agent openssl openssh-client monkeysphere bash</span><br><span class="line">fetch https://dl-cdn.alpinelinux.org/alpine/v3.22/main/x86_64/APKINDEX.tar.gz</span><br><span class="line">fetch https://dl-cdn.alpinelinux.org/alpine/v3.22/community/x86_64/APKINDEX.tar.gz</span><br><span class="line">(1/46) Installing ncurses-terminfo-base (6.5_p20250503-r0)</span><br><span class="line">...</span><br><span class="line">(46/46) Installing openssh-client-default (10.0_p1-r10)</span><br><span class="line">Executing busybox-1.37.0-r19.trigger</span><br><span class="line">OK: 65 MiB in 62 packages</span><br><span class="line">/ # exit</span><br><span class="line">f:/gpgtest&gt; podman start -i gpgtest</span><br><span class="line">gpgtest</span><br><span class="line">f:/gpgtest&gt; podman exec -it gpgtest bash </span><br><span class="line">d661cfbeb503:/#</span><br></pre></td></tr></table></figure><h1 id="第一部分（增删Key）"><a href="#第一部分（增删Key）" class="headerlink" title="第一部分（增删Key）"></a>第一部分（增删Key）</h1><blockquote><p>这部分将生成一个key<br>testa <a href="mailto:&#116;&#101;&#x73;&#116;&#x61;&#64;&#x65;&#x78;&#109;&#97;&#112;&#x6c;&#x65;&#46;&#99;&#x6f;&#109;">&#116;&#101;&#x73;&#116;&#x61;&#64;&#x65;&#x78;&#109;&#97;&#112;&#x6c;&#x65;&#46;&#99;&#x6f;&#109;</a><br>密码是: testa123456</p></blockquote><h2 id="生成Key-–generate-key"><a href="#生成Key-–generate-key" class="headerlink" title="生成Key(–generate-key)"></a>生成Key(–generate-key)</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 生成一个Key</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 这个Key可以用于 Sign Certify Encrypt Authenticate</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line">d661cfbeb503:/# gpg --expert --full-generate-key</span><br><span class="line">gpg (GnuPG) 2.4.9; Copyright (C) 2025 g10 Code GmbH</span><br><span class="line">This is free software: you are free to change and redistribute it.</span><br><span class="line">There is NO WARRANTY, to the extent permitted by law.</span><br><span class="line"></span><br><span class="line">gpg: directory &#x27;/root/.gnupg&#x27; created</span><br><span class="line">Please select what kind of key you want:</span><br><span class="line">   (1) RSA and RSA</span><br><span class="line">   (2) DSA and Elgamal</span><br><span class="line">   (3) DSA (sign only)</span><br><span class="line">   (4) RSA (sign only)</span><br><span class="line">   (7) DSA (set your own capabilities)</span><br><span class="line">   (8) RSA (set your own capabilities)</span><br><span class="line">   (9) ECC (sign and encrypt) *default*</span><br><span class="line">  (10) ECC (sign only)</span><br><span class="line">  (11) ECC (set your own capabilities)</span><br><span class="line">  (13) Existing key</span><br><span class="line">  (14) Existing key from card</span><br><span class="line">Your selection? 8</span><br><span class="line"></span><br><span class="line">Possible actions for this RSA key: Sign Certify Encrypt Authenticate</span><br><span class="line">Current allowed actions: Sign Certify Encrypt</span><br><span class="line"></span><br><span class="line">   (S) Toggle the sign capability</span><br><span class="line">   (E) Toggle the encrypt capability</span><br><span class="line">   (A) Toggle the authenticate capability</span><br><span class="line">   (Q) Finished</span><br><span class="line"></span><br><span class="line">Your selection? A</span><br><span class="line"></span><br><span class="line">Possible actions for this RSA key: Sign Certify Encrypt Authenticate</span><br><span class="line">Current allowed actions: Sign Certify Encrypt Authenticate</span><br><span class="line"></span><br><span class="line">   (S) Toggle the sign capability</span><br><span class="line">   (E) Toggle the encrypt capability</span><br><span class="line">   (A) Toggle the authenticate capability</span><br><span class="line">   (Q) Finished</span><br><span class="line"></span><br><span class="line">Your selection? Q</span><br><span class="line">RSA keys may be between 1024 and 4096 bits long.</span><br><span class="line">What keysize do you want? (3072) 4096</span><br><span class="line">Requested keysize is 4096 bits</span><br><span class="line">Please specify how long the key should be valid.</span><br><span class="line">         0 = key does not expire</span><br><span class="line">      &lt;n&gt;  = key expires in n days</span><br><span class="line">      &lt;n&gt;w = key expires in n weeks</span><br><span class="line">      &lt;n&gt;m = key expires in n months</span><br><span class="line">      &lt;n&gt;y = key expires in n years</span><br><span class="line">Key is valid for? (0)</span><br><span class="line">Key does not expire at all</span><br><span class="line">Is this correct? (y/N) y</span><br><span class="line"></span><br><span class="line">GnuPG needs to construct a user ID to identify your key.</span><br><span class="line"></span><br><span class="line">Real name: testa</span><br><span class="line">Email address: testa@example.com</span><br><span class="line">Comment: testa</span><br><span class="line">You selected this USER-ID:</span><br><span class="line">    &quot;testa (testa) &lt;testa@example.com&gt;&quot;</span><br><span class="line"></span><br><span class="line">Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O</span><br><span class="line">We need to generate a lot of random bytes. It is a good idea to perform</span><br><span class="line">some other action (type on the keyboard, move the mouse, utilize the</span><br><span class="line">disks) during the prime generation; this gives the random number</span><br><span class="line">generator a better chance to gain enough entropy.</span><br><span class="line">gpg: /root/.gnupg/trustdb.gpg: trustdb created</span><br><span class="line">gpg: directory &#x27;/root/.gnupg/openpgp-revocs.d&#x27; created</span><br><span class="line">gpg: revocation certificate stored as &#x27;/root/.gnupg/openpgp-revocs.d/C59DA9100483F2F71C4238464B3A00756CCA7091.rev&#x27;</span><br><span class="line">public and secret key created and signed.</span><br><span class="line"></span><br><span class="line">pub   rsa4096 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">uid                      testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"></span><br><span class="line">d661cfbeb503:/#</span><br><span class="line">d661cfbeb503:/# gpg --quiet --list-key --with-keygrip</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">      Keygrip = BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4</span><br><span class="line">uid           [ultimate] testa (testa) &lt;testa@example.com&gt;</span><br></pre></td></tr></table></figure><h2 id="导出Key-–export"><a href="#导出Key-–export" class="headerlink" title="导出Key(–export)"></a>导出Key(–export)</h2><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><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">d661cfbeb503:/# cd /app/</span><br><span class="line">d661cfbeb503:/app# ls</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 将Key导出，后面还有一种更加快速的方式</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 导出SECRET的时候会提示输入密码</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line">d661cfbeb503:/app# gpg -o testa_public.gpg --export testa</span><br><span class="line">d661cfbeb503:/app# gpg -o testa_SECRET.gpg --export-secret-keys testa</span><br><span class="line">d661cfbeb503:/app# ls</span><br><span class="line">testa_SECRET.gpg  testa_public.gpg</span><br></pre></td></tr></table></figure><h2 id="导入Key-–import"><a href="#导入Key-–import" class="headerlink" title="导入Key(–import)"></a>导入Key(–import)</h2><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><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="meta prompt_">#</span><span class="language-bash"></span></span><br><span class="line"><span class="language-bash"><span class="comment"># 导入公钥</span></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">加密文件给别人的时候用到</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"></span></span><br><span class="line"><span class="language-bash">d661cfbeb503:/app# gpg --import testa_public.gpg</span></span><br><span class="line">gpg: key 4B3A00756CCA7091: public key &quot;testa (testa) &lt;testa@example.com&gt;&quot; imported</span><br><span class="line">gpg: Total number processed: 1</span><br><span class="line">gpg:               imported: 1</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"></span></span><br><span class="line"><span class="language-bash"><span class="comment"># 导入私钥</span></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">解密文件的时候用到</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"></span></span><br><span class="line"><span class="language-bash">d661cfbeb503:/app# gpg --import testa_SECRET.gpg</span></span><br><span class="line">gpg: key 4B3A00756CCA7091: &quot;testa (testa) &lt;testa@example.com&gt;&quot; not changed</span><br><span class="line">gpg: key 4B3A00756CCA7091: secret key imported</span><br><span class="line">gpg: Total number processed: 1</span><br><span class="line">gpg:              unchanged: 1</span><br><span class="line">gpg:       secret keys read: 1</span><br><span class="line">gpg:   secret keys imported: 1</span><br><span class="line">d661cfbeb503:/app# gpg --list-keys --with-keygrip --keyid-format SHORT</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096/6CCA7091 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">      Keygrip = BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4</span><br><span class="line">uid         [ unknown] testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"></span><br><span class="line">d661cfbeb503:/app#</span><br></pre></td></tr></table></figure><h2 id="列出所有的Key-–list-keys"><a href="#列出所有的Key-–list-keys" class="headerlink" title="列出所有的Key(–list-keys)"></a>列出所有的Key(–list-keys)</h2><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><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">d661cfbeb503:/app# gpg --list-keys --with-keygrip --keyid-format SHORT</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096/6CCA7091 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">      Keygrip = BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4</span><br><span class="line">uid         [ultimate] testa (testa) &lt;testa@example.com&gt;</span><br></pre></td></tr></table></figure><h2 id="信任Key-–edit-key-trust-save"><a href="#信任Key-–edit-key-trust-save" class="headerlink" title="信任Key(–edit-key &gt; trust &gt; save)"></a>信任Key(–edit-key &gt; trust &gt; save)</h2><p>新导入的状态是unknown，将其设置为信任ultimately</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><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></pre></td><td class="code"><pre><span class="line">d661cfbeb503:/app# gpg --edit-key testa</span><br><span class="line">gpg (GnuPG) 2.4.9; Copyright (C) 2025 g10 Code GmbH</span><br><span class="line">This is free software: you are free to change and redistribute it.</span><br><span class="line">There is NO WARRANTY, to the extent permitted by law.</span><br><span class="line"></span><br><span class="line">Secret key is available.</span><br><span class="line"></span><br><span class="line">sec  rsa4096/4B3A00756CCA7091</span><br><span class="line">     created: 2026-01-16  expires: never       usage: SCEA</span><br><span class="line">     trust: unknown       validity: unknown</span><br><span class="line">[ unknown] (1). testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">gpg&gt; </span><span class="language-bash">trust</span></span><br><span class="line">sec  rsa4096/4B3A00756CCA7091</span><br><span class="line">     created: 2026-01-16  expires: never       usage: SCEA</span><br><span class="line">     trust: unknown       validity: unknown</span><br><span class="line">[ unknown] (1). testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"></span><br><span class="line">Please decide how far you trust this user to correctly verify other users&#x27; keys</span><br><span class="line">(by looking at passports, checking fingerprints from different sources, etc.)</span><br><span class="line"></span><br><span class="line">  1 = I don&#x27;t know or won&#x27;t say</span><br><span class="line">  2 = I do NOT trust</span><br><span class="line">  3 = I trust marginally</span><br><span class="line">  4 = I trust fully</span><br><span class="line">  5 = I trust ultimately</span><br><span class="line">  m = back to the main menu</span><br><span class="line"></span><br><span class="line">Your decision? 5</span><br><span class="line">Do you really want to set this key to ultimate trust? (y/N) y</span><br><span class="line"></span><br><span class="line">sec  rsa4096/4B3A00756CCA7091</span><br><span class="line">     created: 2026-01-16  expires: never       usage: SCEA</span><br><span class="line">     trust: ultimate      validity: unknown</span><br><span class="line">[ unknown] (1). testa (testa) &lt;testa@example.com&gt;</span><br><span class="line">Please note that the shown key validity is not necessarily correct</span><br><span class="line">unless you restart the program.</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">gpg&gt; </span><span class="language-bash">save</span></span><br><span class="line">Key not changed so no update needed.</span><br><span class="line">d661cfbeb503:/app#</span><br></pre></td></tr></table></figure><p>这时候 trust状态已经变成ultimate，不会再有烦人的提示了</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><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">d661cfbeb503:/app# gpg --list-keys</span><br><span class="line">gpg: checking the trustdb</span><br><span class="line">gpg: marginals needed: 3  completes needed: 1  trust model: pgp</span><br><span class="line">gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">uid           [ultimate] testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"></span><br><span class="line">d661cfbeb503:/app#</span><br></pre></td></tr></table></figure><h2 id="删除Keys"><a href="#删除Keys" class="headerlink" title="删除Keys"></a>删除Keys</h2><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><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">d661cfbeb503:/app# gpg --delete-secret-keys testa</span><br><span class="line">gpg (GnuPG) 2.4.9; Copyright (C) 2025 g10 Code GmbH</span><br><span class="line">This is free software: you are free to change and redistribute it.</span><br><span class="line">There is NO WARRANTY, to the extent permitted by law.</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">sec  rsa4096/4B3A00756CCA7091 2026-01-16 testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"></span><br><span class="line">Delete this key from the keyring? (y/N) y</span><br><span class="line">This is a secret key! - really delete? (y/N) y</span><br><span class="line">d661cfbeb503:/app# gpg --list-keys --with-keygrip --keyid-format SHORT</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096/6CCA7091 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">      Keygrip = BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4</span><br><span class="line">uid         [ultimate] testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"></span><br><span class="line">d661cfbeb503:/app# gpg --delete-keys testa</span><br><span class="line">gpg (GnuPG) 2.4.9; Copyright (C) 2025 g10 Code GmbH</span><br><span class="line">This is free software: you are free to change and redistribute it.</span><br><span class="line">There is NO WARRANTY, to the extent permitted by law.</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">pub  rsa4096/4B3A00756CCA7091 2026-01-16 testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"></span><br><span class="line">Delete this key from the keyring? (y/N) y</span><br><span class="line">d661cfbeb503:/app# gpg --list-keys --with-keygrip --keyid-format SHORT</span><br><span class="line">gpg: checking the trustdb</span><br><span class="line">gpg: no ultimately trusted keys found</span><br><span class="line">d661cfbeb503:/app#</span><br></pre></td></tr></table></figure><h1 id="第二部分（文件文本加解密）"><a href="#第二部分（文件文本加解密）" class="headerlink" title="第二部分（文件文本加解密）"></a>第二部分（文件文本加解密）</h1><h2 id="加密文件-–encrypt"><a href="#加密文件-–encrypt" class="headerlink" title="加密文件(–encrypt)"></a>加密文件(–encrypt)</h2><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><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">d661cfbeb503:/app# echo &quot;abc&quot; &gt; in.txt</span><br><span class="line">d661cfbeb503:/app# ls</span><br><span class="line">in.txt</span><br><span class="line">d661cfbeb503:/app# gpg -se -r testa -o out.txt.gpg in.txt</span><br><span class="line">d661cfbeb503:/app# ls</span><br><span class="line">in.txt            out.txt.gpg</span><br><span class="line">d661cfbeb503:/app# cat in.txt</span><br><span class="line">abc</span><br><span class="line">d661cfbeb503:/app# cat out.txt.gpg</span><br><span class="line">....一堆乱码...</span><br><span class="line">d661cfbeb503:/app#</span><br></pre></td></tr></table></figure><p>-s sign<br>-e&#x2F;–encrypt 加密<br>若加密文件夹的话，可以使用gpg-zip，也可以先压缩再加密</p><h2 id="解密文件-–decrypt"><a href="#解密文件-–decrypt" class="headerlink" title="解密文件(–decrypt)"></a>解密文件(–decrypt)</h2><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><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">d661cfbeb503:/app# gpg -d -o in2.txt out.txt.gpg</span><br><span class="line">gpg: encrypted with rsa4096 key, ID 4B3A00756CCA7091, created 2026-01-16</span><br><span class="line">      &quot;testa (testa) &lt;testa@example.com&gt;&quot;</span><br><span class="line">gpg: Signature made Fri Jan 16 07:11:54 2026 UTC</span><br><span class="line">gpg:                using RSA key C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">gpg: Good signature from &quot;testa (testa) &lt;testa@example.com&gt;&quot; [ultimate]</span><br><span class="line">d661cfbeb503:/app# ls</span><br><span class="line">in.txt            in2.txt           out.txt.gpg</span><br><span class="line">d661cfbeb503:/app# cat in2.txt</span><br><span class="line">abc</span><br></pre></td></tr></table></figure><p>-d&#x2F;–decrypt 解密</p><h2 id="加密字符串"><a href="#加密字符串" class="headerlink" title="加密字符串"></a>加密字符串</h2><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><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">d661cfbeb503:/app# echo &quot;abc&quot; | gpg -e -r testa --armour</span><br><span class="line">-----BEGIN PGP MESSAGE-----</span><br><span class="line"></span><br><span class="line">hQIMA0s6AHVsynCRAQ/9HnvG6yXhyAEqz/6GQvzMfYomHNmqJR4WJr3rHoqchzZk</span><br><span class="line">aKvhcxsQINRqJbDVBVaoCyepx1lz+HVfDnr9SmtlqHrE74FyorAtoTXzmZZR/gtu</span><br><span class="line">VsGevrmQdidnBmXox1+XjX6A+pBNjhNkcopjd5VASsDDtSPGrwdcZX7QFqId5vKl</span><br><span class="line">x8v7p6sRs7bKyY1FK3UDDH7HpMj27enMXO/eqAW3ASBnuzOMc8YsWcGcNWvJT63E</span><br><span class="line">6XB5jrSZBJff8zVLP1R1JXlhClsridlx3oqU4yZlVnW2OQTf77Yrbp+3zPuhH+5g</span><br><span class="line">RbKfs5DL7hf0tBsvPx2WOuDJwg0twoxYZ0mdlUCwcNFqQ5n9PzIbtdSVB5NnDh/w</span><br><span class="line">XaIQ+FJ+O9QT+ctJauNgcypGy0d7GQNBS/18cf2kseJkWsr+on1Q0Me+a4ofXsmT</span><br><span class="line">LW6nPot/zlVyJSNGgWWTUFptP6M09E5qXyjuigBPZrZcHt+FK6GBCLcZTMq1jUJa</span><br><span class="line">tteEyKdiyTLaAsuclbgqJyVdyN1xmzMcWATfvgUNbQJBWsjAHNV+fyBrBqPRqe0a</span><br><span class="line">TjjV38eOftD0jgR4xxUJO26h7/Jc1bUJOZ5azJQU6G6oRLz/CD5XdTwIwRZdK9t7</span><br><span class="line">Gofx3QBbHr9nkUawvhbHjHNPUMLFXnrwvNMYnSoLXYMXz40d4mSxdtCFUXmUdz3U</span><br><span class="line">SQEJAhCQWknuErtqVOYuDOioU5DrmliXN/FvkiXoxUD3d4y5rHA4mCydsNRxsAz4</span><br><span class="line">ktGS75ilpsmXpvKkiPpvowDfcLltkKN57f4=</span><br><span class="line">=BcqG</span><br><span class="line">-----END PGP MESSAGE-----</span><br></pre></td></tr></table></figure><h2 id="解密字符串"><a href="#解密字符串" class="headerlink" title="解密字符串"></a>解密字符串</h2><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><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">d661cfbeb503:/app# echo &quot;abc&quot; | gpg -e -r testa --armour &gt; abc.str.txt</span><br><span class="line">d661cfbeb503:/app# gpg -d abc.str.txt</span><br><span class="line">gpg: encrypted with rsa4096 key, ID 4B3A00756CCA7091, created 2026-01-16</span><br><span class="line">      &quot;testa (testa) &lt;testa@example.com&gt;&quot;</span><br><span class="line">abc</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 如果是第一次解密的话</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 可能会卡住，因为需要输入密码</span></span></span><br><span class="line">d661cfbeb503:/app# cat abc.str.txt | gpg -d</span><br><span class="line">gpg: encrypted with rsa4096 key, ID 4B3A00756CCA7091, created 2026-01-16</span><br><span class="line">      &quot;testa (testa) &lt;testa@example.com&gt;&quot;</span><br><span class="line">abc</span><br></pre></td></tr></table></figure><h1 id="第三部分（替代ssh-agent）"><a href="#第三部分（替代ssh-agent）" class="headerlink" title="第三部分（替代ssh-agent）"></a>第三部分（替代ssh-agent）</h1><p>前面的都是相对简单的，这部分才是这篇文章的重点</p><h2 id="替代ssh-agent"><a href="#替代ssh-agent" class="headerlink" title="替代ssh-agent"></a>替代ssh-agent</h2><h3 id="1、导出ssh-public-key-公钥"><a href="#1、导出ssh-public-key-公钥" class="headerlink" title="1、导出ssh-public-key(公钥)"></a>1、导出ssh-public-key(公钥)</h3><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">d661cfbeb503:/app# gpg --export-ssh-key testa</span><br><span class="line">ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNxSVTIp0bjeb+3dmSjT1NMcTfcCzO0r+49IMqQvOYWvpQ+3uAUiy3Lq9394KDZWbV2UIP+7EKK+wKkcE+8AsptpnFKqjyuxbCUjrNDlAMUSeOD7tv4yuWlkGnueCkSnX5GKntiFjKihZ6P8ZBLyrIPRb4LUaRZthslstSV3dHVd8vW9I3d9hpKJQYknCNIWnmsgoA7pWn4cwFS4Jn0Zcdwk6Gpd2aRfC2o/6AewIRpHUDNgvOJP4zI6DbGwWHkUVox6QYUxNHf1O8ygKqi+BEnh2qxhFh1iOcB6gYpmD6CdiY4UEDvQitOdgfIbUXqyfswSy9xI4IFGjdjcy2+ACa7rrSdSlAbgoP4D/cBdXk9Rjh5UoqflRT879SfzFnlg71daT8EaDcHGS+0rrimby4KdczDqlJhYe5YMfTH6gknk0/HPN7TtDUvLUc/gE0Ur8OqAVhMVjLr05iDpR5HtTIxTSsUyGHuWJB32mF+uyIu58FxY0OQMWp75UfWAYdjTOT+FpRXu0jNAlZlepNoyTf7GYfnquiNNk33b8Lf4ZNzM+pF8K9pWtTWFMPVXJlcCI3OILLidaxRweUSSuWUh4zuRc2gys1Av6eNTL8D8WdqIpQbMX0m9nIFzGO6FeAWtzT2ezd+jDk/brk89QsAXtrt9l2eGF/FObF1cFPnERAhw== openpgp:0x6CCA7091</span><br></pre></td></tr></table></figure><p>将ssh-rsa …添加到服务器上的~&#x2F;.ssh&#x2F;authorized_keys</p><h3 id="2、配置sshcontrol"><a href="#2、配置sshcontrol" class="headerlink" title="2、配置sshcontrol"></a>2、配置sshcontrol</h3><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><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">d661cfbeb503:/app# gpg --list-keys --with-keygrip</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">      Keygrip = BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4</span><br><span class="line">uid           [ultimate] testa (testa) &lt;testa@example.com&gt;</span><br></pre></td></tr></table></figure><blockquote><p>[A] 是Authenticate的意思<br>Keygrip &#x3D; BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4 就是指纹</p></blockquote><p>将指纹添加到~&#x2F;.gnupg&#x2F;sshcontrol中</p><p><code>echo &quot;BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4&quot; &gt;&gt; ~/.gnupg/sshcontrol</code></p><h3 id="3、启动gpg-agent"><a href="#3、启动gpg-agent" class="headerlink" title="3、启动gpg-agent"></a>3、启动gpg-agent</h3><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">d661cfbeb503:/app# gpg-connect-agent --quiet /bye</span><br><span class="line">d661cfbeb503:/app# export SSH_AUTH_SOCK=&quot;$(gpgconf --list-dirs agent-ssh-socket)&quot;</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">## eval $(gpg-agent --daemon --enable-ssh-support)</span></span></span><br></pre></td></tr></table></figure><h3 id="4、完成"><a href="#4、完成" class="headerlink" title="4、完成"></a>4、完成</h3><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">d661cfbeb503:/app# ssh-add -l</span><br><span class="line">4096 SHA256:TLIjaLIPgJ1D5ifJO6jZkCU0LppcGcnB6pNNgR811iA (none) (RSA)</span><br></pre></td></tr></table></figure><p>这是已经是可以使用<code>ssh user@host</code>登录服务器了，似乎已经可以结束了<br>但是如果已经有了id_rsa怎么处理呢？<br><del>用这个新的替换掉旧的</del>，不太合理吧<br>是不是可以把旧的key添加到gpg中呢？当然可以</p><h2 id="将OPENSSH私钥作为subkey添加到gpg中"><a href="#将OPENSSH私钥作为subkey添加到gpg中" class="headerlink" title="将OPENSSH私钥作为subkey添加到gpg中"></a>将OPENSSH私钥作为subkey添加到gpg中</h2><h3 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h3><p>假设我们已经有一个openssh key 名字是<code>testb</code></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><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">d661cfbeb503:/app# ssh-keygen -t rsa -b 4096 -C &quot;testb@exmaple.com&quot;</span><br><span class="line">Generating public/private rsa key pair.</span><br><span class="line">Enter file in which to save the key (/root/.ssh/id_rsa): /app/testb</span><br><span class="line">Enter passphrase for &quot;/app/testb&quot; (empty for no passphrase):</span><br><span class="line">Enter same passphrase again:</span><br><span class="line">Your identification has been saved in /app/testb</span><br><span class="line">Your public key has been saved in /app/testb.pub</span><br><span class="line">The key fingerprint is:</span><br><span class="line">SHA256:wRwKd/0OVS93gZ/tRTU3uVbtVoDIeA2sjxGeTuu4wus testb@exmaple.com</span><br><span class="line">The key&#x27;s randomart image is:</span><br><span class="line">+---[RSA 4096]----+</span><br><span class="line">|    . . o=.+ o+=*|</span><br><span class="line">|     o =o.* +. oX|</span><br><span class="line">|      ..+= o  ooX|</span><br><span class="line">|        *.. .  B*|</span><br><span class="line">|       oS= o  .o.|</span><br><span class="line">|        + . .   .|</span><br><span class="line">|   .   o         |</span><br><span class="line">|    o . .        |</span><br><span class="line">|   .Eo..         |</span><br><span class="line">+----[SHA256]-----+</span><br></pre></td></tr></table></figure><h3 id="将ssh私钥转换为gpg作为subkey添加到其他gpg中"><a href="#将ssh私钥转换为gpg作为subkey添加到其他gpg中" class="headerlink" title="将ssh私钥转换为gpg作为subkey添加到其他gpg中"></a>将ssh私钥转换为gpg作为subkey添加到其他gpg中</h3><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><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="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 首先将其转换为pem</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line">d661cfbeb503:/app# ssh-keygen -f testb -p -m pem</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 将testb导入gpg</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 如果有报错提示，可能是版本问题，降版本</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 比如 alpine3.23是有问题的，用alpine3.22先转换再在3.23中导入</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line">d661cfbeb503:/app# pem2openpgp testb &lt; testb | gpg --import</span><br><span class="line">gpg: key C69ED8C1A9E1F9EF: public key &quot;testb&quot; imported</span><br><span class="line">gpg: key C69ED8C1A9E1F9EF: secret key imported</span><br><span class="line">gpg: Total number processed: 1</span><br><span class="line">gpg:               imported: 1</span><br><span class="line">gpg:       secret keys read: 1</span><br><span class="line">gpg:   secret keys imported: 1</span><br><span class="line">d661cfbeb503:/app# gpg --list-keys --with-keygrip --keyid-format SHORT</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096/A9E1F9EF 2026-01-16 [C]</span><br><span class="line">      A45945D8EE060145F5F4C1FEC69ED8C1A9E1F9EF</span><br><span class="line">      Keygrip = AD30946474C95802071D6A8CBEA8B9779FC8DEA5</span><br><span class="line">uid         [ unknown] testb</span><br><span class="line"></span><br><span class="line">pub   rsa4096/6CCA7091 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">      Keygrip = BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4</span><br><span class="line">uid         [ultimate] testa (testa) &lt;testa@example.com&gt;</span><br></pre></td></tr></table></figure><p>将testb作为testa的subkey，并且只用于[A]uthenticate</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><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></pre></td><td class="code"><pre><span class="line">d661cfbeb503:/app# gpg --expert --edit-key testa</span><br><span class="line">gpg (GnuPG) 2.4.9; Copyright (C) 2025 g10 Code GmbH</span><br><span class="line">This is free software: you are free to change and redistribute it.</span><br><span class="line">There is NO WARRANTY, to the extent permitted by law.</span><br><span class="line"></span><br><span class="line">Secret key is available.</span><br><span class="line"></span><br><span class="line">sec  rsa4096/4B3A00756CCA7091</span><br><span class="line">     created: 2026-01-16  expires: never       usage: SCEA</span><br><span class="line">     trust: ultimate      validity: ultimate</span><br><span class="line">[ultimate] (1). testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">gpg&gt; </span><span class="language-bash">addkey</span></span><br><span class="line">Please select what kind of key you want:</span><br><span class="line">   (3) DSA (sign only)</span><br><span class="line">   (4) RSA (sign only)</span><br><span class="line">   (5) Elgamal (encrypt only)</span><br><span class="line">   (6) RSA (encrypt only)</span><br><span class="line">   (7) DSA (set your own capabilities)</span><br><span class="line">   (8) RSA (set your own capabilities)</span><br><span class="line">  (10) ECC (sign only)</span><br><span class="line">  (11) ECC (set your own capabilities)</span><br><span class="line">  (12) ECC (encrypt only)</span><br><span class="line">  (13) Existing key</span><br><span class="line">  (14) Existing key from card</span><br><span class="line">Your selection? 13</span><br><span class="line">Enter the keygrip: AD30946474C95802071D6A8CBEA8B9779FC8DEA5</span><br><span class="line"></span><br><span class="line">Possible actions for this RSA key: Sign Encrypt Authenticate</span><br><span class="line">Current allowed actions: Sign Encrypt</span><br><span class="line"></span><br><span class="line">   (S) Toggle the sign capability</span><br><span class="line">   (E) Toggle the encrypt capability</span><br><span class="line">   (A) Toggle the authenticate capability</span><br><span class="line">   (Q) Finished</span><br><span class="line"></span><br><span class="line">Your selection? A</span><br><span class="line"></span><br><span class="line">Possible actions for this RSA key: Sign Encrypt Authenticate</span><br><span class="line">Current allowed actions: Sign Encrypt Authenticate</span><br><span class="line"></span><br><span class="line">   (S) Toggle the sign capability</span><br><span class="line">   (E) Toggle the encrypt capability</span><br><span class="line">   (A) Toggle the authenticate capability</span><br><span class="line">   (Q) Finished</span><br><span class="line"></span><br><span class="line">Your selection? E</span><br><span class="line"></span><br><span class="line">Possible actions for this RSA key: Sign Encrypt Authenticate</span><br><span class="line">Current allowed actions: Sign Authenticate</span><br><span class="line"></span><br><span class="line">   (S) Toggle the sign capability</span><br><span class="line">   (E) Toggle the encrypt capability</span><br><span class="line">   (A) Toggle the authenticate capability</span><br><span class="line">   (Q) Finished</span><br><span class="line"></span><br><span class="line">Your selection? S</span><br><span class="line"></span><br><span class="line">Possible actions for this RSA key: Sign Encrypt Authenticate</span><br><span class="line">Current allowed actions: Authenticate</span><br><span class="line"></span><br><span class="line">   (S) Toggle the sign capability</span><br><span class="line">   (E) Toggle the encrypt capability</span><br><span class="line">   (A) Toggle the authenticate capability</span><br><span class="line">   (Q) Finished</span><br><span class="line"></span><br><span class="line">Your selection? Q</span><br><span class="line">Please specify how long the key should be valid.</span><br><span class="line">         0 = key does not expire</span><br><span class="line">      &lt;n&gt;  = key expires in n days</span><br><span class="line">      &lt;n&gt;w = key expires in n weeks</span><br><span class="line">      &lt;n&gt;m = key expires in n months</span><br><span class="line">      &lt;n&gt;y = key expires in n years</span><br><span class="line">Key is valid for? (0) 10y</span><br><span class="line">Key expires at Mon Jan 14 08:39:48 2036 UTC</span><br><span class="line">Is this correct? (y/N) y</span><br><span class="line">Really create? (y/N) y</span><br><span class="line"></span><br><span class="line">sec  rsa4096/4B3A00756CCA7091</span><br><span class="line">     created: 2026-01-16  expires: never       usage: SCEA</span><br><span class="line">     trust: ultimate      validity: ultimate</span><br><span class="line">ssb  rsa4096/8E221B1DB894174B</span><br><span class="line">     created: 2026-01-16  expires: 2036-01-14  usage: A</span><br><span class="line">[ultimate] (1). testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">gpg&gt; </span><span class="language-bash">save</span></span><br><span class="line">d661cfbeb503:/app# gpg --list-keys --with-keygrip --keyid-format SHORT</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096/446596D5 2026-01-16 [C]</span><br><span class="line">      372D316C8BF04BCA90883B9A13ADAE51446596D5</span><br><span class="line">      Keygrip = AD30946474C95802071D6A8CBEA8B9779FC8DEA5</span><br><span class="line">uid         [ unknown] testb</span><br><span class="line"></span><br><span class="line">pub   rsa4096/6CCA7091 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">      Keygrip = BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4</span><br><span class="line">uid         [ultimate] testa (testa) &lt;testa@example.com&gt;</span><br><span class="line">sub   rsa4096/B894174B 2026-01-16 [A] [expires: 2036-01-14]</span><br><span class="line">      Keygrip = AD30946474C95802071D6A8CBEA8B9779FC8DEA5</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><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 导出最新的gpg</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line">d661cfbeb503:/app# gpg -a --export-secret-keys -o testa_b_SECRET.gpg testa</span><br><span class="line">d661cfbeb503:/app# gpg -a --export -o testa_b_public.gpg testa</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 删除旧的gpg</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line">d661cfbeb503:/app# gpg --delete-secret-and-public-keys testa testb</span><br><span class="line">gpg (GnuPG) 2.4.9; Copyright (C) 2025 g10 Code GmbH</span><br><span class="line">This is free software: you are free to change and redistribute it.</span><br><span class="line">There is NO WARRANTY, to the extent permitted by law.</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">sec  rsa4096/4B3A00756CCA7091 2026-01-16 testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"></span><br><span class="line">Delete this key from the keyring? (y/N) y</span><br><span class="line">This is a secret key! - really delete? (y/N) y</span><br><span class="line"></span><br><span class="line">pub  rsa4096/4B3A00756CCA7091 2026-01-16 testa (testa) &lt;testa@example.com&gt;</span><br><span class="line"></span><br><span class="line">Delete this key from the keyring? (y/N) y</span><br><span class="line"></span><br><span class="line">pub  rsa4096/13ADAE51446596D5 2026-01-16 testb</span><br><span class="line"></span><br><span class="line">Delete this key from the keyring? (y/N) y</span><br><span class="line">d661cfbeb503:/app#</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 重新导入testa</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#</span></span></span><br><span class="line">d661cfbeb503:/app# gpg --import testa_b_SECRET.gpg testa_b_public.gpg</span><br><span class="line">gpg: key 4B3A00756CCA7091: public key &quot;testa (testa) &lt;testa@example.com&gt;&quot; imported</span><br><span class="line">gpg: key 4B3A00756CCA7091: secret key imported</span><br><span class="line">gpg: key 4B3A00756CCA7091: &quot;testa (testa) &lt;testa@example.com&gt;&quot; not changed</span><br><span class="line">gpg: Total number processed: 2</span><br><span class="line">gpg:               imported: 1</span><br><span class="line">gpg:              unchanged: 1</span><br><span class="line">gpg:       secret keys read: 1</span><br><span class="line">gpg:   secret keys imported: 1</span><br><span class="line">d661cfbeb503:/app#</span><br><span class="line">d661cfbeb503:/app# gpg --list-keys --with-keygrip --keyid-format SHORT</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096/6CCA7091 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">      Keygrip = BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4</span><br><span class="line">uid         [ unknown] testa (testa) &lt;testa@example.com&gt;</span><br><span class="line">sub   rsa4096/B894174B 2026-01-16 [A] [expires: 2036-01-14]</span><br><span class="line">      Keygrip = AD30946474C95802071D6A8CBEA8B9779FC8DEA5</span><br></pre></td></tr></table></figure><p>将testb用于登录验证</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><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="meta prompt_">#</span><span class="language-bash"><span class="comment"># 导出testb的公钥</span></span></span><br><span class="line">d661cfbeb503:/app# gpg --export-ssh-key B894174B!</span><br><span class="line">ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCjV2tQTSqQm9G2guMRqsTIwHEmk5WvMSfQ7w6rOJfI+jzduJJh68i+Icr1FElTJAJ+yYtnZqAFgeA8kAKU3sbKWKK9CjFXZm/SeBMyeIcQqysTZ6dWSQpmkQm4YUJQusYPqCSiyxWsYe5tW9/9d/GkfzTceH/I0CM9OOzUgDzgZd8DL98AsLeW2mbhErG9yUvLoecP2P1crVc8K0/iLMb+PAg+twbo3hHhsWfF2N2ZVcq1oeKGs6WjqnmYCJcWXuIO6J5DcFx5681pErhrD4j7qbwKisEsqOcBIHUF+XcvQ6O5xm/Ua8P5h2oX0vFEt0kQxL7poX2GpKQ9WPBzvKnU8c4MS3gb0xvXj/1bZdO21V0FowDd+6cbavVPkB4S+98mHeJshyKzPRIWwA2tY7d2uFmbbWnu2qoE1ogAD157q5WTCPRlu9VRB6seCzunr5OF7PJ2yQMSWTqXcrXaIY+uPeGHeT3BcI4J/RxNR5QkSYWv8+BDvTPrX5miDrYrUSYRj4QrWrg5tX0nrv5UEzh2hyyld5fDpK8Hp7PAtjpEj3EA8Wxy38jihgOQ9uETb9Qj2MqyH5LTWHJW4vd1tJGA2MglYkBAqVDL1pF0IGHHXQ92b/RGG8oKr+cv0tkqF58MG9T5gPIjldc8xYk2/3QyZ5XggvP5xmHhChdx8oz/PQ== openpgp:0xB894174B</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 设置testb用于ssh登录验证</span></span></span><br><span class="line">d661cfbeb503:/app# echo &quot;AD30946474C95802071D6A8CBEA8B9779FC8DEA5&quot; &gt; ~/.gnupg/sshcontrol</span><br><span class="line">d661cfbeb503:/app# cat ~/.gnupg/sshcontrol</span><br><span class="line">AD30946474C95802071D6A8CBEA8B9779FC8DEA5</span><br><span class="line">d661cfbeb503:/app# gpg-connect-agent --quiet /bye</span><br><span class="line">d661cfbeb503:/app# export SSH_AUTH_SOCK=&quot;$(gpgconf --list-dirs agent-ssh-socket)&quot;</span><br><span class="line">d661cfbeb503:/app# ssh-add -l</span><br><span class="line">4096 SHA256:wRwKd/0OVS93gZ/tRTU3uVbtVoDIeA2sjxGeTuu4wus (none) (RSA)</span><br><span class="line">d661cfbeb503:/app#</span><br></pre></td></tr></table></figure><h2 id="将GPG-subkey-testb-转换为Openssh"><a href="#将GPG-subkey-testb-转换为Openssh" class="headerlink" title="将GPG subkey(testb)转换为Openssh"></a>将GPG subkey(testb)转换为Openssh</h2><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><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">d661cfbeb503:/app# gpg --list-keys --with-keygrip --keyid-format short</span><br><span class="line">[keyboxd]</span><br><span class="line">---------</span><br><span class="line">pub   rsa4096/6CCA7091 2026-01-16 [SCEA]</span><br><span class="line">      C59DA9100483F2F71C4238464B3A00756CCA7091</span><br><span class="line">      Keygrip = BB5DEEF5B6EDA9C88276A101687AF84D328CC8F4</span><br><span class="line">uid         [ unknown] testa (testa) &lt;testa@example.com&gt;</span><br><span class="line">sub   rsa4096/B894174B 2026-01-16 [A] [expires: 2036-01-14]</span><br><span class="line">      Keygrip = AD30946474C95802071D6A8CBEA8B9779FC8DEA5</span><br><span class="line"></span><br><span class="line">d661cfbeb503:/app# gpg --export-secret-keys B894174B! | openpgp2ssh B894174B</span><br><span class="line">-----BEGIN RSA PRIVATE KEY-----</span><br><span class="line">MIIJKAIBAAKCAgEAo1drUE0qkJvRtoLjEarEyMBxJpOVrzEn0O8OqziXyPo83biS</span><br><span class="line">...</span><br><span class="line">6x1wVPjwFe8Vvx4hJcWiaVO8Cgi2BxlY3cUxEbaSbBs1c/5dw+LUTc0tzdg=</span><br><span class="line">-----END RSA PRIVATE KEY-----</span><br><span class="line">d661cfbeb503:/app# </span><br><span class="line">d661cfbeb503:/app# gpg --export-secret-keys B894174B! | openpgp2ssh B894174B &gt; testb_rsa.pub</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 对比testb_rsa和原testb.pub 是一致的</span></span></span><br><span class="line">d661cfbeb503:/app# ssh-keygen -y -f testb_rsa.pub</span><br><span class="line">ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCjV2tQTSqQm9G2guMRqsTIwHEmk5WvMSfQ7w6rOJfI+jzduJJh68i+Icr1FElTJAJ+yYtnZqAFgeA8kAKU3sbKWKK9CjFXZm/SeBMyeIcQqysTZ6dWSQpmkQm4YUJQusYPqCSiyxWsYe5tW9/9d/GkfzTceH/I0CM9OOzUgDzgZd8DL98AsLeW2mbhErG9yUvLoecP2P1crVc8K0/iLMb+PAg+twbo3hHhsWfF2N2ZVcq1oeKGs6WjqnmYCJcWXuIO6J5DcFx5681pErhrD4j7qbwKisEsqOcBIHUF+XcvQ6O5xm/Ua8P5h2oX0vFEt0kQxL7poX2GpKQ9WPBzvKnU8c4MS3gb0xvXj/1bZdO21V0FowDd+6cbavVPkB4S+98mHeJshyKzPRIWwA2tY7d2uFmbbWnu2qoE1ogAD157q5WTCPRlu9VRB6seCzunr5OF7PJ2yQMSWTqXcrXaIY+uPeGHeT3BcI4J/RxNR5QkSYWv8+BDvTPrX5miDrYrUSYRj4QrWrg5tX0nrv5UEzh2hyyld5fDpK8Hp7PAtjpEj3EA8Wxy38jihgOQ9uETb9Qj2MqyH5LTWHJW4vd1tJGA2MglYkBAqVDL1pF0IGHHXQ92b/RGG8oKr+cv0tkqF58MG9T5gPIjldc8xYk2/3QyZ5XggvP5xmHhChdx8oz/PQ==</span><br><span class="line">d661cfbeb503:/app# cat testb.pub</span><br><span class="line">ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCjV2tQTSqQm9G2guMRqsTIwHEmk5WvMSfQ7w6rOJfI+jzduJJh68i+Icr1FElTJAJ+yYtnZqAFgeA8kAKU3sbKWKK9CjFXZm/SeBMyeIcQqysTZ6dWSQpmkQm4YUJQusYPqCSiyxWsYe5tW9/9d/GkfzTceH/I0CM9OOzUgDzgZd8DL98AsLeW2mbhErG9yUvLoecP2P1crVc8K0/iLMb+PAg+twbo3hHhsWfF2N2ZVcq1oeKGs6WjqnmYCJcWXuIO6J5DcFx5681pErhrD4j7qbwKisEsqOcBIHUF+XcvQ6O5xm/Ua8P5h2oX0vFEt0kQxL7poX2GpKQ9WPBzvKnU8c4MS3gb0xvXj/1bZdO21V0FowDd+6cbavVPkB4S+98mHeJshyKzPRIWwA2tY7d2uFmbbWnu2qoE1ogAD157q5WTCPRlu9VRB6seCzunr5OF7PJ2yQMSWTqXcrXaIY+uPeGHeT3BcI4J/RxNR5QkSYWv8+BDvTPrX5miDrYrUSYRj4QrWrg5tX0nrv5UEzh2hyyld5fDpK8Hp7PAtjpEj3EA8Wxy38jihgOQ9uETb9Qj2MqyH5LTWHJW4vd1tJGA2MglYkBAqVDL1pF0IGHHXQ92b/RGG8oKr+cv0tkqF58MG9T5gPIjldc8xYk2/3QyZ5XggvP5xmHhChdx8oz/PQ== testb@exmaple.com</span><br><span class="line">d661cfbeb503:/app#</span><br></pre></td></tr></table></figure><h1 id="结束"><a href="#结束" class="headerlink" title="结束"></a>结束</h1>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;测试环境：alpine:3.22(docker)&lt;br&gt;基础软件：gpg gpg-agent openssl openssh-client monkeysphere bash&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第一部分、第二部分相关的文章比较多，第三部分相对较少。这篇文章基本上都是代码，是一篇完全实操过程的记录。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;GPG&lt;/code&gt;windows对应版本是&lt;code&gt;Kleopatra&lt;/code&gt;&lt;br&gt;文中的一些操作有对应的图形界面，有些没有，比如第三部分（也可能是我没有找到）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font color=red&gt;&lt;strong&gt;低版本可导入高版本，反过来不行，因此，第一步先确认使用的环境以及版本。&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;</summary>
    
    
    
    <category term="gpg" scheme="https://www.mingilin.com/categories/gpg/"/>
    
    
    <category term="gpg" scheme="https://www.mingilin.com/tags/gpg/"/>
    
  </entry>
  
  <entry>
    <title>小狼毫输入法从入门到放弃</title>
    <link href="https://www.mingilin.com/2026/01/15/other/other-rime/"/>
    <id>https://www.mingilin.com/2026/01/15/other/other-rime/</id>
    <published>2026-01-15T02:04:48.000Z</published>
    <updated>2026-01-15T05:58:15.926Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p><a href="https://rime.im/">RIME</a>是一个输入法引擎，对应windows版本的是小狼毫输入法（实话说名字起得挺难听的），为什么还有人用呢，主要是自由以及不被收集数据，缺点就是没有语音输入</p><span id="more"></span><p>好坏不做过多讨论，我们主要来看下怎么配置<br>以雾凇拼音为例：<a href="https://github.com/iDvel/rime-ice">https://github.com/iDvel/rime-ice</a></p><p>配置文件：</p><ul><li>default.yaml 设置输入法、如何切换输入法、翻页等</li><li>*.schema.yaml 各种输入方案：全拼、双拼、五笔。。。</li><li>weasel.yaml 小狼毫( Win 版本 ) 主要是输入法皮肤等</li><li>*.dict.yaml 字典，一般不需要了解</li></ul><p>上面的都是默认的配置，如果我想修改怎么办呢？<br>一种方式是：<del>可以在原文件上修改，但是不推荐</del><br>推荐方式是：<strong>增加一个配置文件，可以替换掉原配置的部分内容，即<code>*.custom.yaml</code></strong><br>例如:</p><ul><li><code>double_pinyin_flypy.schema.yaml</code> &#x3D;&gt; <code>double_pinyin_flypy.custom.yaml</code></li><li><code>default.yaml</code> &#x3D;&gt; <code>default.custom.yaml</code></li><li><code>weasel.yaml</code> &#x3D;&gt; <code>weasel.custom.yaml</code></li></ul><p><code>xxx.custom.yaml</code>配置格式：</p><figure class="highlight yaml"><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="attr">patch:</span></span><br><span class="line">  <span class="string">xxx</span></span><br></pre></td></tr></table></figure><h2 id="一些命令"><a href="#一些命令" class="headerlink" title="一些命令"></a>一些命令</h2><ul><li><code>WeaselSetup.exe /userdir:配置目录</code> - 修改配置目录</li><li><code>WeaselDeployer.exe /deploy</code>       - 重新部署</li><li><code>WeaselDeployer.exe /sync</code>         - 用户资料同步</li></ul><blockquote><p>这些命令都可以在开始菜单中找到</p></blockquote><h2 id="一些常用的配置"><a href="#一些常用的配置" class="headerlink" title="一些常用的配置"></a>一些常用的配置</h2><h3 id="候选词个数"><a href="#候选词个数" class="headerlink" title="候选词个数"></a>候选词个数</h3><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"># default.custom.yaml or *.custom.yaml</span></span><br><span class="line"><span class="attr">patch:</span></span><br><span class="line">  <span class="attr">menu:</span></span><br><span class="line">    <span class="attr">page_size:</span> <span class="number">10</span>  <span class="comment"># 切换候选词个数</span></span><br></pre></td></tr></table></figure><h3 id="候选词横向显示"><a href="#候选词横向显示" class="headerlink" title="候选词横向显示"></a>候选词横向显示</h3><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"># wasel.custom.yaml</span></span><br><span class="line"><span class="attr">patch:</span></span><br><span class="line">  <span class="attr">style:</span></span><br><span class="line">    <span class="attr">horizontal:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h2 id="rime输入法各种版本"><a href="#rime输入法各种版本" class="headerlink" title="rime输入法各种版本"></a>rime输入法各种版本</h2><ul><li>薄荷拼音：<a href="https://github.com/Mintimate/oh-my-rime.git">https://github.com/Mintimate/oh-my-rime.git</a><br>这个版本增加了混输和五笔，但是默认6个候选词，需要修改好多文件<br>而且默认的皮肤字体有点不舒服，我是直接用雾凇拼音的<code>weasel.yaml</code>覆盖薄荷拼音的默认配置</li><li>雾凇拼音：<a href="https://github.com/iDvel/rime-ice.git">https://github.com/iDvel/rime-ice.git</a><br>这个版本比较好用，基本上不用改就可以用，就我个人而言，只是增加了模糊音<br>如果只使用拼音的话，这个就很好用了</li><li>其他版本：自己收集吧</li></ul><h2 id="已知的问题"><a href="#已知的问题" class="headerlink" title="已知的问题"></a>已知的问题</h2><ol><li>部分软件适配有问题，输入窗口无法跟随</li><li>有时候会卡</li></ol><h2 id="自己实现的中文拼音音调schema"><a href="#自己实现的中文拼音音调schema" class="headerlink" title="自己实现的中文拼音音调schema"></a>自己实现的中文拼音音调schema</h2><p>最后分享一个自己实现的快速输入拼音音调的schema</p><figure class="highlight yaml"><figcaption><span>mhome_pinyin_tone.schema.yaml</span><a href="/downloads/code/rime/mhome_pinyin_tone.schema.yaml.txt">view raw</a></figcaption><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># Rime schema</span></span><br><span class="line"><span class="comment"># encoding: utf-8</span></span><br><span class="line"><span class="comment"># Date: 2026-01-07 15:07:50</span></span><br><span class="line"></span><br><span class="line"><span class="attr">schema:</span></span><br><span class="line">  <span class="attr">schema_id:</span> <span class="string">mhome_pinyin_tone</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">中文拼音音调</span></span><br><span class="line">  <span class="attr">version:</span> <span class="string">&quot;1.2&quot;</span></span><br><span class="line">  <span class="attr">description:</span> <span class="string">中文拼音音调快速输入</span></span><br><span class="line"></span><br><span class="line"><span class="attr">switches:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">full_shape</span></span><br><span class="line">    <span class="attr">states:</span> [ <span class="string">半角</span>, <span class="string">全角</span> ]</span><br><span class="line">    <span class="attr">reset:</span> <span class="number">0</span></span><br><span class="line"></span><br><span class="line"><span class="attr">engine:</span></span><br><span class="line">  <span class="attr">processors:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">key_binder</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">punctuator</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">selector</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">express_editor</span></span><br><span class="line">  <span class="attr">segmentors:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">punct_segmentor</span></span><br><span class="line">  <span class="attr">translators:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">punct_translator</span></span><br><span class="line"><span class="attr">menu:</span></span><br><span class="line">  <span class="comment"># 选择候选词的键，相当于 12345，</span></span><br><span class="line">  <span class="comment"># 因为这个输入方案中的数字已经用于输入文字了，</span></span><br><span class="line">  <span class="comment"># 不能使用12345作为候选词的选择键</span></span><br><span class="line">  <span class="attr">alternative_select_keys:</span> <span class="string">&quot;01234&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">key_binder:</span></span><br><span class="line">  <span class="attr">bindings:</span></span><br><span class="line">    <span class="bullet">-</span> {<span class="attr">accept:</span> <span class="string">semicolon</span>, <span class="attr">send:</span> <span class="string">c</span>, <span class="attr">when:</span> <span class="string">has_menu</span>}  <span class="comment"># 候选2 用分号</span></span><br><span class="line">    <span class="bullet">-</span> {<span class="attr">accept:</span> <span class="string">apostrophe</span>, <span class="attr">send:</span> <span class="string">e</span>, <span class="attr">when:</span> <span class="string">has_menu</span>} <span class="comment"># 候选3 用单引号</span></span><br><span class="line"></span><br><span class="line"><span class="attr">punctuator:</span></span><br><span class="line">  <span class="attr">half_shape:</span></span><br><span class="line">    <span class="attr">&quot;a&quot;:</span> [<span class="string">a</span>,<span class="string">ā</span>,<span class="string">á</span>,<span class="string">ǎ</span>,<span class="string">à</span>]</span><br><span class="line">    <span class="attr">&quot;o&quot;:</span> [<span class="string">o</span>,<span class="string">ō</span>,<span class="string">ó</span>,<span class="string">ǒ</span>,<span class="string">ò</span>]</span><br><span class="line">    <span class="attr">&quot;e&quot;:</span> [<span class="string">e</span>,<span class="string">ē</span>,<span class="string">é</span>,<span class="string">ě</span>,<span class="string">è</span>]</span><br><span class="line">    <span class="attr">&quot;i&quot;:</span> [<span class="string">i</span>,<span class="string">ī</span>,<span class="string">í</span>,<span class="string">ǐ</span>,<span class="string">ì</span>]</span><br><span class="line">    <span class="attr">&quot;u&quot;:</span> [<span class="string">u</span>,<span class="string">ū</span>,<span class="string">ú</span>,<span class="string">ǔ</span>,<span class="string">ù</span>]</span><br><span class="line">    <span class="attr">&quot;v&quot;:</span> [<span class="string">ü</span>,<span class="string">ǖ</span>,<span class="string">ǘ</span>,<span class="string">ǚ</span>,<span class="string">ǜ</span>]</span><br><span class="line"></span><br><span class="line">  <span class="attr">full_shape:</span></span><br><span class="line">    <span class="attr">&quot;a&quot;:</span> [<span class="string">a</span>,<span class="string">ā</span>,<span class="string">á</span>,<span class="string">ǎ</span>,<span class="string">à</span>]</span><br><span class="line">    <span class="attr">&quot;o&quot;:</span> [<span class="string">o</span>,<span class="string">ō</span>,<span class="string">ó</span>,<span class="string">ǒ</span>,<span class="string">ò</span>]</span><br><span class="line">    <span class="attr">&quot;e&quot;:</span> [<span class="string">e</span>,<span class="string">ē</span>,<span class="string">é</span>,<span class="string">ě</span>,<span class="string">è</span>]</span><br><span class="line">    <span class="attr">&quot;i&quot;:</span> [<span class="string">i</span>,<span class="string">ī</span>,<span class="string">í</span>,<span class="string">ǐ</span>,<span class="string">ì</span>]</span><br><span class="line">    <span class="attr">&quot;u&quot;:</span> [<span class="string">u</span>,<span class="string">ū</span>,<span class="string">ú</span>,<span class="string">ǔ</span>,<span class="string">ù</span>]</span><br><span class="line">    <span class="attr">&quot;v&quot;:</span> [<span class="string">ü</span>,<span class="string">ǖ</span>,<span class="string">ǘ</span>,<span class="string">ǚ</span>,<span class="string">ǜ</span>]</span><br></pre></td></tr></table></figure><h2 id="最后，没时间折腾的同学还是放弃吧。"><a href="#最后，没时间折腾的同学还是放弃吧。" class="headerlink" title="最后，没时间折腾的同学还是放弃吧。"></a><strong>最后，没时间折腾的同学还是放弃吧。</strong></h2>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;a href=&quot;https://rime.im/&quot;&gt;RIME&lt;/a&gt;是一个输入法引擎，对应windows版本的是小狼毫输入法（实话说名字起得挺难听的），为什么还有人用呢，主要是自由以及不被收集数据，缺点就是没有语音输入&lt;/p&gt;</summary>
    
    
    
    <category term="other" scheme="https://www.mingilin.com/categories/other/"/>
    
    
    <category term="other" scheme="https://www.mingilin.com/tags/other/"/>
    
  </entry>
  
  <entry>
    <title>Centos7 SSH增加多因子验证(google-authenticator)</title>
    <link href="https://www.mingilin.com/2024/11/07/centos/centos7-2fa/"/>
    <id>https://www.mingilin.com/2024/11/07/centos/centos7-2fa/</id>
    <published>2024-11-07T02:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.370Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>按照一些文章开启ssh的多因子验证，发现不起作用，参考了一些国外的文章才起作用，记录下。</p><span id="more"></span><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><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">yum install epel-release</span><br><span class="line">yum install google-authenticator</span><br></pre></td></tr></table></figure><h2 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h2><h3 id="google-authenticator"><a href="#google-authenticator" class="headerlink" title="google-authenticator"></a>google-authenticator</h3><figure class="highlight plaintext"><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">google-authenticator</span><br><span class="line">Do you want authentication tokens to be time-based (y/n) y</span><br><span class="line">Do you want me to update your &quot;/root/.google_authenticator&quot; file? (y/n) y</span><br><span class="line">your chances to notice or even prevent man-in-the-middle attacks (y/n) y</span><br><span class="line">Do you want to do so? (y/n) y</span><br><span class="line">Do you want to enable rate-limiting? (y/n) y</span><br></pre></td></tr></table></figure><p>用2FA客户端(比如：Stratum - Authenticator APP)扫描二维码，保存</p><blockquote><p>记得备份下<code>/root/.google_authenticator</code>文件</p></blockquote><h3 id="配置-etc-pam-d-sshd"><a href="#配置-etc-pam-d-sshd" class="headerlink" title="配置/etc/pam.d/sshd"></a>配置<code>/etc/pam.d/sshd</code></h3><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><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">%PAM-1.0</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 添加 pam_google_authenticator.so</span></span></span><br><span class="line">auth       required     pam_google_authenticator.so</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 注释掉 password-auth</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">auth       substack     password-auth</span></span><br></pre></td></tr></table></figure><blockquote><p><code>#auth       substack     password-auth </code>注释掉很关键<br>很多文章中没有这一步！！！</p></blockquote><h3 id="配置-etc-ssh-sshd-config"><a href="#配置-etc-ssh-sshd-config" class="headerlink" title="配置/etc/ssh/sshd_config"></a>配置<code>/etc/ssh/sshd_config</code></h3><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><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="meta prompt_"># </span><span class="language-bash">ChallengeResponseAuthentication设置为<span class="built_in">yes</span></span></span><br><span class="line">ChallengeResponseAuthentication yes</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">ChallengeResponseAuthentication no</span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">添加一行</span></span><br><span class="line">AuthenticationMethods publickey,password publickey,keyboard-interactive</span><br></pre></td></tr></table></figure><blockquote><p><code>AuthenticationMethods publickey,password publickey,keyboard-interactive</code>新加的一行很关键<br>很多文章中没有这一步！！！</p></blockquote><h2 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h2><p><code>systemctl restart sshd</code></p><figure class="highlight plaintext"><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">ssh -p 22 root@xxxx</span><br><span class="line">Verification code:</span><br><span class="line">Last login: xxxxx</span><br></pre></td></tr></table></figure><blockquote><p>需要注意的是，默认情况下一个code最多只能验证3次。<br>验证不通过的话就等下一个code</p></blockquote><h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h2><ol><li><a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-multi-factor-authentication-for-ssh-on-centos-7">https://www.digitalocean.com/community/tutorials/how-to-set-up-multi-factor-authentication-for-ssh-on-centos-7</a></li></ol>]]></content>
    
    
    <summary type="html">&lt;p&gt;按照一些文章开启ssh的多因子验证，发现不起作用，参考了一些国外的文章才起作用，记录下。&lt;/p&gt;</summary>
    
    
    
    <category term="centos" scheme="https://www.mingilin.com/categories/centos/"/>
    
    
    <category term="centos7" scheme="https://www.mingilin.com/tags/centos7/"/>
    
  </entry>
  
  <entry>
    <title>分割A3文档为A4</title>
    <link href="https://www.mingilin.com/2024/11/04/other/other-a3-to-a4/"/>
    <id>https://www.mingilin.com/2024/11/04/other/other-a3-to-a4/</id>
    <published>2024-11-04T10:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.386Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>最近需要将A3文档（PDF）分割成A4，毕竟家里只有可以打印A4的打印机</p><span id="more"></span><p>网上找了很多方案，要么广告要么收费</p><p>使用<code>PDF-XChange Viewer</code>打印文档，打印机选择虚拟打印机</p><h2 id="第一步：先设置纸张类型"><a href="#第一步：先设置纸张类型" class="headerlink" title="第一步：先设置纸张类型"></a>第一步：先设置纸张类型</h2><p><img src="/downloads/assets/20241104155742.png"></p><h2 id="第二步：配置打印"><a href="#第二步：配置打印" class="headerlink" title="第二步：配置打印"></a>第二步：配置打印</h2><p><img src="/downloads/assets/20241104155012.png"></p><blockquote><p>缩放类型：并排大型页面<br>重叠：0</p></blockquote>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近需要将A3文档（PDF）分割成A4，毕竟家里只有可以打印A4的打印机&lt;/p&gt;</summary>
    
    
    
    <category term="other" scheme="https://www.mingilin.com/categories/other/"/>
    
    
    <category term="other" scheme="https://www.mingilin.com/tags/other/"/>
    
  </entry>
  
  <entry>
    <title>elixir hexpm 镜像搭建</title>
    <link href="https://www.mingilin.com/2024/11/04/elixir/elixir-hexpm-mirror/"/>
    <id>https://www.mingilin.com/2024/11/04/elixir/elixir-hexpm-mirror/</id>
    <published>2024-11-04T07:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.372Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>搭建一个<a href="https://repo.hex.pm/">https://repo.hex.pm</a>镜像站，用于加速<code>mix deps.get</code></p><span id="more"></span><h2 id="方式1：子目录"><a href="#方式1：子目录" class="headerlink" title="方式1：子目录"></a>方式1：子目录</h2><figure class="highlight nginx"><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">## https://xxx/hexpm/</span></span><br><span class="line"><span class="attribute">rewrite</span><span class="regexp"> ^/hexpm$</span> /hexpm/ <span class="literal">permanent</span>;</span><br><span class="line"><span class="section">location</span> <span class="regexp">~ &quot;^/hexpm/(.*)&quot;</span> &#123;</span><br><span class="line">    <span class="attribute">proxy_request_buffering</span> <span class="literal">off</span>;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">proxy_buffer_size</span> <span class="number">64k</span>;</span><br><span class="line">    <span class="attribute">proxy_buffers</span>   <span class="number">32</span> <span class="number">64k</span>;</span><br><span class="line">    <span class="attribute">proxy_busy_buffers_size</span> <span class="number">128k</span>;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">proxy_http_version</span> <span class="number">1</span>.<span class="number">1</span>;</span><br><span class="line">    <span class="attribute">proxy_connect_timeout</span> <span class="number">10s</span>;</span><br><span class="line">    <span class="attribute">proxy_read_timeout</span> <span class="number">10s</span>;</span><br><span class="line">    <span class="attribute">proxy_socket_keepalive</span> <span class="literal">on</span>;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">proxy_ssl_server_name</span> <span class="literal">on</span>;</span><br><span class="line">    <span class="attribute">proxy_ssl_name</span> repo.hex.pm;</span><br><span class="line">    <span class="attribute">proxy_ssl_verify</span> <span class="literal">off</span>;</span><br><span class="line">    <span class="attribute">proxy_set_header</span> Host repo.hex.pm;</span><br><span class="line">    <span class="attribute">proxy_pass</span> https://repo.hex.pm/<span class="variable">$1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="方式2：域名"><a href="#方式2：域名" class="headerlink" title="方式2：域名"></a>方式2：域名</h2><figure class="highlight nginx"><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"><span class="comment">## https://xxxxx</span></span><br><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span> <span class="number">443</span> ssl http2;</span><br><span class="line">    <span class="attribute">server_name</span> xxxxx;</span><br><span class="line">    <span class="attribute">root</span> /data/github;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">client_max_body_size</span> <span class="number">2G</span>;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">error_page</span> <span class="number">497</span>  https://<span class="variable">$host</span><span class="variable">$request_uri</span>;</span><br><span class="line"></span><br><span class="line">    <span class="section">location</span> / &#123;</span><br><span class="line">        <span class="attribute">proxy_request_buffering</span> <span class="literal">off</span>;</span><br><span class="line"></span><br><span class="line">        <span class="attribute">proxy_buffer_size</span> <span class="number">64k</span>;</span><br><span class="line">        <span class="attribute">proxy_buffers</span>   <span class="number">32</span> <span class="number">64k</span>;</span><br><span class="line">        <span class="attribute">proxy_busy_buffers_size</span> <span class="number">128k</span>;</span><br><span class="line"></span><br><span class="line">        <span class="attribute">proxy_http_version</span> <span class="number">1</span>.<span class="number">1</span>;</span><br><span class="line">        <span class="attribute">proxy_connect_timeout</span> <span class="number">10s</span>;</span><br><span class="line">        <span class="attribute">proxy_read_timeout</span> <span class="number">10s</span>;</span><br><span class="line">        <span class="attribute">proxy_socket_keepalive</span> <span class="literal">on</span>;</span><br><span class="line"></span><br><span class="line">        <span class="attribute">proxy_ssl_server_name</span> <span class="literal">on</span>;</span><br><span class="line">        <span class="attribute">proxy_ssl_name</span> repo.hex.pm;</span><br><span class="line">        <span class="attribute">proxy_ssl_verify</span> <span class="literal">off</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> Host repo.hex.pm;</span><br><span class="line">        <span class="attribute">proxy_pass</span> https://repo.hex.pm;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">## 其他配置</span></span><br><span class="line">    <span class="comment">## ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;搭建一个&lt;a href=&quot;https://repo.hex.pm/&quot;&gt;https://repo.hex.pm&lt;/a&gt;镜像站，用于加速&lt;code&gt;mix deps.get&lt;/code&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="erlang" scheme="https://www.mingilin.com/categories/erlang/"/>
    
    <category term="elixir" scheme="https://www.mingilin.com/categories/erlang/elixir/"/>
    
    
    <category term="erlang" scheme="https://www.mingilin.com/tags/erlang/"/>
    
    <category term="elixir" scheme="https://www.mingilin.com/tags/elixir/"/>
    
  </entry>
  
  <entry>
    <title>微信8.0.50回退到旧版本8.0.46，取消服务号折叠</title>
    <link href="https://www.mingilin.com/2024/07/15/other/other-wechat-service/"/>
    <id>https://www.mingilin.com/2024/07/15/other/other-wechat-service/</id>
    <published>2024-07-15T08:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.391Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>微信最新版本<code>8.0.50</code>开启了服务号折叠内测，非常不友好，这个教程将微信回退到旧版本。经测试，回退到<code>8.0.49</code>是没有用的，看版本记录在<code>8.0.48</code>包大了很多，保险起见，将版本回退到<code>8.0.46</code>。<br><img src="/downloads/assets/20240715163702.png"></p><span id="more"></span><h2 id="第一步下载旧版本"><a href="#第一步下载旧版本" class="headerlink" title="第一步下载旧版本"></a>第一步下载旧版本</h2><p><code>8.0.46</code>版本的下载地址：<a href="https://www.wandoujia.com/apps/596157/history_v2540">https://www.wandoujia.com/apps/596157/history_v2540</a></p><h2 id="使用adb安装"><a href="#使用adb安装" class="headerlink" title="使用adb安装"></a>使用adb安装</h2><blockquote><p>前提：确保PC上已经安装了<code>adb</code><br>下载地址：<a href="https://developer.android.com/tools/releases/platform-tools?hl=zh-cn">https://developer.android.com/tools/releases/platform-tools?hl=zh-cn</a><br>下载完成后添加环境变量，具体百度吧。</p></blockquote><ol><li><p>打开开发者模式<br>我用的是小米的手机<br>在<code>设置</code>-&gt;<code>我的设备</code>-&gt;<code>全部参数</code>-&gt;<code>MIUI版本</code><br>连续点击&#96;MIUI版本</p></li><li><p>配对<br>在<code>设置</code>-&gt;<code>更多设置</code>-&gt;<code>开发者选项</code>-&gt;<code>无线调试</code>中打开<code>无线调试</code>，再点击<code>使用配对码配对设备</code><br>命令行界面输入：<code>adb pair IP:端口</code></p></li><li><p>连接<br>在<code>无线调试</code>中，查看<code>IP地址和端口</code><br>命令行界面输入：<code>adb connect IP:端口</code><br>正常情况下，使用<code>adb devices</code>就可以看到刚才添加的设备了</p></li><li><p>安装<br>命令行界面输入：<code>adb install -r -d 刚刚下载的微信.apk</code><br>等待<code>Success</code>提示成功。</p></li></ol><figure class="highlight plaintext"><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">PS C:\Users\Administrator&gt; adb pair 192.168.50.31:32985</span><br><span class="line">Enter pairing code: 038184</span><br><span class="line">Successfully paired to 192.168.50.31:32985 [guid=adb-7lgm5p7xcqjbww9l-05Nyrj]</span><br><span class="line"></span><br><span class="line">PS C:\Users\Administrator&gt; adb connect 192.168.50.31:46233</span><br><span class="line">connected to 192.168.50.31:46233</span><br><span class="line"></span><br><span class="line">PS C:\Users\Administrator&gt; adb devices</span><br><span class="line">List of devices attached</span><br><span class="line">192.168.50.31:46233     device</span><br><span class="line"></span><br><span class="line">PS C:\Users\Administrator&gt; cd D:\Downloads\</span><br><span class="line"></span><br><span class="line">PS D:\Downloads&gt; adb install -r -d .\106_5e9203c6c5072b07d2a39f9ceac2a0ed.apk</span><br><span class="line">Performing Streamed Install</span><br><span class="line">Success</span><br></pre></td></tr></table></figure><h2 id="后续"><a href="#后续" class="headerlink" title="后续"></a>后续</h2><p>已经折叠的服务号需要重新设置才行，比如置顶。。。<br>还要记得在应用商店设置禁止更新。。。</p><h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h2><ol><li><a href="https://www.bilibili.com/read/cv28823105/?jump_opus=1">https://www.bilibili.com/read/cv28823105/?jump_opus&#x3D;1</a></li></ol>]]></content>
    
    
    <summary type="html">&lt;p&gt;微信最新版本&lt;code&gt;8.0.50&lt;/code&gt;开启了服务号折叠内测，非常不友好，这个教程将微信回退到旧版本。经测试，回退到&lt;code&gt;8.0.49&lt;/code&gt;是没有用的，看版本记录在&lt;code&gt;8.0.48&lt;/code&gt;包大了很多，保险起见，将版本回退到&lt;code&gt;8.0.46&lt;/code&gt;。&lt;br&gt;&lt;img src=&quot;/downloads/assets/20240715163702.png&quot;&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="other" scheme="https://www.mingilin.com/categories/other/"/>
    
    
    <category term="other" scheme="https://www.mingilin.com/tags/other/"/>
    
  </entry>
  
  <entry>
    <title>erlang使用rsa实现sign/verify</title>
    <link href="https://www.mingilin.com/2023/11/02/erlang/erlang-rsa-sign-verify/"/>
    <id>https://www.mingilin.com/2023/11/02/erlang/erlang-rsa-sign-verify/</id>
    <published>2023-11-02T01:20:00.000Z</published>
    <updated>2026-01-15T05:33:18.379Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>最近需要erlang使用rsa实现签名验证<br>在网上搜了好久终于拼接成一份完整的代码</p><span id="more"></span><h3 id="rsa常用的格式"><a href="#rsa常用的格式" class="headerlink" title="rsa常用的格式"></a>rsa常用的格式</h3><h4 id="私钥"><a href="#私钥" class="headerlink" title="私钥"></a>私钥</h4><ul><li>格式1<figure class="highlight plaintext"><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">-----BEGIN PRIVATE KEY-----</span><br><span class="line">MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDDxRpuKIdYQ3lR</span><br><span class="line">...</span><br><span class="line">mXCNDx5bSbbPL+WMY8c7F7K0krOfl8Vtzg5cCfo45+IsLCM16sDT0MhLCPUMWj0k</span><br><span class="line">cd4bKcAc3CENaL3U03oLE58r</span><br><span class="line">-----END PRIVATE KEY-----</span><br></pre></td></tr></table></figure></li><li>格式2<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MIIEvgI...0kcd4bKcAc3CENaL3U03oLE58r</span><br></pre></td></tr></table></figure></li></ul><h4 id="公钥"><a href="#公钥" class="headerlink" title="公钥"></a>公钥</h4><ul><li>格式1<figure class="highlight plaintext"><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">-----BEGIN PUBLIC KEY-----</span><br><span class="line">MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw8UabiiHWEN5UR5SByS2</span><br><span class="line">...</span><br><span class="line">oK5jmjNnFsCrWbkd68H6tsm9dGPcUMgNWxeahU/8tSOtX94AaTfU4cp846Yn7dH4</span><br><span class="line">JQIDAQAB</span><br><span class="line">-----END PUBLIC KEY-----</span><br></pre></td></tr></table></figure></li><li>格式2<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh-rsa MIIEvgI...0kcd4bKcAc3CENaL3U03oLE58r</span><br></pre></td></tr></table></figure></li></ul><h3 id="贴代码"><a href="#贴代码" class="headerlink" title="贴代码"></a>贴代码</h3><p>简单逻辑就是将各种格式的key转换如下格式：</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">-----BEGIN XXXX KEY-----</span><br><span class="line">...</span><br><span class="line">-----END XXXX KEY-----</span><br></pre></td></tr></table></figure><p>然后调用<code>public_key:pem_decode/1</code>, <code>public_key:pem_entry_decode/1</code>加载key<br>若是从目录下加载，目录下的key名字必须是<code>ssh_host_rsa_key</code>,<code>ssh_host_rsa_key.pub</code></p><figure class="highlight erlang"><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><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">-module</span><span class="params">(rsa_sign_verify)</span>.</span><br><span class="line"></span><br><span class="line"><span class="keyword">-include_lib</span><span class="params">(<span class="string">&quot;public_key/include/public_key.hrl&quot;</span>)</span>.</span><br><span class="line"></span><br><span class="line"><span class="keyword">-export</span><span class="params">([sign/<span class="number">2</span>, verify/<span class="number">3</span>])</span>.</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">ttt</span><span class="params">()</span> -&gt;</span></span><br><span class="line">    Message = &lt;&lt;<span class="string">&quot;1&quot;</span>&gt;&gt;,</span><br><span class="line">    Sign1 = sign(Message, &#123;dir, <span class="string">&quot;d:/Downloads/x7mall_test&quot;</span>&#125;),</span><br><span class="line">    io:format(<span class="string">&quot;sign1:~p~n&quot;</span>, [Sign1]),</span><br><span class="line">    Verify1 = verify(Message, Sign1, &#123;dir, <span class="string">&quot;d:/Downloads/x7mall_test&quot;</span>&#125;),</span><br><span class="line">    io:format(<span class="string">&quot;verify1:~p~n&quot;</span>, [Verify1]),</span><br><span class="line"></span><br><span class="line">    Sign2 = sign(Message, <span class="string">&quot;d:/Downloads/x7mall_test_key&quot;</span>),</span><br><span class="line">    io:format(<span class="string">&quot;sign2:~p~n&quot;</span>, [Sign2]),</span><br><span class="line">    Verify2 = verify(Message, Sign2, <span class="string">&quot;d:/Downloads/x7mall_test_key.pub&quot;</span>),</span><br><span class="line">    io:format(<span class="string">&quot;verify2:~p~n&quot;</span>, [Verify2]),</span><br><span class="line"></span><br><span class="line">    Sign3 = sign(Message, &#123;dir, <span class="string">&quot;d:/Downloads/x7mall_test&quot;</span>&#125;),</span><br><span class="line">    io:format(<span class="string">&quot;sign3:~p~n&quot;</span>, [Sign3]),</span><br><span class="line">    Verify3 = verify(Message, Sign3, <span class="string">&quot;d:/Downloads/x7mall_test/ssh_host_rsa_key.pub&quot;</span>),</span><br><span class="line">    io:format(<span class="string">&quot;verify3:~p~n&quot;</span>, [Verify3]),</span><br><span class="line">    </span><br><span class="line">    Sign4 = sign(Message, <span class="string">&quot;d:/Downloads/x7mall_test/ssh_host_rsa_key&quot;</span>),</span><br><span class="line">    io:format(<span class="string">&quot;sign4:~p~n&quot;</span>, [Sign4]),</span><br><span class="line">    Verify4 = verify(Message, Sign4, &#123;dir, <span class="string">&quot;d:/Downloads/x7mall_test&quot;</span>&#125;),</span><br><span class="line">    io:format(<span class="string">&quot;verify4:~p~n&quot;</span>, [Verify4]),</span><br><span class="line"></span><br><span class="line">    Sign5 = sign(Message, <span class="string">&quot;d:/Downloads/x7mall_test/ssh_host_rsa_key&quot;</span>),</span><br><span class="line">    io:format(<span class="string">&quot;sign5:~p~n&quot;</span>, [Sign5]),</span><br><span class="line">    Verify5 = verify(Message, Sign5, <span class="string">&quot;d:/Downloads/x7mall_test/ssh_host_rsa_key.pub&quot;</span>),</span><br><span class="line">    io:format(<span class="string">&quot;verify5:~p~n&quot;</span>, [Verify5]),</span><br><span class="line">    ok.</span><br><span class="line"></span><br><span class="line"><span class="comment">%% 签名</span></span><br><span class="line"><span class="function"><span class="title">sign</span><span class="params">(Message, PrivateKeyFile)</span> -&gt;</span></span><br><span class="line">    PrivateKey = load_private_key(PrivateKeyFile),</span><br><span class="line">    Sign = public_key:sign(Message, sha256, PrivateKey),</span><br><span class="line">    base64:encode(Sign).</span><br><span class="line"></span><br><span class="line"><span class="comment">%% 验证</span></span><br><span class="line"><span class="function"><span class="title">verify</span><span class="params">(Message, Sign, PublicKeyFile)</span> -&gt;</span></span><br><span class="line">    Sign1 = base64:decode(Sign),</span><br><span class="line">    PublicKey = load_public_key(PublicKeyFile),</span><br><span class="line">    public_key:verify(Message, sha256, Sign1, PublicKey).</span><br><span class="line"></span><br><span class="line"><span class="comment">%% 加载private key</span></span><br><span class="line"><span class="function"><span class="title">load_private_key</span><span class="params">(&#123;file, File&#125;)</span> -&gt;</span></span><br><span class="line">    <span class="comment">%% private key格式1</span></span><br><span class="line">    <span class="comment">%% -----BEGIN PRIVATE KEY-----</span></span><br><span class="line">    <span class="comment">%% MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDDxRpuKIdYQ3lR</span></span><br><span class="line">    <span class="comment">%% ...</span></span><br><span class="line">    <span class="comment">%% mXCNDx5bSbbPL+WMY8c7F7K0krOfl8Vtzg5cCfo45+IsLCM16sDT0MhLCPUMWj0k</span></span><br><span class="line">    <span class="comment">%% cd4bKcAc3CENaL3U03oLE58r</span></span><br><span class="line">    <span class="comment">%% -----END PRIVATE KEY-----</span></span><br><span class="line">    <span class="comment">%% </span></span><br><span class="line">    <span class="comment">%% private key格式2</span></span><br><span class="line">    <span class="comment">%% MIIEvgI...0kcd4bKcAc3CENaL3U03oLE58r</span></span><br><span class="line">    <span class="comment">%% </span></span><br><span class="line">    &#123;ok, Data&#125; = file:read_file(File),</span><br><span class="line">    load_private_key(&#123;binary, Data&#125;);</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">load_private_key</span><span class="params">(&#123;binary, Data&#125;)</span> -&gt;</span></span><br><span class="line">    PrivateData = </span><br><span class="line">    <span class="keyword">case</span> re:run(Data, <span class="string">&quot;^-----BEGIN&quot;</span>) <span class="keyword">of</span></span><br><span class="line">        &#123;match, _&#125; -&gt; Data;</span><br><span class="line">        _ -&gt;</span><br><span class="line">            &lt;&lt;<span class="string">&quot;-----BEGIN PRIVATE KEY-----\n&quot;</span>, (format_data(Data))/binary, <span class="string">&quot;\n-----END PRIVATE KEY-----&quot;</span>&gt;&gt;</span><br><span class="line">    <span class="keyword">end</span>,</span><br><span class="line">    [PrivatePEMEntry | _] = public_key:pem_decode(PrivateData),</span><br><span class="line">    #&#x27;RSAPrivateKey&#x27;&#123;&#125; = PrivateKey = public_key:pem_entry_decode(PrivatePEMEntry),</span><br><span class="line">    PrivateKey;</span><br><span class="line"><span class="function"><span class="title">load_private_key</span><span class="params">(&#123;dir, Dir&#125;)</span> -&gt;</span></span><br><span class="line">    <span class="comment">%% 目录下文件名字:</span></span><br><span class="line">    <span class="comment">%% ssh_host_rsa_key</span></span><br><span class="line">    <span class="comment">%% ssh_host_rsa_key.pub</span></span><br><span class="line">    <span class="comment">%%</span></span><br><span class="line">    <span class="comment">%% private key格式</span></span><br><span class="line">    <span class="comment">%% -----BEGIN PRIVATE KEY-----</span></span><br><span class="line">    <span class="comment">%% MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDDxRpuKIdYQ3lR</span></span><br><span class="line">    <span class="comment">%% ...</span></span><br><span class="line">    <span class="comment">%% mXCNDx5bSbbPL+WMY8c7F7K0krOfl8Vtzg5cCfo45+IsLCM16sDT0MhLCPUMWj0k</span></span><br><span class="line">    <span class="comment">%% cd4bKcAc3CENaL3U03oLE58r</span></span><br><span class="line">    <span class="comment">%% -----END PRIVATE KEY-----</span></span><br><span class="line">    <span class="comment">%%</span></span><br><span class="line">    <span class="comment">%% public key格式</span></span><br><span class="line">    <span class="comment">%% ssh-rsa MIIEvgI...0kcd4bKcAc3CENaL3U03oLE58r</span></span><br><span class="line">    <span class="comment">%%</span></span><br><span class="line">    Algorithm = &#x27;ssh-rsa&#x27;,</span><br><span class="line">    Options = [&#123;system_dir, Dir&#125;],</span><br><span class="line">    &#123;ok, PrivateKey&#125; = ssh_file:host_key(Algorithm, Options),</span><br><span class="line">    PrivateKey;</span><br><span class="line"><span class="function"><span class="title">load_private_key</span><span class="params">(File)</span> -&gt;</span></span><br><span class="line">    <span class="keyword">case</span> filelib:is_dir(File) <span class="keyword">of</span></span><br><span class="line">        <span class="literal">true</span> -&gt; load_private_key(&#123;dir, File&#125;);</span><br><span class="line">        <span class="literal">false</span> -&gt; load_private_key(&#123;file, File&#125;)</span><br><span class="line">    <span class="keyword">end</span>.</span><br><span class="line"></span><br><span class="line"><span class="comment">%% 加载public key</span></span><br><span class="line"><span class="function"><span class="title">load_public_key</span><span class="params">(&#123;file, File&#125;)</span> -&gt;</span></span><br><span class="line">    <span class="comment">%% public key格式1</span></span><br><span class="line">    <span class="comment">%% -----BEGIN PUBLIC KEY-----</span></span><br><span class="line">    <span class="comment">%% MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw8UabiiHWEN5UR5SByS2</span></span><br><span class="line">    <span class="comment">%% ...</span></span><br><span class="line">    <span class="comment">%% oK5jmjNnFsCrWbkd68H6tsm9dGPcUMgNWxeahU/8tSOtX94AaTfU4cp846Yn7dH4</span></span><br><span class="line">    <span class="comment">%% JQIDAQAB</span></span><br><span class="line">    <span class="comment">%% -----END PUBLIC KEY-----</span></span><br><span class="line">    <span class="comment">%%</span></span><br><span class="line">    <span class="comment">%% public key格式2</span></span><br><span class="line">    <span class="comment">%% MIIBIjA...AaTfU4cp846Yn7dH4JQIDAQAB</span></span><br><span class="line">    <span class="comment">%%</span></span><br><span class="line">    &#123;ok, Data&#125; = file:read_file(File),</span><br><span class="line">    load_public_key(&#123;binary, Data&#125;);</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">load_public_key</span><span class="params">(&#123;binary, Data&#125;)</span> -&gt;</span></span><br><span class="line">    PublicData = </span><br><span class="line">    <span class="keyword">case</span> re:run(Data, <span class="string">&quot;^-----BEGIN&quot;</span>) <span class="keyword">of</span></span><br><span class="line">        &#123;match, _&#125; -&gt; Data;</span><br><span class="line">        _ -&gt;</span><br><span class="line">            NewData = </span><br><span class="line">            <span class="keyword">case</span> re:split(Data, <span class="string">&quot; &quot;</span>) <span class="keyword">of</span></span><br><span class="line">                [&lt;&lt;<span class="string">&quot;ssh-rsa&quot;</span>&gt;&gt;, Data1|_] -&gt; Data1;</span><br><span class="line">                _ -&gt; Data</span><br><span class="line">            <span class="keyword">end</span>,</span><br><span class="line">            &lt;&lt;<span class="string">&quot;-----BEGIN PUBLIC KEY-----\n&quot;</span>, (format_data(NewData))/binary, <span class="string">&quot;\n-----END PUBLIC KEY-----&quot;</span>&gt;&gt;</span><br><span class="line">    <span class="keyword">end</span>,</span><br><span class="line">    [PublicPEMEntry | _] = public_key:pem_decode(PublicData),</span><br><span class="line">    #&#x27;RSAPublicKey&#x27;&#123;&#125; = PublicKey = public_key:pem_entry_decode(PublicPEMEntry),</span><br><span class="line">    PublicKey;</span><br><span class="line"><span class="function"><span class="title">load_public_key</span><span class="params">(&#123;dir, Dir&#125;)</span> -&gt;</span></span><br><span class="line">    <span class="comment">%% 同 load_private_key(&#123;dir, Dir&#125;)</span></span><br><span class="line">    &#123;ok, PublicData&#125; = file:read_file(Dir ++ <span class="string">&quot;/ssh_host_rsa_key.pub&quot;</span>),</span><br><span class="line">    [&lt;&lt;<span class="string">&quot;ssh-rsa&quot;</span>&gt;&gt;, Data|_] = re:split(PublicData, <span class="string">&quot; &quot;</span>),</span><br><span class="line">    load_public_key(&#123;binary, Data&#125;);</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">load_public_key</span><span class="params">(File)</span> -&gt;</span></span><br><span class="line">    <span class="keyword">case</span> filelib:is_dir(File) <span class="keyword">of</span></span><br><span class="line">        <span class="literal">true</span> -&gt; load_public_key(&#123;dir, File&#125;);</span><br><span class="line">        <span class="literal">false</span> -&gt; load_public_key(&#123;file, File&#125;)</span><br><span class="line">    <span class="keyword">end</span>.</span><br><span class="line"></span><br><span class="line"><span class="comment">%% 其实不需要格式化也是ok的</span></span><br><span class="line"><span class="comment">%% 主要是为了debug时打印好看</span></span><br><span class="line"><span class="function"><span class="title">format_data</span><span class="params">(Data)</span> <span class="title">when</span> <span class="title">is_binary</span><span class="params">(Data)</span> -&gt;</span></span><br><span class="line">    List = erlang:binary_to_list(Data),</span><br><span class="line">    format_data(List);</span><br><span class="line"><span class="function"><span class="title">format_data</span><span class="params">(List)</span> <span class="title">when</span> <span class="title">is_list</span><span class="params">(List)</span> -&gt;</span></span><br><span class="line">    NewList = format_data(List, []),</span><br><span class="line">    NewList1 = lists:reverse(NewList),</span><br><span class="line">    NewList2 = string:join(NewList1, <span class="string">&quot;\n&quot;</span>),</span><br><span class="line">    Binary = erlang:list_to_binary(NewList2),</span><br><span class="line">    Binary.</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">format_data</span><span class="params">(List, NewList)</span> -&gt;</span></span><br><span class="line">    <span class="keyword">case</span> length(List) &gt; <span class="number">64</span> <span class="keyword">of</span></span><br><span class="line">        <span class="literal">true</span> -&gt;</span><br><span class="line">            &#123;List1, List2&#125; = lists:split(<span class="number">64</span>, List),</span><br><span class="line">            format_data(List2, [List1|NewList]);</span><br><span class="line">        <span class="literal">false</span> -&gt;</span><br><span class="line">            [List|NewList]</span><br><span class="line">    <span class="keyword">end</span>.</span><br></pre></td></tr></table></figure><h3 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h3><ol><li><a href="https://github.com/potatosalad/erlang-crypto_rsassa_pss">https://github.com/potatosalad/erlang-crypto_rsassa_pss</a></li><li><a href="https://elixirforum.com/t/verifying-web-crypto-signatures-in-erlang-elixir/20727">https://elixirforum.com/t/verifying-web-crypto-signatures-in-erlang-elixir/20727</a></li><li><a href="https://blog.csdn.net/huangshihaont/article/details/82849920">https://blog.csdn.net/huangshihaont/article/details/82849920</a></li></ol>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近需要erlang使用rsa实现签名验证&lt;br&gt;在网上搜了好久终于拼接成一份完整的代码&lt;/p&gt;</summary>
    
    
    
    <category term="erlang" scheme="https://www.mingilin.com/categories/erlang/"/>
    
    
    <category term="erlang" scheme="https://www.mingilin.com/tags/erlang/"/>
    
  </entry>
  
  <entry>
    <title>CENTOS下命令行播放音乐</title>
    <link href="https://www.mingilin.com/2021/12/28/centos/centos-aplay/"/>
    <id>https://www.mingilin.com/2021/12/28/centos/centos-aplay/</id>
    <published>2021-12-28T08:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.354Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>最近需要盘点公司的资产<br>部分centos主机关联不上具体的IP<br>又不方便关机</p><p>想到一个简单的方式：ssh远程后，播放音乐，用耳机听下</p><span id="more"></span><p>搜索了linux下的命令行播放器，发现大部分在centos6上没法使用yum安装</p><p>最后发现了<code>aplay</code>，自带的，只是听个声，够用了</p><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p><code>yum install alsa-utils -y</code><br>本来机器上已经有了，忽略</p><h2 id="显示设备列表"><a href="#显示设备列表" class="headerlink" title="显示设备列表"></a>显示设备列表</h2><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><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">[root@platform ~]# aplay -l</span><br><span class="line">**** List of PLAYBACK Hardware Devices ****</span><br><span class="line">card 0: MID [HDA Intel MID], device 3: HDMI 0 [HDMI 0]</span><br><span class="line">  Subdevices: 1/1</span><br><span class="line">  Subdevice #0: subdevice #0</span><br><span class="line">card 0: MID [HDA Intel MID], device 7: HDMI 1 [HDMI 1]</span><br><span class="line">  Subdevices: 1/1</span><br><span class="line">  Subdevice #0: subdevice #0</span><br><span class="line">card 0: MID [HDA Intel MID], device 8: HDMI 2 [HDMI 2]</span><br><span class="line">  Subdevices: 1/1</span><br><span class="line">  Subdevice #0: subdevice #0</span><br><span class="line">card 1: PCH [HDA Intel PCH], device 0: ALC887-VD Analog [ALC887-VD Analog]</span><br><span class="line">  Subdevices: 1/1</span><br><span class="line">  Subdevice #0: subdevice #0</span><br></pre></td></tr></table></figure><blockquote><p>显示有4个设备：<br>3个HDMI<br>1个ALC887-VD Analog，虽然名字不知道什么意思，但是很明显这个就是音频设备，Analog-模拟</p></blockquote><h2 id="播放"><a href="#播放" class="headerlink" title="播放"></a>播放</h2><p>找个歌曲，比如<a href="http://www.gov.cn/guoqing/2017-06/09/content_5200994.htm">国歌</a>，上传上去</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><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="meta prompt_">#</span><span class="language-bash"><span class="comment"># -D 指定设备</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 1 - card 1</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 0 - device 0</span></span></span><br><span class="line">[root@platform ~]# aplay -D hw:1,0 国歌.wav</span><br><span class="line">Playing WAVE &#x27;国歌.wav&#x27; : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># 卡在这儿表示正常播放了</span></span></span><br></pre></td></tr></table></figure><p>开始播放了，找个耳机去机器上听下，现在可以确定IP了，😄</p><h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h2><ol><li><a href="https://blog.csdn.net/wangji163163/article/details/51625961">https://blog.csdn.net/wangji163163/article/details/51625961</a></li></ol>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近需要盘点公司的资产&lt;br&gt;部分centos主机关联不上具体的IP&lt;br&gt;又不方便关机&lt;/p&gt;
&lt;p&gt;想到一个简单的方式：ssh远程后，播放音乐，用耳机听下&lt;/p&gt;</summary>
    
    
    
    <category term="centos" scheme="https://www.mingilin.com/categories/centos/"/>
    
    
    <category term="centos" scheme="https://www.mingilin.com/tags/centos/"/>
    
  </entry>
  
  <entry>
    <title>使用fpm打包</title>
    <link href="https://www.mingilin.com/2021/11/24/centos/centos-fpm/"/>
    <id>https://www.mingilin.com/2021/11/24/centos/centos-fpm/</id>
    <published>2021-11-24T02:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.356Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p><a href="https://github.com/jordansissel/fpm">fpm</a><br>The goal of fpm is to make it easy and quick to build packages such as rpms, debs, OSX packages, etc.</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><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">yum install ruby-devel gcc make rpm-build rubygems</span><br><span class="line">gem sources -a https://mirrors.aliyun.com/rubygems/</span><br><span class="line">gem sources --list</span><br><span class="line">gem install fpm</span><br><span class="line"></span><br><span class="line">fpm -p outdir -s dir -t rpm -n website --iteration 1.el6 -d aaa -d psmisc -v 1.0.1 -C ~/hello/</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># -p 输出目录</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># -d 依赖</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># -v 版本</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># -n name</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment"># -C 包目录,~/hello/ =&gt; /</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">#          ~/hello/usr/bin/hello =&gt; /usr/bin/hello</span></span> </span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;&#92;assets&#92;css&#92;APlayer.min.css&quot;&gt;&lt;script src=&quot;&#92;assets&#92;js&#92;APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="centos" scheme="https://www.mingilin.com/categories/centos/"/>
    
    
    <category term="centos" scheme="https://www.mingilin.com/tags/centos/"/>
    
  </entry>
  
  <entry>
    <title>ios15 修复websocket ssl连接失败的问题</title>
    <link href="https://www.mingilin.com/2021/09/29/erlang/erlang-ios15-wss/"/>
    <id>https://www.mingilin.com/2021/09/29/erlang/erlang-ios15-wss/</id>
    <published>2021-09-29T04:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.376Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>玩家反馈，ios15无法登录游戏，android和ios其他版本没有问题</p><p>分析发现，ios15将原本是一条数据内容分成三份发送</p><figure class="highlight plaintext"><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><br><span class="line">## FIN - Payload len</span><br><span class="line">websocket:request:53 [mfa:proc_lib:init_p/5] parse_frames:&#123;ssl,hybi,&lt;&lt;130,131&gt;&gt;,&#123;ssl,&#123;sslsocket,&#123;gen_tcp,#Port&lt;0.17851&gt;,tls_connection,&lt;0.533.0&gt;&#125;,&lt;0.6628.124&gt;&#125;&#125;&#125;</span><br><span class="line">## Masking-key</span><br><span class="line">websocket:request:53 [mfa:proc_lib:init_p/5] parse_frames:&#123;ssl,hybi,&lt;&lt;153,193,1,85&gt;&gt;,&#123;ssl,&#123;sslsocket,&#123;gen_tcp,#Port&lt;0.17851&gt;,tls_connection,&lt;0.533.0&gt;&#125;,&lt;0.6628.124&gt;&#125;&#125;&#125;</span><br><span class="line">## Payload Data</span><br><span class="line">websocket:request:53 [mfa:proc_lib:init_p/5] parse_frames:&#123;ssl,hybi,&lt;&lt;190,209,15&gt;&gt;,&#123;ssl,&#123;sslsocket,&#123;gen_tcp,#Port&lt;0.17851&gt;,tls_connection,&lt;0.533.0&gt;&#125;,&lt;0.6628.124&gt;&#125;&#125;&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>对应的协议格式：</p><figure class="highlight plaintext"><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"> 0                   1                   2                   3</span><br><span class="line"> 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1</span><br><span class="line">+-+-+-+-+-------+-+-------------+-------------------------------+</span><br><span class="line">|F|R|R|R| opcode|M| Payload len |    Extended payload length    |</span><br><span class="line">|I|S|S|S|  (4)  |A|     (7)     |             (16/63)           |</span><br><span class="line">|N|V|V|V|       |S|             |   (if payload len==126/127)   |</span><br><span class="line">| |1|2|3|       |K|             |                               |</span><br><span class="line">+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +</span><br><span class="line">|     Extended payload length continued, if payload len == 127  |</span><br><span class="line">+ - - - - - - - - - - - - - - - +-------------------------------+</span><br><span class="line">|                               |Masking-key, if MASK set to 1  |</span><br><span class="line">+-------------------------------+-------------------------------+</span><br><span class="line">| Masking-key (continued)       |          Payload Data         |</span><br><span class="line">+-------------------------------- - - - - - - - - - - - - - - - +</span><br><span class="line">:                     Payload Data continued ...                :</span><br><span class="line">+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +</span><br><span class="line">|                     Payload Data continued ...                |</span><br><span class="line">+---------------------------------------------------------------+</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>对于使用mochiweb的websocket只要增加</p><figure class="highlight plaintext"><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">parse_hybi_frames(_, &lt;&lt;&gt;&gt;, Acc) -&gt;</span><br><span class="line">    lists:reverse(Acc);</span><br><span class="line"></span><br><span class="line">......此处省略N行</span><br><span class="line"></span><br><span class="line">%% 数据不完整，继续收</span><br><span class="line">parse_hybi_frames(Socket, PartFrame, Acc) -&gt;</span><br><span class="line">    %%  io:format(&quot;3 ~p ~n&quot;,[&#123;_Fin,_Rsv,_Opcode,_Mask,_PayloadLen,_MaskKey&#125;]),</span><br><span class="line">    ok = mochiweb_socket:exit_if_closed(mochiweb_socket:setopts(Socket, [&#123;packet, 0&#125;, &#123;active, once&#125;])),</span><br><span class="line">    receive</span><br><span class="line">        &#123;tcp_closed, _&#125; -&gt;</span><br><span class="line">            mochiweb_socket:close(Socket),</span><br><span class="line">            exit(normal);</span><br><span class="line">        &#123;ssl_closed, _&#125; -&gt;</span><br><span class="line">            mochiweb_socket:close(Socket),</span><br><span class="line">            exit(normal);</span><br><span class="line">        &#123;tcp_error, _, _&#125; -&gt;</span><br><span class="line">            mochiweb_socket:close(Socket),</span><br><span class="line">            exit(normal);</span><br><span class="line">        &#123;Proto, _, Continuation&#125; when Proto =:= tcp orelse Proto =:= ssl -&gt;</span><br><span class="line">            parse_hybi_frames(Socket, &lt;&lt;PartFrame/binary, Continuation/binary&gt;&gt;,</span><br><span class="line">                Acc);</span><br><span class="line">        _ -&gt;</span><br><span class="line">            mochiweb_socket:close(Socket),</span><br><span class="line">            exit(normal)</span><br><span class="line">    after</span><br><span class="line">        5000 -&gt;</span><br><span class="line">            mochiweb_socket:close(Socket),</span><br><span class="line">            exit(normal)</span><br><span class="line">    end.</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>其他语言也差不多的逻辑，数据不全就继续等待数据了</p><h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h2><ol><li><a href="https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-10">https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-10</a></li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;&#92;assets&#92;css&#92;APlayer.min.css&quot;&gt;&lt;script src=&quot;&#92;assets&#92;js&#92;APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="erlang" scheme="https://www.mingilin.com/categories/erlang/"/>
    
    
    <category term="erlang" scheme="https://www.mingilin.com/tags/erlang/"/>
    
  </entry>
  
  <entry>
    <title>运行中的mongo减少内存占用</title>
    <link href="https://www.mingilin.com/2021/09/17/centos/centos-mongo-memory/"/>
    <id>https://www.mingilin.com/2021/09/17/centos/centos-mongo-memory/</id>
    <published>2021-09-17T09:17:07.000Z</published>
    <updated>2026-01-15T05:33:18.360Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>最近查看公司机器的内存占用情况，发现mongod大约占了50%的内存。<br>命令：<code>ps auxc|head -1;ps auxc|grep -v PID|sort -rn -k +4|head;</code><br>原来<code>内存默认使用的是(系统内存-1GB)*50%</code>（据说是3.4版本+）。</p><p>这也太坑了，服务器又不是专门用作DB的，还有其他进程也要吃内存。</p><p>运行中的mongod，也不敢restart，查询了可能的运行中清理内存。<br><font color=red>注意：没有在正式环境中执行过，仅作参考。</font></p><span id="more"></span><h3 id="方法1-这个应该可以"><a href="#方法1-这个应该可以" class="headerlink" title="方法1(这个应该可以)"></a>方法1(这个应该可以)</h3><p>关闭所有的数据库:<br><code>db.adminCommand(&#123;closeAllDatabases: 1&#125;)</code><br>或者<code>use admin; db.runCommand(&#123;closeAllDatabases: 1&#125;)</code></p><p>使用<code>crontab</code>定时执行<code>mongo --eval &quot;db.adminCommand(&#123;closeAllDatabases: 1&#125;)&quot;</code>?也许可以</p><blockquote><p>有新的数据进来的话,会重新开数据库的</p></blockquote><h3 id="方法2-没试过-不知道进程是否会重启"><a href="#方法2-没试过-不知道进程是否会重启" class="headerlink" title="方法2(没试过,不知道进程是否会重启)"></a>方法2(没试过,不知道进程是否会重启)</h3><p>要安装<code>cgroups</code>，正式环境中没有，没试过，不清楚进程会不会重启</p><ol><li><code>cgcreate -g memory:DBLimitedGroup</code> </li><li><code>echo 16G &gt; /sys/fs/cgroup/memory/DBLimitedGroup/memory.limit_in_bytes</code></li><li><code>sync; echo 3 &gt; /proc/sys/vm/drop_caches</code></li><li><code>cgclassify -g memory:DBLimitedGroup $(pidof mongod)</code></li></ol><h3 id="方法3-应该要重启的，没有试过"><a href="#方法3-应该要重启的，没有试过" class="headerlink" title="方法3(应该要重启的，没有试过)"></a>方法3(应该要重启的，没有试过)</h3><p><code>mongod.conf</code>增加<code>wiredTigerCacheSizeGB=8</code>，然后<code>mongod reload</code><br>或者<br><code>/usr/bin/mongod --config /etc/mongod.conf --fork --wiredTigerCacheSizeGB 8</code></p><h3 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h3><ol><li><a href="https://www.techpaste.com/2016/04/limit-mongodb-memory-usage/">https://www.techpaste.com/2016/04/limit-mongodb-memory-usage/</a></li><li><a href="https://www.cnblogs.com/On-my-way/p/9708225.html">https://www.cnblogs.com/On-my-way/p/9708225.html</a></li><li><a href="https://www.cnblogs.com/wt11/p/9291583.html">https://www.cnblogs.com/wt11/p/9291583.html</a></li><li><a href="https://stackoverflow.com/questions/6861184/is-there-any-option-to-limit-mongodb-memory-usage">https://stackoverflow.com/questions/6861184/is-there-any-option-to-limit-mongodb-memory-usage</a></li><li><a href="https://mongodb-documentation.readthedocs.io/en/latest/reference/command/listDatabases.html#gsc.tab=0">https://mongodb-documentation.readthedocs.io/en/latest/reference/command/listDatabases.html#gsc.tab=0</a></li><li><a href="https://segmentfault.com/q/1010000002953588">https://segmentfault.com/q/1010000002953588</a></li></ol>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近查看公司机器的内存占用情况，发现mongod大约占了50%的内存。&lt;br&gt;命令：&lt;code&gt;ps auxc|head -1;ps auxc|grep -v PID|sort -rn -k +4|head;&lt;/code&gt;&lt;br&gt;原来&lt;code&gt;内存默认使用的是(系统内存-1GB)*50%&lt;/code&gt;（据说是3.4版本+）。&lt;/p&gt;
&lt;p&gt;这也太坑了，服务器又不是专门用作DB的，还有其他进程也要吃内存。&lt;/p&gt;
&lt;p&gt;运行中的mongod，也不敢restart，查询了可能的运行中清理内存。&lt;br&gt;&lt;font color=red&gt;注意：没有在正式环境中执行过，仅作参考。&lt;/font&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="centos" scheme="https://www.mingilin.com/categories/centos/"/>
    
    <category term="mongo" scheme="https://www.mingilin.com/categories/centos/mongo/"/>
    
    
    <category term="centos" scheme="https://www.mingilin.com/tags/centos/"/>
    
    <category term="mongo" scheme="https://www.mingilin.com/tags/mongo/"/>
    
  </entry>
  
  <entry>
    <title>共享Android手机上的音视频到智能电视上</title>
    <link href="https://www.mingilin.com/2021/08/13/mobile/mobile-dlna-server/"/>
    <id>https://www.mingilin.com/2021/08/13/mobile/mobile-dlna-server/</id>
    <published>2021-08-13T06:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.385Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><h2 id="server端"><a href="#server端" class="headerlink" title="server端"></a><code>server端</code></h2><p>下载地址:</p><ul><li><a href="https://play.google.com/store/apps/details?id=com.al.dlnaserver">[fq]Google Play</a></li><li><a href="https://apkpure.com/cn/dlnaserver/com.al.dlnaserver">[fq]ApkPure</a></li><li><a href="/downloads/binary/DLNAServer_v2.14_apkpure.com.apk">本地下载</a></li></ul><p>安装到自己的手机上，然后点击右上角的+，添加需要共享的视频&#x2F;音频<br>确保可以后台运行</p><h2 id="client端"><a href="#client端" class="headerlink" title="client端"></a><code>client端</code></h2><p>下载<a href="https://www.videolan.org/vlc/download-android.html">VLC for Android</a><br>安装到<code>某盒子</code>或者<code>智能电视</code>上<br>确保<code>server端</code>和<code>client端</code>在同一个局域网中</p><p>打开VLC，稍等片刻就可以在<code>本地网络</code>中看到了<br>如果看不到的话,就<code>重启</code>下server端</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;&#92;assets&#92;css&#92;APlayer.min.css&quot;&gt;&lt;script src=&quot;&#92;assets&#92;js&#92;APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="手机" scheme="https://www.mingilin.com/categories/%E6%89%8B%E6%9C%BA/"/>
    
    
    <category term="手机" scheme="https://www.mingilin.com/tags/%E6%89%8B%E6%9C%BA/"/>
    
  </entry>
  
  <entry>
    <title>农历公历转换</title>
    <link href="https://www.mingilin.com/2021/08/09/other/other-lunar2solar/"/>
    <id>https://www.mingilin.com/2021/08/09/other/other-lunar2solar/</id>
    <published>2021-08-09T00:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.389Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p><strong>农历转公历是没有规律的，所以只能根据已有的数据转换</strong><br>香港天文台的数据：<a href="https://www.hko.gov.hk/tc/gts/time/conversion1_text.htm#">https://www.hko.gov.hk/tc/gts/time/conversion1_text.htm#</a></p><p>自己转换出了一个<code>lunar.db</code><a href="/downloads/binary/lunar.db">(点击下载)</a>，用<code>sqilte3</code>打开</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 prompt_">&gt;</span><span class="language-bash">sqlite3 lunar.db <span class="string">&quot;SELECT solar from lunar2solar where lunar=\&quot;2023-02-22\&quot;&quot;</span></span></span><br><span class="line">2023-03-13</span><br><span class="line">2023-04-12</span><br></pre></td></tr></table></figure><p>自己随便写了一个农历转公历的接口，其实就是从<code>lunar.db</code>中查询数据而已<br>很随意的，性能没法保证的<br><code>https://tools.web.mingilin.com/lunar2solar/lunar2solar.php?lunar=2023-02-22</code><br>日期格式必须是YYYY-MM-DD</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 --silent https://tools.web.mingilin.com/lunar2solar/lunar2solar.php?lunar=2023-02-22 | jq -r <span class="string">&#x27;.data | .[].solar&#x27;</span></span><br><span class="line">2023-03-13</span><br><span class="line">2023-04-12</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;&#92;assets&#92;css&#92;APlayer.min.css&quot;&gt;&lt;script src=&quot;&#92;assets&#92;js&#92;APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="other" scheme="https://www.mingilin.com/categories/other/"/>
    
    
    <category term="other" scheme="https://www.mingilin.com/tags/other/"/>
    
  </entry>
  
  <entry>
    <title>Win10下git clone ssh免密</title>
    <link href="https://www.mingilin.com/2021/08/08/windows/windows-git-clone-nopass/"/>
    <id>https://www.mingilin.com/2021/08/08/windows/windows-git-clone-nopass/</id>
    <published>2021-08-08T10:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.398Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><h2 id="git-for-windows"><a href="#git-for-windows" class="headerlink" title="git for windows"></a><code>git for windows</code></h2><ol><li>启动<code>ssh-agent</code>服务<ol><li><code>Win+s</code>搜索<code>服务</code>,以管理员身份运行</li><li>设置<code>OpenSSH Authentication Agent</code>为开机启动</li></ol></li><li><code>ssh-add</code>增加私钥<br>私钥放到<code>C:\Users\用户名</code>目录下,<code>ssh-add %USERPROFILE%\ssh_keys\id_rsa</code><br>可以创建一个开机启动.bat(<code>Win+R</code>-&gt;<code>shell:startup</code>)<figure class="highlight bat"><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="built_in">echo</span> 启动win10_ssh-agent</span><br><span class="line"><span class="built_in">echo</span> 环境变量增加GIT_SSH=C:\WINDOWS\System32\OpenSSH\ssh.exe</span><br><span class="line"><span class="function">C:\<span class="title">WINDOWS</span>\<span class="title">System32</span>\<span class="title">OpenSSH</span>\<span class="title">ssh</span>-<span class="title">agent.exe</span></span></span><br><span class="line"><span class="function"><span class="title">ssh</span>-<span class="title">add</span> %<span class="title">USERPROFILE</span>%\<span class="title">ssh_keys</span>\<span class="title">id_rsa</span></span></span><br><span class="line"><span class="function"><span class="title">ssh</span>-<span class="title">add</span> %<span class="title">USERPROFILE</span>%\<span class="title">ssh_keys</span>\<span class="title">id_rsa2</span></span></span><br></pre></td></tr></table></figure></li><li>修改git配置<ol><li><code>Win+s</code>搜索<code>编辑系统环境变量</code></li><li>增加系统环境变量<code>GIT_SSH=C:\WINDOWS\System32\OpenSSH\ssh.exe</code></li></ol></li><li>完成<br><code>git clone ssh://xxx</code>应该就可以正常工作了</li></ol><h2 id="TortoiseGIT"><a href="#TortoiseGIT" class="headerlink" title="TortoiseGIT"></a><code>TortoiseGIT</code></h2><ol><li>方法1:<ol><li>先设置好<code>git for windows</code></li><li>修改配置(<code>Settings</code> -&gt; <code>Network</code> -&gt; <code>SSH Client</code>)<br>修改为<code>C:\WINDOWS\System32\OpenSSH\ssh.exe</code></li></ol></li><li>方法2:<ol><li>启动<code>Pageant</code>，添加私钥.ppk</li><li>修改配置(<code>Settings</code> -&gt; <code>Network</code> -&gt; <code>SSH Client</code>)<br>修改为<code>Your\TortoiseGit\Path\bin\TortoisePlink.exe</code></li></ol></li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;&#92;assets&#92;css&#92;APlayer.min.css&quot;&gt;&lt;script src=&quot;&#92;assets&#92;js&#92;APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="windows" scheme="https://www.mingilin.com/categories/windows/"/>
    
    
    <category term="windows" scheme="https://www.mingilin.com/tags/windows/"/>
    
  </entry>
  
  <entry>
    <title>【转】DAVx5无法开启OpenTasks/Tasks.org权限的问题</title>
    <link href="https://www.mingilin.com/2021/07/30/other/other-davx5-sync/"/>
    <id>https://www.mingilin.com/2021/07/30/other/other-davx5-sync/</id>
    <published>2021-07-30T10:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.387Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><div class="tabs" id="tab"><ul class="nav-tabs"><li class="tab active"><a href="#tab-1">原文</a></li><li class="tab"><a href="#tab-2">附加</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tab-1"><blockquote><p>原文链接: <a href="https://blog.wanfajie.com/2021/02/566">https://blog.wanfajie.com/2021/02/566</a></p></blockquote><p>小米6手机（MIUI 11 20.1.16）中使用 DAVx5 显示缺少权限、无法同步 Tasks&#x2F;OpenTasks 中任务。并且在 “设置” -&gt; “应用权限” 中点击 “OpenTasks权限”&#x2F;“Tasks权限” 开关无法打开。查看 DAVx5 日志发现以下四项权限被禁止：</p><ul><li>org.dmfs.permission.READ_TASKS: denied</li><li>org.dmfs.permission.WRITE_TASKS: denied</li><li>org.tasks.permission.READ_TASKS: denied</li><li>org.tasks.permission.WRITE_TASKS: denied</li></ul><p>令人困惑的是，MIUI 既不给出授权提示，在权限管理中也找不到自定义应用权限授权的地方。对 MIUI 的“设置”地毯式搜索后，终于找到了解决方法。</p><ol><li>首先安装好 DAVx5 及 OpenTasks&#x2F;Tasks.org 应用。</li><li>在“全部参数”中点击5次“MIUI 版本”，开启开发者模式。</li><li>在“开发者选项”中，关闭位于最下面的几个选项中的“启用MIUI优化”。</li><li>回到桌面，长按 DAVx5 应用的图标，点击“应用信息”。<br>P.S.: 此时，应用信息界面变了个样子。如果是通过“设置”进入“应用信息”的话，界面将保持 MIUI 的原状。</li><li>然后，点击“应用信息”界面中的“权限”。进入“应用权限”界面后，你会在最下方看到“其他权限”选项。</li><li>进入“其他权限”，权限列表中将出现 “Tasks” 之类的权限，打开权限开关。<br>进入 DAVx5 的 “设置” -&gt; “应用权限”，此时就可以开启 “OpenTasks权限”&#x2F;“Tasks权限” 开关并正常同步 OpenTasks 中的数据。</li></ol><p>最后，建议再重新开启“启用MIUI优化”。关闭优化后，许多设置像是重置了一样，一来重新设置嫌麻烦，二来开启MIUI优化手机使用起来于我而言也没什么不足。网络上对MIUI优化众说纷纭，就看各位自行判断了。</p></div><div class="tab-pane" id="tab-2"><ol><li>在<code>Google Play</code>上<code>DAVx5</code>需要米，在<a href="https://f-droid.org/"><code>F-Droid</code></a>免费；</li><li>按照原文的方法，第一次重新“开启MIUI优化”后，<code>DAVx5</code>权限被重置了，<br>又重新关闭再开启，<code>DAVx5</code>可以用了，<br>可能成功与否要看人品；</li><li><code>Tasks.org</code>需要订购后才能使用<code>DAVx5</code>同步，没米，果断放弃，用<code>OpenTasks</code>；</li><li>使用<a href="https://radicale.org/3.0.html"><code>Radicale</code></a>自建<code>CalDAV</code>和<code>CardDAV</code>Server，真香，<br>如果配合docker就更香；</li><li>PC上用<code>Thunder Bird</code>+<code>TbSync</code>插件，管理日程和联系人；</li></ol></div></div></div>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;&#92;assets&#92;css&#92;APlayer.min.css&quot;&gt;&lt;script src=&quot;&#92;assets&#92;js&#92;APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="other" scheme="https://www.mingilin.com/categories/other/"/>
    
    
    <category term="other" scheme="https://www.mingilin.com/tags/other/"/>
    
  </entry>
  
  <entry>
    <title>Termux(Android)配置</title>
    <link href="https://www.mingilin.com/2021/07/29/centos/centos-termux/"/>
    <id>https://www.mingilin.com/2021/07/29/centos/centos-termux/</id>
    <published>2021-07-29T10:00:00.000Z</published>
    <updated>2026-01-15T05:33:18.367Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>最近要接手一些运维的工作<br>有时候需要远程更新下<br>对比了几个安卓的ssh客户端,发现<code>termux</code>最好用了(可以很方便的将迁移sessions)(<code>Termius</code>也挺好的)</p><span id="more"></span><h2 id="修改源"><a href="#修改源" class="headerlink" title="修改源"></a>修改源</h2><p><code>termux-change-repo</code></p><h2 id="根目录地址"><a href="#根目录地址" class="headerlink" title="根目录地址"></a>根目录地址</h2><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 prompt_">$ </span><span class="language-bash"><span class="built_in">echo</span> <span class="variable">$PREFIX</span></span></span><br><span class="line">/data/data/com.termux/files/usr</span><br></pre></td></tr></table></figure><h2 id="安装sshd服务"><a href="#安装sshd服务" class="headerlink" title="安装sshd服务"></a>安装<code>sshd</code>服务</h2><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><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">pkg install termux-services</span><br><span class="line">pkg install openssh</span><br><span class="line">sv-enable sshd</span><br><span class="line">sv start sshd</span><br></pre></td></tr></table></figure><p>默认端口 <code>8022</code><br>现在就可以用ssh登录了,用<code>sftp</code>发送文件了</p><h2 id="设置Termux软键盘"><a href="#设置Termux软键盘" class="headerlink" title="设置Termux软键盘"></a>设置Termux软键盘</h2><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><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="meta prompt_">#</span><span class="language-bash"><span class="comment"># ~/.termux/termux.properties</span></span></span><br><span class="line">extra-keys = [ \</span><br><span class="line"> [&#x27;|&#x27;, &#x27;~&#x27;, &#x27;/&#x27;, &#x27;.&#x27;, &#x27;-&#x27;, &#x27;_&#x27;, &#x27;ENTER&#x27;], \</span><br><span class="line"> [&#x27;ESC&#x27;, &#x27;TAB&#x27;, &#x27;HOME&#x27;,&#x27;UP&#x27;,&#x27;END&#x27;,&#x27;DEL&#x27;, &#x27;exit&#x27;], \</span><br><span class="line"> [&#x27;CTRL&#x27;,&#x27;ALT&#x27;,&#x27;LEFT&#x27;,&#x27;DOWN&#x27;,&#x27;RIGHT&#x27;, &#x27;BKSP&#x27;, &#x27;KEYBOARD&#x27;] \</span><br><span class="line">]</span><br></pre></td></tr></table></figure><h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><ul><li>grep 中文问题<br><a href="https://unix.stackexchange.com/questions/580139/termux-grep-fails-to-detect-chinese-character">相同问题的链接</a>, 解决方式:<code>pkg install busybox</code>, 使用<code>busybox grep</code></li></ul><h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h2><ol><li><a href="https://mirrors.tuna.tsinghua.edu.cn/help/termux/">https://mirrors.tuna.tsinghua.edu.cn/help/termux/</a></li><li><a href="https://wiki.termux.com/wiki/Termux-services">https://wiki.termux.com/wiki/Termux-services</a></li><li><a href="https://wiki.termux.com/wiki/Touch_Keyboard">https://wiki.termux.com/wiki/Touch_Keyboard</a></li></ol><h2 id="附带自动生成的远程登录的脚本"><a href="#附带自动生成的远程登录的脚本" class="headerlink" title="附带自动生成的远程登录的脚本"></a>附带自动生成的远程登录的脚本</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">!/bin/bash</span></span><br><span class="line">eval &quot;$(curl --silent https://www.mingilin.com/downloads/code/printcolor.sh)&quot;</span><br><span class="line">CACHE_DIR=~/.cache/</span><br><span class="line">mkdir -p $CACHE_DIR</span><br><span class="line">CFG_FILE=$&#123;CACHE_DIR&#125;/ssh_test_cfg.cfg</span><br><span class="line">if [ &quot;$(uname -o)&quot; == &quot;Android&quot; ];then</span><br><span class="line">    GREP=&quot;busybox grep&quot;</span><br><span class="line">else</span><br><span class="line">    GREP=grep</span><br><span class="line">fi</span><br><span class="line">MYSSH_KEY_DIR=~/myssh</span><br><span class="line">cat &gt; $CFG_FILE &lt;&lt;EOF</span><br><span class="line">&#123;&quot;id&quot;:&quot;7&quot;, &quot;group&quot;:[&quot;&quot;,&quot;0. 内网机器&quot;], &quot;name&quot;:&quot;DNS服务器-192.168.50.12&quot;, &quot;user&quot;:&quot;root&quot;, &quot;host&quot;:&quot;192.168.50.12&quot;, &quot;port&quot;:&quot;9022&quot;&#125;</span><br><span class="line">&#123;&quot;id&quot;:&quot;63&quot;, &quot;group&quot;:[&quot;&quot;,&quot;Z101. vagrant&quot;], &quot;name&quot;:&quot;192.168.56.10&quot;, &quot;user&quot;:&quot;root&quot;, &quot;host&quot;:&quot;192.168.56.10&quot;, &quot;port&quot;:&quot;22&quot;&#125;</span><br><span class="line">&#123;&quot;id&quot;:&quot;64&quot;, &quot;group&quot;:[&quot;&quot;,&quot;Z101. vagrant&quot;], &quot;name&quot;:&quot;192.168.56.11&quot;, &quot;user&quot;:&quot;root&quot;, &quot;host&quot;:&quot;192.168.56.11&quot;, &quot;port&quot;:&quot;22&quot;&#125;</span><br><span class="line">EOF</span><br><span class="line"></span><br><span class="line">function show_list() &#123;</span><br><span class="line">    filter=$1</span><br><span class="line">    group=&quot;&quot;</span><br><span class="line">    while read line_t; do</span><br><span class="line">        if [ &quot;$filter&quot; == &quot;&quot; ]; then</span><br><span class="line">            line=$line_t</span><br><span class="line">        else</span><br><span class="line">            line=$(echo $line_t | $&#123;GREP&#125; &quot;$filter&quot;)</span><br><span class="line">        fi</span><br><span class="line">        if [ &quot;$line&quot; == &quot;&quot; ]; then</span><br><span class="line">            continue</span><br><span class="line">        fi</span><br><span class="line">        group1=$(echo $line | jq &#x27;.group | join(&quot;&quot;)&#x27;)</span><br><span class="line">        port=$(echo $line | jq .port | sed &#x27;s/&quot;//g&#x27;)</span><br><span class="line">        if [ &quot;$port&quot; == &quot;0&quot; ]; then</span><br><span class="line">            continue</span><br><span class="line">        fi</span><br><span class="line">        if [ &quot;$group&quot; == &quot;$group1&quot; ]; then</span><br><span class="line">            echo -n &quot; &quot;</span><br><span class="line">            echo $line | jq &#x27;[.id,.name] | join(&quot; ===&gt; &quot;)&#x27; | sed &#x27;s/&quot;//g&#x27;</span><br><span class="line">        else</span><br><span class="line">            group=$group1</span><br><span class="line">            echo &quot;&quot;</span><br><span class="line">            print_info &quot;=======================================================&quot;</span><br><span class="line">            _print_info &quot;&gt;&gt;&gt; &quot;</span><br><span class="line">            print_info $(echo $line | jq -r &#x27;.group | .[1:] | join(&quot; &gt; &quot;)&#x27;)</span><br><span class="line">            print_info &quot;-------------------------------------------------------&quot;</span><br><span class="line">            echo -n &quot; &quot;</span><br><span class="line">            echo $line | jq -r &#x27;[.id,.name] | join(&quot; ===&gt; &quot;)&#x27;</span><br><span class="line">        fi</span><br><span class="line">    done &lt; $CFG_FILE</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function login() &#123;</span><br><span class="line">    id=$1</span><br><span class="line">    line=$(cat $CFG_FILE | $&#123;GREP&#125; &quot;\&quot;id\&quot;:\&quot;$id\&quot;&quot;)</span><br><span class="line">    sshhost=$(echo $line | jq -r .host)</span><br><span class="line">    sshport=$(echo $line | jq -r .port)</span><br><span class="line">    sshuser=$(echo $line | jq -r .user)</span><br><span class="line">    print_info &quot;===&gt; login $sshuser@$sshhost port:$sshport&quot;</span><br><span class="line">    ssh -o GSSAPIAuthentication=no -o StrictHostKeyChecking=no -p $sshport $sshuser@$sshhost</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function start_sshagent() &#123;</span><br><span class="line">    [ ! -d $MYSSH_KEY_DIR ] &amp;&amp; echo &quot;[error] not found dir: $MYSSH_KEY_DIR&quot; &amp;&amp; exit</span><br><span class="line"></span><br><span class="line">    eval $(ssh-agent)</span><br><span class="line">    for i in $(find $MYSSH_KEY_DIR -type f); do</span><br><span class="line">        ssh-add -q $i</span><br><span class="line">    done</span><br><span class="line">    ssh-add -l</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function stop_sshagent() &#123;</span><br><span class="line">    eval $(ssh-agent -k)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function help() &#123;</span><br><span class="line">    print_info &quot;=======================================&quot;</span><br><span class="line">    print_info &quot;show_list         - list all sessions  &quot;</span><br><span class="line">    print_info &quot;show_list group   - list group sessions&quot;</span><br><span class="line">    print_info &quot;login id          - login&quot;</span><br><span class="line">    print_info &quot;=======================================&quot;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">case $1 in</span><br><span class="line">    &quot;login&quot;)</span><br><span class="line">        start_sshagent</span><br><span class="line">        login $2</span><br><span class="line">        stop_sshagent</span><br><span class="line">        ;;</span><br><span class="line">    &quot;show_list&quot;)</span><br><span class="line">        show_list $2</span><br><span class="line">        ;;</span><br><span class="line">    *) </span><br><span class="line">        help</span><br><span class="line">        ;;</span><br><span class="line">esac</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近要接手一些运维的工作&lt;br&gt;有时候需要远程更新下&lt;br&gt;对比了几个安卓的ssh客户端,发现&lt;code&gt;termux&lt;/code&gt;最好用了(可以很方便的将迁移sessions)(&lt;code&gt;Termius&lt;/code&gt;也挺好的)&lt;/p&gt;</summary>
    
    
    
    <category term="termux" scheme="https://www.mingilin.com/categories/termux/"/>
    
    
    <category term="termux" scheme="https://www.mingilin.com/tags/termux/"/>
    
  </entry>
  
  <entry>
    <title>screen</title>
    <link href="https://www.mingilin.com/2021/07/04/centos/centos-screentool/"/>
    <id>https://www.mingilin.com/2021/07/04/centos/centos-screentool/</id>
    <published>2021-07-04T03:30:00.000Z</published>
    <updated>2026-01-15T05:33:18.365Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>个人经常使用的是<code>tmux</code>, 使用<code>tmuxinator</code>管理session</p><p>现在需要接手一些运维工作，但是默认安装的是<code>screen</code>，因此需要一些<code>screen</code>的知识</p><p>用惯了<code>tmuxinator</code>，也想使用类似的工具管理<code>screen</code>的session</p><blockquote><p>其实就是简单的生成不同的<code>screenrc</code>配置，使用<code>screen -c xxx.rc</code>调用不同的配置</p></blockquote><div class="tabs" id="tab"><ul class="nav-tabs"><li class="tab active"><a href="#tab-1">效果图</a></li><li class="tab"><a href="#tab-2">HELP</a></li><li class="tab"><a href="#tab-3">源码</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tab-1"><p><img src="/downloads/assets/screentool.png" alt="效果图"></p></div><div class="tab-pane" id="tab-2"><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><span class="line">$ screentool</span><br><span class="line"></span><br><span class="line">&gt;&gt;&gt;&gt;&gt; COMMAND &lt;&lt;&lt;&lt;&lt;</span><br><span class="line">new session      # create new session</span><br><span class="line">ls               # list all session</span><br><span class="line">edit session     # edit session config</span><br><span class="line">rm session       # remove session config</span><br><span class="line">start session    # start session</span><br><span class="line">stop session     # stop session</span><br><span class="line">status session   # status session</span><br><span class="line">install binname  # install screentool</span><br><span class="line">exec session cmd # exec &quot;cmd&quot;(use quotes)</span><br><span class="line">  cmd:</span><br><span class="line">    1. a command(ex. python)</span><br><span class="line">    2. -t python 10 python</span><br><span class="line"></span><br><span class="line">&gt;&gt;&gt;&gt;&gt; KEYBINDINGS &lt;&lt;&lt;&lt;&lt;</span><br><span class="line">+---------------+---------------------+</span><br><span class="line">| ctrl-a d      | detach              |</span><br><span class="line">| ctrl-a c      | 创建 window         |</span><br><span class="line">| ctrl-a k      | 关闭 window         |</span><br><span class="line">| ctrl-a A      | 重命名 windows      |</span><br><span class="line">| ctrl-a w      | 显示所有窗口        |</span><br><span class="line">|---------------+---------------------|</span><br><span class="line">| ctrl-a 0~9    | 切换窗口            |</span><br><span class="line">| ctrl-a ctrl-a | 快速切换窗口        |</span><br><span class="line">| ctrl-a Tab    | 切换到另一个(分屏)  |</span><br><span class="line">| ctrl-a p      | prev window         |</span><br><span class="line">| ctrl-a n      | next window         |</span><br><span class="line">|---------------+---------------------|</span><br><span class="line">| ctrl-a S      | 水平分屏            |</span><br><span class="line">| ctrl-a |      | 垂直分屏            |</span><br><span class="line">| ctrl-a Q      | 去除分屏            |</span><br><span class="line">|---------------+---------------------|</span><br><span class="line">| ctrl-a [      | copy                |</span><br><span class="line">|               | 空格是开始/结束选择 |</span><br><span class="line">| ctrl-a ]      | paste               |</span><br><span class="line">+---------------+---------------------+</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tab-3"><p>附带<a href="/downloads/code/screentool/myscreen"><code>源码</code></a></p></div></div></div>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;&#92;assets&#92;css&#92;APlayer.min.css&quot;&gt;&lt;script src=&quot;&#92;assets&#92;js&#92;APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="centos" scheme="https://www.mingilin.com/categories/centos/"/>
    
    <category term="linux" scheme="https://www.mingilin.com/categories/centos/linux/"/>
    
    
    <category term="screen" scheme="https://www.mingilin.com/tags/screen/"/>
    
  </entry>
  
  <entry>
    <title>推荐两个安卓下的桌面股票插件</title>
    <link href="https://www.mingilin.com/2020/12/04/other/other-deskstock-android/"/>
    <id>https://www.mingilin.com/2020/12/04/other/other-deskstock-android/</id>
    <published>2020-12-04T08:07:42.000Z</published>
    <updated>2026-01-15T05:33:18.387Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p><img src="/downloads/assets/deskstock.jpg" alt="效果图"></p><p>上面是：<a href="https://play.google.com/store/apps/details?id=top.ministock"><strong>桌面股票</strong></a><br>下面是：<a href="https://play.google.com/store/apps/details?id=com.virsir.android.smartstockcn"><strong>机灵股票</strong></a></p><p>插件是极好的，就是股票不赚钱😂<br>原来<code>股票精灵</code>挺好用的，现在已经废掉了😂</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;&#92;assets&#92;css&#92;APlayer.min.css&quot;&gt;&lt;script src=&quot;&#92;assets&#92;js&#92;APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="other" scheme="https://www.mingilin.com/categories/other/"/>
    
    
    <category term="other" scheme="https://www.mingilin.com/tags/other/"/>
    
  </entry>
  
  <entry>
    <title>自用的NGINX+MYSQL+PHP集成环境</title>
    <link href="https://www.mingilin.com/2020/12/04/other/other-mywnmp/"/>
    <id>https://www.mingilin.com/2020/12/04/other/other-mywnmp/</id>
    <published>2020-12-04T07:36:00.000Z</published>
    <updated>2026-01-15T05:33:18.390Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>分享一个自用的web集成环境<br>在其他人的基础上修改的，现在实在找不到是在哪个基础上修改的，抱歉<br>只要有点开发基础，就可以快速的自定义组件，目前包括：</p><ul><li>NGINX + PHP + MYSQL</li><li>MONGO</li><li>REDIS + MEMCACHED</li><li>XLIGHT(FTP SERVER)</li><li>OpenSSH-Win64</li></ul><p>链接: <a href="https://pan.baidu.com/s/1xi2MzcR6P7lNrQ3JItYXUQ">https://pan.baidu.com/s/1xi2MzcR6P7lNrQ3JItYXUQ</a> 提取码: w15d<br><img src="/downloads/assets/mywnmp_qrcode.jpg" alt="二维码"> </p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;&#92;assets&#92;css&#92;APlayer.min.css&quot;&gt;&lt;script src=&quot;&#92;assets&#92;js&#92;APlayer.min.js&quot; cla</summary>
      
    
    
    
    <category term="other" scheme="https://www.mingilin.com/categories/other/"/>
    
    
    <category term="other" scheme="https://www.mingilin.com/tags/other/"/>
    
  </entry>
  
  <entry>
    <title>ERLANG解决“证书出错，请登录微信支付商户平台下载证书”</title>
    <link href="https://www.mingilin.com/2020/12/04/erlang/erlang-wx-pay/"/>
    <id>https://www.mingilin.com/2020/12/04/erlang/erlang-wx-pay/</id>
    <published>2020-12-04T06:55:00.000Z</published>
    <updated>2026-01-15T05:33:18.381Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><h3 id="解决“证书出错，请登录微信支付商户平台下载证书”的核心代码"><a href="#解决“证书出错，请登录微信支付商户平台下载证书”的核心代码" class="headerlink" title="解决“证书出错，请登录微信支付商户平台下载证书”的核心代码"></a>解决“证书出错，请登录微信支付商户平台下载证书”的核心代码</h3><figure class="highlight erlang"><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="function"><span class="title">request_post</span><span class="params">(Url, Path, &#123;data, Str&#125;)</span> -&gt;</span></span><br><span class="line">    ReqUrl = lists:concat([Url, Path]),</span><br><span class="line">    <span class="comment">%% +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</span></span><br><span class="line">    <span class="comment">%% 😊这个是核心的核心😊</span></span><br><span class="line">    SSLOptions = [</span><br><span class="line">        &#123;keyfile,<span class="string">&quot;apiclient_key.pem&quot;</span>&#125;,</span><br><span class="line">        &#123;certfile,<span class="string">&quot;apiclient_cert.pem&quot;</span>&#125;</span><br><span class="line">    ],</span><br><span class="line">    HTTPOptions = [&#123;ssl, SSLOptions&#125;, &#123;timeout, <span class="number">5000</span>&#125;, &#123;version, <span class="string">&quot;HTTP/1.1&quot;</span>&#125;],</span><br><span class="line">    <span class="comment">%% +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</span></span><br><span class="line">    Request = &#123;ReqUrl, [], <span class="string">&quot;application/x-www-form-urlencoded&quot;</span>, iolist_to_binary(Str)&#125;,</span><br><span class="line">    httpc:request(post, Request, HTTPOptions, []).</span><br></pre></td></tr></table></figure><span id="more"></span><h3 id="使用xmerl解析xml"><a href="#使用xmerl解析xml" class="headerlink" title="使用xmerl解析xml"></a>使用<code>xmerl</code>解析xml</h3><figure class="highlight erlang"><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"><span class="function"><span class="title">scan_str</span><span class="params">(Str)</span> -&gt;</span></span><br><span class="line">    &#123;XmlElement, _Rest&#125; = xmerl_scan:string(Str, [&#123;space, normalize&#125;]),</span><br><span class="line">    [XmlElement1] = xmerl_lib:remove_whitespace([XmlElement]),</span><br><span class="line">    XmlElement1.</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">value_of</span><span class="params">(Key, #xmlElement&#123;&#125; = X)</span> -&gt;</span></span><br><span class="line">    <span class="keyword">case</span> xmerl_xs:select(Key, X) <span class="keyword">of</span></span><br><span class="line">        [#xmlElement&#123;&#125; = Find] -&gt;</span><br><span class="line">            de_cdata(xmerl_xs:value_of(Find));</span><br><span class="line">        [] -&gt;</span><br><span class="line">            []</span><br><span class="line">    <span class="keyword">end</span>.</span><br><span class="line"><span class="function"><span class="title">de_cdata</span><span class="params">(<span class="string">&quot;![CDATA[&quot;</span> ++ Data)</span> -&gt;</span></span><br><span class="line">    [_,_|Data1] = lists:reverse(Data),</span><br><span class="line">    unescape_str(lists:reverse(Data1));</span><br><span class="line"><span class="function"><span class="title">de_cdata</span><span class="params">(Data)</span> -&gt;</span></span><br><span class="line">    unescape_str(Data).</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">unescape_str</span><span class="params">(Str)</span> -&gt;</span></span><br><span class="line">    Str1 = unicode:characters_to_binary(Str),</span><br><span class="line">    GtEsc  = re:replace(Str1, <span class="string">&quot;&amp;amp;&quot;</span>, <span class="string">&quot;\\&amp;&quot;</span>, [global]),</span><br><span class="line">    LtEsc  = re:replace(GtEsc,  <span class="string">&quot;&amp;gt;&quot;</span>,  <span class="string">&quot;&gt;&quot;</span>,   [global]),</span><br><span class="line">    AmpEsc = re:replace(LtEsc,  <span class="string">&quot;&amp;lt;&quot;</span>,  <span class="string">&quot;&lt;&quot;</span>,   [global]),</span><br><span class="line">    Text   = re:replace(AmpEsc, <span class="string">&quot;&amp;amp;&quot;</span>, <span class="string">&quot;\\&amp;&quot;</span>, [global]),</span><br><span class="line">    util:to_list(Text).</span><br></pre></td></tr></table></figure><h3 id="将proplists转换为xml"><a href="#将proplists转换为xml" class="headerlink" title="将proplists转换为xml"></a>将<code>proplists</code>转换为xml</h3><figure class="highlight erlang"><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="title">export_xml</span><span class="params">(List)</span> -&gt;</span></span><br><span class="line">    Fields = lists:map(</span><br><span class="line">               <span class="keyword">fun</span>(&#123;Key, Value&#125;) -&gt;</span><br><span class="line">                       &#123;Key, [], [util:to_list(Value)]&#125;</span><br><span class="line">               <span class="keyword">end</span>, List),</span><br><span class="line">    Xml = xmerl:export_simple([&#123;xml, Fields&#125;], xmerl_xml, [&#123;prolog, <span class="string">&quot;&quot;</span>&#125;]),</span><br><span class="line">    Xml.</span><br></pre></td></tr></table></figure><h3 id="相对完整的逻辑代码"><a href="#相对完整的逻辑代码" class="headerlink" title="相对完整的逻辑代码"></a>相对完整的逻辑代码</h3><figure class="highlight erlang"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="title">notice_wx</span><span class="params">(UserName, PlayerId, Amount, OrderNum)</span> -&gt;</span></span><br><span class="line">    <span class="comment">%% 插入日志</span></span><br><span class="line">    insert_extract_log(OrderNum, Amount),</span><br><span class="line"></span><br><span class="line">    Url = <span class="string">&quot;https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers&quot;</span>,</span><br><span class="line"></span><br><span class="line">    MchAppId = <span class="string">&quot;wx1234567890&quot;</span>,</span><br><span class="line">    MchId = <span class="number">1234567890</span>,</span><br><span class="line">    Key = <span class="string">&quot;key1234567890&quot;</span>,</span><br><span class="line">    Desc = <span class="string">&quot;&quot;</span>,</span><br><span class="line">    <span class="comment">%% 生成随机字符串</span></span><br><span class="line">    RandStr = util:rand_str(<span class="number">16</span>, <span class="string">&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&quot;</span>),</span><br><span class="line">    DataT = [</span><br><span class="line">            &#123;mch_appid, MchAppId&#125;,</span><br><span class="line">            &#123;mchid, MchId&#125;,</span><br><span class="line">            &#123;device_info, config:server_id()&#125;,</span><br><span class="line">            &#123;nonce_str, RandStr&#125;,</span><br><span class="line">            &#123;partner_trade_no, OrderNum&#125;,</span><br><span class="line">            &#123;openid, UserName&#125;,</span><br><span class="line">            &#123;check_name, <span class="string">&quot;NO_CHECK&quot;</span>&#125;,</span><br><span class="line">            &#123;amount, Amount&#125;,</span><br><span class="line">            &#123;desc, Desc&#125;</span><br><span class="line">           ],</span><br><span class="line">    Data = lists:sort(DataT),</span><br><span class="line">    DataStrList = lists:map( </span><br><span class="line">                    <span class="keyword">fun</span>(&#123;K, V&#125;) -&gt;</span><br><span class="line">                            io_lib:format(<span class="string">&quot;~p=~s&quot;</span>, [K, util:to_list(V)])</span><br><span class="line">                    <span class="keyword">end</span>, Data),</span><br><span class="line">    DataStr1 = string:join(DataStrList, <span class="string">&quot;&amp;&quot;</span>),</span><br><span class="line">    DataStr = lists:concat([DataStr1, <span class="string">&quot;&amp;key=&quot;</span>, Key]),</span><br><span class="line">    Sign = util:md5(DataStr),</span><br><span class="line">    Data1 = [&#123;sign, util:to_upper(Sign)&#125;|Data],</span><br><span class="line">    Str = export_xml(Data1),</span><br><span class="line"></span><br><span class="line">    <span class="comment">%% POST请求</span></span><br><span class="line">    <span class="keyword">case</span> request_post(Url, <span class="string">&quot;&quot;</span>, &#123;data, Str&#125;) <span class="keyword">of</span></span><br><span class="line">        &#123;ok, &#123;&#123;_,<span class="number">200</span>,<span class="string">&quot;OK&quot;</span>&#125;, _, Content&#125;&#125; -&gt;</span><br><span class="line">            Xml = scan_str(Content),</span><br><span class="line">            Val = value_of(<span class="string">&quot;return_code&quot;</span>, Xml),</span><br><span class="line">            <span class="keyword">case</span> Val <span class="keyword">of</span></span><br><span class="line">                <span class="string">&quot;SUCCESS&quot;</span> -&gt; </span><br><span class="line">                    Code = value_of(<span class="string">&quot;result_code&quot;</span>, Xml),</span><br><span class="line">                    <span class="keyword">case</span> Code <span class="keyword">of</span></span><br><span class="line">                        <span class="string">&quot;SUCCESS&quot;</span> -&gt; </span><br><span class="line">                            WxPayNo = value_of(<span class="string">&quot;payment_no&quot;</span>, Xml),</span><br><span class="line">                            <span class="comment">%% 更新日志</span></span><br><span class="line">                            update_extract_log(OrderNum, WxPayNo, ?WX_REDBAT_EXTRACT_STATE_SUCC, <span class="string">&quot;&quot;</span>);</span><br><span class="line">                        <span class="string">&quot;FAIL&quot;</span> -&gt;</span><br><span class="line">                            ErrCode = value_of(<span class="string">&quot;err_code&quot;</span>, Xml),</span><br><span class="line">                            ErrCodeDesc = value_of(<span class="string">&quot;err_code_des&quot;</span>, Xml),</span><br><span class="line">                            <span class="comment">%% 更新日志</span></span><br><span class="line">                            update_extract_log(OrderNum, <span class="string">&quot;&quot;</span>, ErrCode, ErrCodeDesc)</span><br><span class="line">                    <span class="keyword">end</span>;</span><br><span class="line">                <span class="string">&quot;FAIL&quot;</span> -&gt;</span><br><span class="line">                    Msg = value_of(<span class="string">&quot;return_msg&quot;</span>, Xml),</span><br><span class="line">                    update_extract_log(OrderNum, <span class="string">&quot;&quot;</span>, <span class="string">&quot;FAIL&quot;</span>, Msg),</span><br><span class="line">                    ?ERROR_MSG(<span class="string">&quot;return_msg: ~ts&quot;</span>, [utf8_list_to_string(Msg)])</span><br><span class="line">            <span class="keyword">end</span>;</span><br><span class="line">        Ret -&gt;</span><br><span class="line">            ?ERROR_MSG(<span class="string">&quot;ret:~p&quot;</span>, [Ret])</span><br><span class="line">    <span class="keyword">end</span>.</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">request_post</span><span class="params">(Url, Path, &#123;data, Str&#125;)</span> -&gt;</span></span><br><span class="line">    ReqUrl = lists:concat([Url, Path]),</span><br><span class="line">    SSLOptions = [</span><br><span class="line">        &#123;keyfile,<span class="string">&quot;apiclient_key.pem&quot;</span>&#125;,</span><br><span class="line">        &#123;certfile,<span class="string">&quot;apiclient_cert.pem&quot;</span>&#125;</span><br><span class="line">    ],</span><br><span class="line">    HTTPOptions = [&#123;ssl, SSLOptions&#125;, &#123;timeout, <span class="number">5000</span>&#125;, &#123;version, <span class="string">&quot;HTTP/1.1&quot;</span>&#125;],</span><br><span class="line">    Request = &#123;ReqUrl, [], <span class="string">&quot;application/x-www-form-urlencoded&quot;</span>, iolist_to_binary(Str)&#125;,</span><br><span class="line">    httpc:request(post, Request, HTTPOptions, []).</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">scan_str</span><span class="params">(Str)</span> -&gt;</span></span><br><span class="line">    &#123;XmlElement, _Rest&#125; = xmerl_scan:string(Str, [&#123;space, normalize&#125;]),</span><br><span class="line">    [XmlElement1] = xmerl_lib:remove_whitespace([XmlElement]),</span><br><span class="line">    XmlElement1.</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">value_of</span><span class="params">(Key, #xmlElement&#123;&#125; = X)</span> -&gt;</span></span><br><span class="line">    <span class="keyword">case</span> xmerl_xs:select(Key, X) <span class="keyword">of</span></span><br><span class="line">        [#xmlElement&#123;&#125; = Find] -&gt;</span><br><span class="line">            de_cdata(xmerl_xs:value_of(Find));</span><br><span class="line">        [] -&gt;</span><br><span class="line">            []</span><br><span class="line">    <span class="keyword">end</span>.</span><br><span class="line"><span class="function"><span class="title">de_cdata</span><span class="params">(<span class="string">&quot;![CDATA[&quot;</span> ++ Data)</span> -&gt;</span></span><br><span class="line">    [_,_|Data1] = lists:reverse(Data),</span><br><span class="line">    unescape_str(lists:reverse(Data1));</span><br><span class="line"><span class="function"><span class="title">de_cdata</span><span class="params">(Data)</span> -&gt;</span></span><br><span class="line">    unescape_str(Data).</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">unescape_str</span><span class="params">(Str)</span> -&gt;</span></span><br><span class="line">    Str1 = unicode:characters_to_binary(Str),</span><br><span class="line">    GtEsc  = re:replace(Str1, <span class="string">&quot;&amp;amp;&quot;</span>, <span class="string">&quot;\\&amp;&quot;</span>, [global]),</span><br><span class="line">    LtEsc  = re:replace(GtEsc,  <span class="string">&quot;&amp;gt;&quot;</span>,  <span class="string">&quot;&gt;&quot;</span>,   [global]),</span><br><span class="line">    AmpEsc = re:replace(LtEsc,  <span class="string">&quot;&amp;lt;&quot;</span>,  <span class="string">&quot;&lt;&quot;</span>,   [global]),</span><br><span class="line">    Text   = re:replace(AmpEsc, <span class="string">&quot;&amp;amp;&quot;</span>, <span class="string">&quot;\\&amp;&quot;</span>, [global]),</span><br><span class="line">    util:to_list(Text).</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">export_xml</span><span class="params">(List)</span> -&gt;</span></span><br><span class="line">    Fields = lists:map(</span><br><span class="line">               <span class="keyword">fun</span>(&#123;Key, Value&#125;) -&gt;</span><br><span class="line">                       &#123;Key, [], [util:to_list(Value)]&#125;</span><br><span class="line">               <span class="keyword">end</span>, List),</span><br><span class="line">    Xml = xmerl:export_simple([&#123;xml, Fields&#125;], xmerl_xml, [&#123;prolog, <span class="string">&quot;&quot;</span>&#125;]),</span><br><span class="line">    Xml.</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">utf8_list_to_string</span><span class="params">(List)</span> -&gt;</span></span><br><span class="line">    unicode:characters_to_list(list_to_binary(List)).</span><br></pre></td></tr></table></figure><h3 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h3><ol><li><a href="https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2">https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter&#x3D;14_2</a></li></ol>]]></content>
    
    
    <summary type="html">&lt;h3 id=&quot;解决“证书出错，请登录微信支付商户平台下载证书”的核心代码&quot;&gt;&lt;a href=&quot;#解决“证书出错，请登录微信支付商户平台下载证书”的核心代码&quot; class=&quot;headerlink&quot; title=&quot;解决“证书出错，请登录微信支付商户平台下载证书”的核心代码&quot;&gt;&lt;/a&gt;解决“证书出错，请登录微信支付商户平台下载证书”的核心代码&lt;/h3&gt;&lt;figure class=&quot;highlight erlang&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;title&quot;&gt;request_post&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(Url, Path, &amp;#123;data, Str&amp;#125;)&lt;/span&gt; -&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ReqUrl = lists:concat([Url, Path]),&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;%% +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;%% 😊这个是核心的核心😊&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    SSLOptions = [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#123;keyfile,&lt;span class=&quot;string&quot;&gt;&amp;quot;apiclient_key.pem&amp;quot;&lt;/span&gt;&amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#123;certfile,&lt;span class=&quot;string&quot;&gt;&amp;quot;apiclient_cert.pem&amp;quot;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ],&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    HTTPOptions = [&amp;#123;ssl, SSLOptions&amp;#125;, &amp;#123;timeout, &lt;span class=&quot;number&quot;&gt;5000&lt;/span&gt;&amp;#125;, &amp;#123;version, &lt;span class=&quot;string&quot;&gt;&amp;quot;HTTP/1.1&amp;quot;&lt;/span&gt;&amp;#125;],&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;%% +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    Request = &amp;#123;ReqUrl, [], &lt;span class=&quot;string&quot;&gt;&amp;quot;application/x-www-form-urlencoded&amp;quot;&lt;/span&gt;, iolist_to_binary(Str)&amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    httpc:request(post, Request, HTTPOptions, []).&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;</summary>
    
    
    
    <category term="erlang" scheme="https://www.mingilin.com/categories/erlang/"/>
    
    
    <category term="erlang" scheme="https://www.mingilin.com/tags/erlang/"/>
    
  </entry>
  
</feed>
