<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>iFan</title>
  
  
  <link href="https://blog.ifan.host/atom.xml" rel="self"/>
  
  <link href="https://blog.ifan.host/"/>
  <updated>2024-10-10T06:12:41.745Z</updated>
  <id>https://blog.ifan.host/</id>
  
  <author>
    <name>iFan</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Sqlalchemy Upsert</title>
    <link href="https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-upsery/"/>
    <id>https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-upsery/</id>
    <published>2024-10-01T01:00:00.000Z</published>
    <updated>2024-10-10T06:12:41.745Z</updated>
    
    <content type="html"><![CDATA[<h2 id="实现不存在则插入"><a href="#实现不存在则插入" class="headerlink" title="实现不存在则插入"></a>实现不存在则插入</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">upsert</span>(<span class="params">table, insert_data: <span class="built_in">dict</span>, update_data: <span class="built_in">dict</span></span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    插入或者更新</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br><span class="line">    insert_stmt = insert(table).values(**insert_data)</span><br><span class="line">    on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(**update_data)</span><br><span class="line">    <span class="keyword">with</span> db.engine.connect() <span class="keyword">as</span> connect:</span><br><span class="line">        connect.execute(on_duplicate_key_stmt)</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">ignore_insert</span>(<span class="params">table, data: <span class="built_in">dict</span></span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    忽略重复插入</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br><span class="line">    insert_command = table.__table__.insert().prefix_with(<span class="string">&#x27; IGNORE&#x27;</span>).values(data)</span><br><span class="line">    <span class="keyword">with</span> db.engine.connect() <span class="keyword">as</span> connect:</span><br><span class="line">        connect.execute(insert_command)</span><br><span class="line">        connect.commit()</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;实现不存在则插入&quot;&gt;&lt;a href=&quot;#实现不存在则插入&quot; class=&quot;headerlink&quot; title=&quot;实现不存在则插入&quot;&gt;&lt;/a&gt;实现不存在则插入&lt;/h2&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td c</summary>
      
    
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/categories/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/categories/Sqlalchemy/ORM/"/>
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/tags/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/tags/ORM/"/>
    
  </entry>
  
  <entry>
    <title>Sqlalchemy 绑定多个数据库</title>
    <link href="https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-bind-many-db/"/>
    <id>https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-bind-many-db/</id>
    <published>2024-10-01T01:00:00.000Z</published>
    <updated>2024-10-10T06:13:20.518Z</updated>
    
    <content type="html"><![CDATA[<h2 id="绑定多个数据库"><a href="#绑定多个数据库" class="headerlink" title="绑定多个数据库"></a>绑定多个数据库</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">SQLALCHEMY_DATABASE_URI = <span class="string">&#x27;postgres://localhost/main&#x27;</span></span><br><span class="line">SQLALCHEMY_BINDS = &#123;</span><br><span class="line">    <span class="string">&#x27;users&#x27;</span>:        <span class="string">&#x27;mysqldb://localhost/users&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;appmeta&#x27;</span>:      <span class="string">&#x27;sqlite:////path/to/appmeta.db&#x27;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>创建和删除表</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">db.create_all()</span><br><span class="line">db.create_all(bind=[<span class="string">&#x27;users&#x27;</span>])</span><br><span class="line">db.create_all(bind=<span class="string">&#x27;appmeta&#x27;</span>)</span><br><span class="line">db.drop_all(bind=<span class="literal">None</span>)</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;绑定多个数据库&quot;&gt;&lt;a href=&quot;#绑定多个数据库&quot; class=&quot;headerlink&quot; title=&quot;绑定多个数据库&quot;&gt;&lt;/a&gt;绑定多个数据库&lt;/h2&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class</summary>
      
    
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/categories/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/categories/Sqlalchemy/ORM/"/>
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/tags/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/tags/ORM/"/>
    
  </entry>
  
  <entry>
    <title>Sqlalchemy 批量插入数据</title>
    <link href="https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-batch-data/"/>
    <id>https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-batch-data/</id>
    <published>2024-10-01T01:00:00.000Z</published>
    <updated>2024-10-10T06:14:23.708Z</updated>
    
    <content type="html"><![CDATA[<h2 id="批量插入数据测试"><a href="#批量插入数据测试" class="headerlink" title="批量插入数据测试"></a>批量插入数据测试</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> sqlite3</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> sqlalchemy.ext.declarative <span class="keyword">import</span> declarative_base</span><br><span class="line"><span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> Column, Integer, String,  create_engine</span><br><span class="line"><span class="keyword">from</span> sqlalchemy.orm <span class="keyword">import</span> scoped_session, sessionmaker</span><br><span class="line"></span><br><span class="line">Base = declarative_base()</span><br><span class="line">DBSession = scoped_session(sessionmaker())</span><br><span class="line">engine = <span class="literal">None</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Customer</span>(<span class="title class_ inherited__">Base</span>):</span><br><span class="line">    __tablename__ = <span class="string">&quot;customer&quot;</span></span><br><span class="line">    <span class="built_in">id</span> = Column(Integer, primary_key=<span class="literal">True</span>)</span><br><span class="line">    name = Column(String(<span class="number">255</span>))</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">init_sqlalchemy</span>(<span class="params">dbname=<span class="string">&#x27;sqlite:///sqlalchemy.db&#x27;</span></span>):</span><br><span class="line">    <span class="keyword">global</span> engine</span><br><span class="line">    engine = create_engine(dbname, echo=<span class="literal">False</span>)</span><br><span class="line">    DBSession.remove()</span><br><span class="line">    DBSession.configure(bind=engine, autoflush=<span class="literal">False</span>, expire_on_commit=<span class="literal">False</span>)</span><br><span class="line">    Base.metadata.drop_all(engine)</span><br><span class="line">    Base.metadata.create_all(engine)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_sqlalchemy_orm</span>(<span class="params">n=<span class="number">100000</span></span>):</span><br><span class="line">    init_sqlalchemy()</span><br><span class="line">    t0 = time.time()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n):</span><br><span class="line">        customer = Customer()</span><br><span class="line">        customer.name = <span class="string">&#x27;NAME &#x27;</span> + <span class="built_in">str</span>(i)</span><br><span class="line">        DBSession.add(customer)</span><br><span class="line">        <span class="keyword">if</span> i % <span class="number">1000</span> == <span class="number">0</span>:</span><br><span class="line">            DBSession.flush()</span><br><span class="line">    DBSession.commit()</span><br><span class="line">    <span class="built_in">print</span>(</span><br><span class="line">        <span class="string">&quot;SQLAlchemy ORM: Total time for &quot;</span> + <span class="built_in">str</span>(n) +</span><br><span class="line">        <span class="string">&quot; records &quot;</span> + <span class="built_in">str</span>(time.time() - t0) + <span class="string">&quot; secs&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_sqlalchemy_orm_pk_given</span>(<span class="params">n=<span class="number">100000</span></span>):</span><br><span class="line">    init_sqlalchemy()</span><br><span class="line">    t0 = time.time()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n):</span><br><span class="line">        customer = Customer(<span class="built_in">id</span>=i+<span class="number">1</span>, name=<span class="string">&quot;NAME &quot;</span> + <span class="built_in">str</span>(i))</span><br><span class="line">        DBSession.add(customer)</span><br><span class="line">        <span class="keyword">if</span> i % <span class="number">1000</span> == <span class="number">0</span>:</span><br><span class="line">            DBSession.flush()</span><br><span class="line">    DBSession.commit()</span><br><span class="line">    <span class="built_in">print</span>(</span><br><span class="line">        <span class="string">&quot;SQLAlchemy ORM pk given: Total time for &quot;</span> + <span class="built_in">str</span>(n) +</span><br><span class="line">        <span class="string">&quot; records &quot;</span> + <span class="built_in">str</span>(time.time() - t0) + <span class="string">&quot; secs&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_sqlalchemy_orm_bulk_insert</span>(<span class="params">n=<span class="number">100000</span></span>):</span><br><span class="line">    init_sqlalchemy()</span><br><span class="line">    t0 = time.time()</span><br><span class="line">    n1 = n</span><br><span class="line">    <span class="keyword">while</span> n1 &gt; <span class="number">0</span>:</span><br><span class="line">        n1 = n1 - <span class="number">10000</span></span><br><span class="line">        DBSession.bulk_insert_mappings(</span><br><span class="line">            Customer,</span><br><span class="line">            [</span><br><span class="line">                <span class="built_in">dict</span>(name=<span class="string">&quot;NAME &quot;</span> + <span class="built_in">str</span>(i))</span><br><span class="line">                <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">min</span>(<span class="number">10000</span>, n1))</span><br><span class="line">            ]</span><br><span class="line">        )</span><br><span class="line">    DBSession.commit()</span><br><span class="line">    <span class="built_in">print</span>(</span><br><span class="line">        <span class="string">&quot;SQLAlchemy ORM bulk_save_objects(): Total time for &quot;</span> + <span class="built_in">str</span>(n) +</span><br><span class="line">        <span class="string">&quot; records &quot;</span> + <span class="built_in">str</span>(time.time() - t0) + <span class="string">&quot; secs&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_sqlalchemy_core</span>(<span class="params">n=<span class="number">100000</span></span>):</span><br><span class="line">    init_sqlalchemy()</span><br><span class="line">    t0 = time.time()</span><br><span class="line">    engine.execute(</span><br><span class="line">        Customer.__table__.insert(),</span><br><span class="line">        [&#123;<span class="string">&quot;name&quot;</span>: <span class="string">&#x27;NAME &#x27;</span> + <span class="built_in">str</span>(i)&#125; <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n)]</span><br><span class="line">    )</span><br><span class="line">    <span class="built_in">print</span>(</span><br><span class="line">        <span class="string">&quot;SQLAlchemy Core: Total time for &quot;</span> + <span class="built_in">str</span>(n) +</span><br><span class="line">        <span class="string">&quot; records &quot;</span> + <span class="built_in">str</span>(time.time() - t0) + <span class="string">&quot; secs&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_sqlalchemy_add_all</span>(<span class="params">n=<span class="number">100000</span></span>):</span><br><span class="line">    init_sqlalchemy()</span><br><span class="line">    t0 = time.time()</span><br><span class="line">    objs = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n):</span><br><span class="line">        objs.append(Customer(<span class="built_in">id</span> = i, name = <span class="string">&quot;name&quot;</span> + <span class="built_in">str</span>(i)))</span><br><span class="line">    DBSession.add_all(objs)</span><br><span class="line">    DBSession.commit()</span><br><span class="line">    <span class="built_in">print</span>(</span><br><span class="line">        <span class="string">&quot;SQLAlchemy all_all: Total time for &quot;</span> + <span class="built_in">str</span>(n) +</span><br><span class="line">        <span class="string">&quot; records &quot;</span> + <span class="built_in">str</span>(time.time() - t0) + <span class="string">&quot; secs&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">init_sqlite3</span>(<span class="params">dbname</span>):</span><br><span class="line">    conn = sqlite3.connect(dbname)</span><br><span class="line">    c = conn.cursor()</span><br><span class="line">    c.execute(<span class="string">&quot;DROP TABLE IF EXISTS customer&quot;</span>)</span><br><span class="line">    c.execute(</span><br><span class="line">        <span class="string">&quot;CREATE TABLE customer (id INTEGER NOT NULL, &quot;</span></span><br><span class="line">        <span class="string">&quot;name VARCHAR(255), PRIMARY KEY(id))&quot;</span>)</span><br><span class="line">    conn.commit()</span><br><span class="line">    <span class="keyword">return</span> conn</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_sqlite3</span>(<span class="params">n=<span class="number">100000</span>, dbname=<span class="string">&#x27;sqlite3.db&#x27;</span></span>):</span><br><span class="line">    conn = init_sqlite3(dbname)</span><br><span class="line">    c = conn.cursor()</span><br><span class="line">    t0 = time.time()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(n):</span><br><span class="line">        row = (<span class="string">&#x27;NAME &#x27;</span> + <span class="built_in">str</span>(i),)</span><br><span class="line">        c.execute(<span class="string">&quot;INSERT INTO customer (name) VALUES (?)&quot;</span>, row)</span><br><span class="line">    conn.commit()</span><br><span class="line">    <span class="built_in">print</span>(</span><br><span class="line">        <span class="string">&quot;sqlite3: Total time for &quot;</span> + <span class="built_in">str</span>(n) +</span><br><span class="line">        <span class="string">&quot; records &quot;</span> + <span class="built_in">str</span>(time.time() - t0) + <span class="string">&quot; sec&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    test_sqlalchemy_orm(<span class="number">100000</span>)</span><br><span class="line">    test_sqlalchemy_orm_pk_given(<span class="number">100000</span>)</span><br><span class="line">    test_sqlalchemy_orm_bulk_insert(<span class="number">100000</span>)</span><br><span class="line">    test_sqlalchemy_add_all(<span class="number">100000</span>)</span><br><span class="line">    test_sqlalchemy_core(<span class="number">100000</span>)</span><br><span class="line">    test_sqlite3(<span class="number">100000</span>)</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;批量插入数据测试&quot;&gt;&lt;a href=&quot;#批量插入数据测试&quot; class=&quot;headerlink&quot; title=&quot;批量插入数据测试&quot;&gt;&lt;/a&gt;批量插入数据测试&lt;/h2&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td c</summary>
      
    
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/categories/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/categories/Sqlalchemy/ORM/"/>
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/tags/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/tags/ORM/"/>
    
  </entry>
  
  <entry>
    <title>Sqlalchemy 打印建表语句</title>
    <link href="https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-echo-create-table-sql/"/>
    <id>https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-echo-create-table-sql/</id>
    <published>2024-10-01T01:00:00.000Z</published>
    <updated>2024-10-10T06:15:09.222Z</updated>
    
    <content type="html"><![CDATA[<figure class="highlight python"><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="keyword">from</span> sqlalchemy.schema <span class="keyword">import</span> CreateTable</span><br><span class="line"><span class="built_in">print</span>( CreateTable(Model.__table__ ) )</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;figure class=&quot;highlight python&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;/pre&gt;&lt;/td</summary>
      
    
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/categories/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/categories/Sqlalchemy/ORM/"/>
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/tags/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/tags/ORM/"/>
    
  </entry>
  
  <entry>
    <title>Sqlalchemy 关联查询</title>
    <link href="https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-join/"/>
    <id>https://blog.ifan.host/2024/10/01/language/python/libs/sqlalchemy/sqlalchemy-join/</id>
    <published>2024-10-01T01:00:00.000Z</published>
    <updated>2024-10-10T07:16:37.026Z</updated>
    
    <content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> create_engine</span><br><span class="line"><span class="keyword">from</span> sqlalchemy.orm <span class="keyword">import</span> sessionmaker</span><br><span class="line"><span class="keyword">from</span> sqlalchemy.ext.declarative <span class="keyword">import</span> declarative_base</span><br><span class="line"><span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> Column, Integer, String</span><br><span class="line"><span class="keyword">from</span> sqlalchemy.orm <span class="keyword">import</span> relationship</span><br><span class="line"></span><br><span class="line"><span class="comment"># Create the database engine and session</span></span><br><span class="line">engine = create_engine(<span class="string">&#x27;sqlite:///join_demo.db&#x27;</span>)</span><br><span class="line">Session = sessionmaker(bind=engine)</span><br><span class="line">session = Session()</span><br><span class="line"></span><br><span class="line"><span class="comment"># Create the base model</span></span><br><span class="line">Base = declarative_base()</span><br><span class="line"></span><br><span class="line"><span class="comment"># Define the table models</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Table1</span>(<span class="title class_ inherited__">Base</span>):</span><br><span class="line">    __tablename__ = <span class="string">&#x27;table1&#x27;</span></span><br><span class="line">    <span class="built_in">id</span> = Column(Integer, primary_key=<span class="literal">True</span>)</span><br><span class="line">    name = Column(String)</span><br><span class="line">    table2_rows = relationship(<span class="string">&quot;Table2&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Table2</span>(<span class="title class_ inherited__">Base</span>):</span><br><span class="line">    __tablename__ = <span class="string">&#x27;table2&#x27;</span></span><br><span class="line">    <span class="built_in">id</span> = Column(Integer, primary_key=<span class="literal">True</span>)</span><br><span class="line">    table1_id = Column(Integer, ForeignKey(<span class="string">&#x27;table1.id&#x27;</span>))</span><br><span class="line">    name = Column(String)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Create the tables</span></span><br><span class="line">Base.metadata.create_all(engine)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Insert sample data</span></span><br><span class="line">table1_data = [</span><br><span class="line">    Table1(<span class="built_in">id</span>=<span class="number">1</span>, name=<span class="string">&#x27;Table1 Row 1&#x27;</span>),</span><br><span class="line">    Table1(<span class="built_in">id</span>=<span class="number">2</span>, name=<span class="string">&#x27;Table1 Row 2&#x27;</span>),</span><br><span class="line">    Table1(<span class="built_in">id</span>=<span class="number">3</span>, name=<span class="string">&#x27;Table1 Row 3&#x27;</span>)</span><br><span class="line">]</span><br><span class="line">session.bulk_save_objects(table1_data)</span><br><span class="line"></span><br><span class="line">table2_data = [</span><br><span class="line">    Table2(<span class="built_in">id</span>=<span class="number">1</span>, table1_id=<span class="number">1</span>, name=<span class="string">&#x27;Table2 Row 1&#x27;</span>),</span><br><span class="line">    Table2(<span class="built_in">id</span>=<span class="number">2</span>, table1_id=<span class="number">3</span>, name=<span class="string">&#x27;Table2 Row 2&#x27;</span>)</span><br><span class="line">]</span><br><span class="line">session.bulk_save_objects(table2_data)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 1. Inner Join</span></span><br><span class="line">inner_join_query = session.query(Table1, Table2).join(Table2, Table1.<span class="built_in">id</span> == Table2.table1_id)</span><br><span class="line">inner_join_results = inner_join_query.<span class="built_in">all</span>()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Inner Join Results:&quot;</span>)</span><br><span class="line"><span class="keyword">for</span> result <span class="keyword">in</span> inner_join_results:</span><br><span class="line">    <span class="built_in">print</span>(result[<span class="number">0</span>].name, result[<span class="number">1</span>].name)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. Left Join</span></span><br><span class="line">left_join_query = session.query(Table1, Table2).join(Table2, Table1.<span class="built_in">id</span> == Table2.table1_id, isouter=<span class="literal">True</span>)</span><br><span class="line">left_join_results = left_join_query.<span class="built_in">all</span>()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Left Join Results:&quot;</span>)</span><br><span class="line"><span class="keyword">for</span> result <span class="keyword">in</span> left_join_results:</span><br><span class="line">    <span class="built_in">print</span>(result[<span class="number">0</span>].name, result[<span class="number">1</span>].name <span class="keyword">if</span> result[<span class="number">1</span>] <span class="keyword">else</span> <span class="string">&quot;NULL&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. Right Join</span></span><br><span class="line">right_join_query = session.query(Table1, Table2).join(Table2, Table1.<span class="built_in">id</span> == Table2.table1_id, isouter=<span class="literal">True</span>).from_statement(<span class="string">&quot;RIGHT JOIN table1 ON table1.id = table2.table1_id&quot;</span>)</span><br><span class="line">right_join_results = right_join_query.<span class="built_in">all</span>()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Right Join Results:&quot;</span>)</span><br><span class="line"><span class="keyword">for</span> result <span class="keyword">in</span> right_join_results:</span><br><span class="line">    <span class="built_in">print</span>(result[<span class="number">0</span>].name <span class="keyword">if</span> result[<span class="number">0</span>] <span class="keyword">else</span> <span class="string">&quot;NULL&quot;</span>, result[<span class="number">1</span>].name)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. Full Join</span></span><br><span class="line">full_join_query = session.query(Table1, Table2).join(Table2, Table1.<span class="built_in">id</span> == Table2.table1_id, full=<span class="literal">True</span>)</span><br><span class="line">full_join_results = full_join_query.<span class="built_in">all</span>()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Full Join Results:&quot;</span>)</span><br><span class="line"><span class="keyword">for</span> result <span class="keyword">in</span> full_join_results:</span><br><span class="line">    <span class="built_in">print</span>(result[<span class="number">0</span>].name <span class="keyword">if</span> result[<span class="number">0</span>] <span class="keyword">else</span> <span class="string">&quot;NULL&quot;</span>, result[<span class="number">1</span>].name <span class="keyword">if</span> result[<span class="number">1</span>] <span class="keyword">else</span> <span class="string">&quot;NULL&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 5. Cross Join</span></span><br><span class="line">cross_join_query = session.query(Table1, Table2).cross_join(Table2)</span><br><span class="line">cross_join_results = cross_join_query.<span class="built_in">all</span>()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Cross Join Results:&quot;</span>)</span><br><span class="line"><span class="keyword">for</span> result <span class="keyword">in</span> cross_join_results:</span><br><span class="line">    <span class="built_in">print</span>(result[<span class="number">0</span>].name, result[<span class="number">1</span>].name)</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;figure class=&quot;highlight python&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 clas</summary>
      
    
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/categories/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/categories/Sqlalchemy/ORM/"/>
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/tags/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/tags/ORM/"/>
    
  </entry>
  
  <entry>
    <title>Docker Minio 实现文件永久链接</title>
    <link href="https://blog.ifan.host/2022/12/10/docker/docker-minio/"/>
    <id>https://blog.ifan.host/2022/12/10/docker/docker-minio/</id>
    <published>2022-12-10T01:00:00.000Z</published>
    <updated>2023-12-25T05:56:09.169Z</updated>
    
    <content type="html"><![CDATA[<ol><li>启动Minio</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"></span><br><span class="line">BASEPATH=`<span class="built_in">pwd</span>`</span><br><span class="line">NAME=minio</span><br><span class="line"></span><br><span class="line">docker <span class="built_in">rm</span> -f <span class="variable">$NAME</span></span><br><span class="line">docker run -d --name <span class="variable">$NAME</span> \</span><br><span class="line">    --restart=always \</span><br><span class="line">    -v <span class="variable">$BASEPATH</span>/data:/data \</span><br><span class="line">    -v <span class="variable">$BASEPATH</span>/conf:/root/.minio \</span><br><span class="line">    -e <span class="string">&quot;MINIO_SERVER_URL=https://APIHost地址&quot;</span> \ <span class="comment"># 文件分享地址</span></span><br><span class="line">    -e <span class="string">&quot;MINIO_BROWSER_REDIRECT_URL=https://minio地址&quot;</span> \ <span class="comment"># 页面查看地址</span></span><br><span class="line">    -e <span class="string">&quot;MINIO_ROOT_USER=xxxx&quot;</span> \</span><br><span class="line">    -e <span class="string">&quot;MINIO_ROOT_PASSWORD=xxxx&quot;</span> \</span><br><span class="line">    minio/minio \</span><br><span class="line">    server ./data --console-address <span class="string">&quot;:9001&quot;</span> --address <span class="string">&quot;:9000&quot;</span></span><br><span class="line">docker logs -f <span class="variable">$NAME</span></span><br></pre></td></tr></table></figure><ol start="2"><li><p>Nginx 配置</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></pre></td><td class="code"><pre><span class="line">server &#123;</span><br><span class="line">    listen 80;</span><br><span class="line">    listen [::]:80;</span><br><span class="line">    server_name xxxx;</span><br><span class="line">    return 301 https://$server_name$request_uri;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">server &#123;</span><br><span class="line">    listen 443 ssl http2;</span><br><span class="line">    server_name xxxx;</span><br><span class="line">    location / &#123;</span><br><span class="line">        proxy_set_header Host $host;</span><br><span class="line">        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br><span class="line">        proxy_pass http://minio:9001/; # API自行配置9000</span><br><span class="line">    &#125;</span><br><span class="line">    ssl_certificate        /usr/local/openresty/nginx/cert/fullchain.cer;</span><br><span class="line">    ssl_certificate_key    /usr/local/openresty/nginx/cert/ifan.host.key;</span><br><span class="line">    ssl_protocols TLSv1.1 TLSv1.2;</span><br><span class="line">    ssl_prefer_server_ciphers on;</span><br><span class="line">    ssl_session_cache shared:SSL:10m;</span><br><span class="line">    ssl_session_timeout 10m;</span><br><span class="line"></span><br><span class="line">    access_log  /usr/local/openresty/nginx/logs/minio.access.log;</span><br><span class="line">    error_log  /usr/local/openresty/nginx/logs/minio.error.log;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>配置本地mc</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></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">&quot;version&quot;: &quot;10&quot;,</span><br><span class="line">&quot;aliases&quot;: &#123;</span><br><span class="line">&quot;minio&quot;: &#123;</span><br><span class="line">&quot;url&quot;: &quot;https://API地址&quot;,</span><br><span class="line">&quot;accessKey&quot;: &quot;xxxx&quot;,</span><br><span class="line">&quot;secretKey&quot;: &quot;xxx&quot;,</span><br><span class="line">&quot;api&quot;: &quot;s3v4&quot;,</span><br><span class="line">&quot;path&quot;: &quot;auto&quot;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="4"><li>设置永久链接</li></ol><figure class="highlight plaintext"><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><br><span class="line">mc anonymous set download minio/桶名称</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;ol&gt;
&lt;li&gt;启动Minio&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class=&quot;highlight bash&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;li</summary>
      
    
    
    
    <category term="工具" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Docker" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/Docker/"/>
    
    
    <category term="工具" scheme="https://blog.ifan.host/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Minio" scheme="https://blog.ifan.host/tags/Minio/"/>
    
    <category term="Docker" scheme="https://blog.ifan.host/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>Minio 配置 nginx 代理</title>
    <link href="https://blog.ifan.host/2022/12/10/database/minio/minio-nginx-proxy/"/>
    <id>https://blog.ifan.host/2022/12/10/database/minio/minio-nginx-proxy/</id>
    <published>2022-12-10T01:00:00.000Z</published>
    <updated>2023-12-25T08:26:29.115Z</updated>
    
    <content type="html"><![CDATA[<h2 id="启动Minio"><a href="#启动Minio" class="headerlink" title="启动Minio"></a>启动Minio</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></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"></span><br><span class="line">BASEPATH=`pwd`</span><br><span class="line">NAME=minio</span><br><span class="line"></span><br><span class="line">docker rm -f $NAME</span><br><span class="line">docker run -d --name $NAME \</span><br><span class="line">    --restart=always \</span><br><span class="line">    -v $BASEPATH/data:/data \</span><br><span class="line">    -v $BASEPATH/conf:/root/.minio \</span><br><span class="line">    -e &quot;MINIO_SERVER_URL=https://APIHost地址&quot; \ # 文件分享地址</span><br><span class="line">    -e &quot;MINIO_BROWSER_REDIRECT_URL=https://minio地址&quot; \ # 页面查看地址</span><br><span class="line">    -e &quot;MINIO_ROOT_USER=xxxx&quot; \</span><br><span class="line">    -e &quot;MINIO_ROOT_PASSWORD=xxxx&quot; \</span><br><span class="line">    minio/minio \</span><br><span class="line">    server ./data --console-address &quot;:9001&quot; --address &quot;:9000&quot;</span><br><span class="line">docker logs -f $NAME</span><br></pre></td></tr></table></figure><h2 id="nginx配置"><a href="#nginx配置" class="headerlink" title="nginx配置"></a>nginx配置</h2><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></pre></td><td class="code"><pre><span class="line">server &#123;</span><br><span class="line">    listen 80;</span><br><span class="line">    listen [::]:80;</span><br><span class="line">    server_name xxxx;</span><br><span class="line">    return 301 https://$server_name$request_uri;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">server &#123;</span><br><span class="line">    listen 443 ssl http2;</span><br><span class="line">    server_name xxxx;</span><br><span class="line">    location / &#123;</span><br><span class="line">        proxy_set_header Host $host;</span><br><span class="line">        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br><span class="line">        proxy_pass http://minio:9001/; # API自行配置9000</span><br><span class="line">    &#125;</span><br><span class="line">    ssl_certificate        /usr/local/openresty/nginx/cert/fullchain.cer;</span><br><span class="line">    ssl_certificate_key    /usr/local/openresty/nginx/cert/ifan.host.key;</span><br><span class="line">    ssl_protocols TLSv1.1 TLSv1.2;</span><br><span class="line">    ssl_prefer_server_ciphers on;</span><br><span class="line">    ssl_session_cache shared:SSL:10m;</span><br><span class="line">    ssl_session_timeout 10m;</span><br><span class="line"></span><br><span class="line">    access_log  /usr/local/openresty/nginx/logs/minio.access.log;</span><br><span class="line">    error_log  /usr/local/openresty/nginx/logs/minio.error.log;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="配置本地mc"><a href="#配置本地mc" class="headerlink" title="配置本地mc"></a>配置本地mc</h2><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></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">&quot;version&quot;: &quot;10&quot;,</span><br><span class="line">&quot;aliases&quot;: &#123;</span><br><span class="line">&quot;minio&quot;: &#123;</span><br><span class="line">&quot;url&quot;: &quot;https://API地址&quot;,</span><br><span class="line">&quot;accessKey&quot;: &quot;xxxx&quot;,</span><br><span class="line">&quot;secretKey&quot;: &quot;xxx&quot;,</span><br><span class="line">&quot;api&quot;: &quot;s3v4&quot;,</span><br><span class="line">&quot;path&quot;: &quot;auto&quot;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="设置永久链接"><a href="#设置永久链接" class="headerlink" title="设置永久链接"></a>设置永久链接</h2><figure class="highlight plaintext"><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><br><span class="line">mc anonymous set download minio/桶名称</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;启动Minio&quot;&gt;&lt;a href=&quot;#启动Minio&quot; class=&quot;headerlink&quot; title=&quot;启动Minio&quot;&gt;&lt;/a&gt;启动Minio&lt;/h2&gt;&lt;figure class=&quot;highlight shell&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=</summary>
      
    
    
    
    <category term="Minio" scheme="https://blog.ifan.host/categories/Minio/"/>
    
    
    <category term="Minio" scheme="https://blog.ifan.host/tags/Minio/"/>
    
  </entry>
  
  <entry>
    <title>Sqlalchemy 基础学习</title>
    <link href="https://blog.ifan.host/2022/12/01/language/python/libs/sqlalchemy/sqlalchemy-base/"/>
    <id>https://blog.ifan.host/2022/12/01/language/python/libs/sqlalchemy/sqlalchemy-base/</id>
    <published>2022-12-01T01:00:00.000Z</published>
    <updated>2024-10-10T06:09:37.342Z</updated>
    
    <content type="html"><![CDATA[<h1 id="增删改查"><a href="#增删改查" class="headerlink" title="增删改查"></a>增删改查</h1><h2 id="添加"><a href="#添加" class="headerlink" title="添加"></a>添加</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 添加单个对象</span></span><br><span class="line">user = User(name=<span class="string">&#x27;ed&#x27;</span>, fullname=<span class="string">&#x27;Ed Jones&#x27;</span>, nickname=<span class="string">&#x27;edsnickname&#x27;</span>)</span><br><span class="line">session.add(user)</span><br><span class="line"><span class="comment"># 添加对象忽略重复错误</span></span><br><span class="line">insert_command = User.__table__.insert().prefix_with(<span class="string">&#x27; IGNORE&#x27;</span>).values(data)</span><br><span class="line"><span class="keyword">with</span> db.engine.connect() <span class="keyword">as</span> connect:</span><br><span class="line">    connect.execute(insert_command)</span><br><span class="line">    connect.commit()</span><br><span class="line"><span class="comment"># 批量添加</span></span><br><span class="line">users = [</span><br><span class="line">    User(name=<span class="string">&#x27;wendy&#x27;</span>, fullname=<span class="string">&#x27;Wendy Williams&#x27;</span>, nickname=<span class="string">&#x27;windy&#x27;</span>),</span><br><span class="line">    User(name=<span class="string">&#x27;mary&#x27;</span>, fullname=<span class="string">&#x27;Mary Contrary&#x27;</span>, nickname=<span class="string">&#x27;mary&#x27;</span>),</span><br><span class="line">    User(name=<span class="string">&#x27;fred&#x27;</span>, fullname=<span class="string">&#x27;Fred Flintstone&#x27;</span>, nickname=<span class="string">&#x27;freddy&#x27;</span>)</span><br><span class="line">]</span><br><span class="line">session.add_all(users)</span><br><span class="line">session.commit() <span class="comment"># 提交</span></span><br><span class="line">session.rollback() <span class="comment"># 回滚</span></span><br><span class="line"><span class="comment"># Upsert</span></span><br><span class="line">insert_stmt = insert(User).values(**insert_data)</span><br><span class="line">on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(**update_data)</span><br><span class="line"><span class="keyword">with</span> db.engine.connect() <span class="keyword">as</span> connect:</span><br><span class="line">    connect.execute(on_duplicate_key_stmt)</span><br></pre></td></tr></table></figure><h2 id="删除"><a href="#删除" class="headerlink" title="删除"></a>删除</h2><figure class="highlight python"><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">session.delete(jack)</span><br><span class="line">session.query(User).filter_by(name=<span class="string">&#x27;jack&#x27;</span>).count()</span><br></pre></td></tr></table></figure><h2 id="修改"><a href="#修改" class="headerlink" title="修改"></a>修改</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> update, bindparam</span><br><span class="line">stmt = update(User).where(User.c.name == <span class="string">&quot;iFan&quot;</span>).values(fullname=<span class="string">&quot;iFanlw&quot;</span>)</span><br><span class="line"></span><br><span class="line">stmt = update(user_table).where(user_table.c.name == bindparam(<span class="string">&quot;oldname&quot;</span>)).values(name=bindparam(<span class="string">&quot;newname&quot;</span>))</span><br><span class="line"><span class="keyword">with</span> engine.begin() <span class="keyword">as</span> conn:</span><br><span class="line">    conn.execute(</span><br><span class="line">        stmt,</span><br><span class="line">        [</span><br><span class="line">            &#123;<span class="string">&quot;oldname&quot;</span>: <span class="string">&quot;jack&quot;</span>, <span class="string">&quot;newname&quot;</span>: <span class="string">&quot;ed&quot;</span>&#125;,</span><br><span class="line">            &#123;<span class="string">&quot;oldname&quot;</span>: <span class="string">&quot;wendy&quot;</span>, <span class="string">&quot;newname&quot;</span>: <span class="string">&quot;mary&quot;</span>&#125;,</span><br><span class="line">            &#123;<span class="string">&quot;oldname&quot;</span>: <span class="string">&quot;jim&quot;</span>, <span class="string">&quot;newname&quot;</span>: <span class="string">&quot;jake&quot;</span>&#125;,</span><br><span class="line">        ],</span><br><span class="line">    )</span><br></pre></td></tr></table></figure><h2 id="查询"><a href="#查询" class="headerlink" title="查询"></a>查询</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查询全部</span></span><br><span class="line">session.query(User).<span class="built_in">all</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 根据条件查询</span></span><br><span class="line">session.query(User).<span class="built_in">filter</span>(User.name == <span class="string">&quot;iFan&quot;</span>).<span class="built_in">all</span>()</span><br><span class="line">session.query(User).<span class="built_in">filter</span>(User.name != <span class="string">&quot;iFan&quot;</span>).<span class="built_in">all</span>()</span><br><span class="line">session.query(User).<span class="built_in">filter</span>(User.name.like(<span class="string">&quot;%ifan%&quot;</span>)).<span class="built_in">all</span>() <span class="comment"># 区分大小写</span></span><br><span class="line">session.query(User).<span class="built_in">filter</span>(User.name.ilike(<span class="string">&quot;%ifan%&quot;</span>)).<span class="built_in">all</span>() <span class="comment"># 不区分大小写</span></span><br><span class="line">session.query(User).<span class="built_in">filter</span>(User.name.in_([<span class="string">&quot;ifan&quot;</span>, <span class="string">&quot;ifan1&quot;</span>])).<span class="built_in">all</span>()</span><br><span class="line">session.query(User).<span class="built_in">filter</span>(User.name.in_(session.query(User.name).<span class="built_in">filter</span>(User.name.like(<span class="string">&quot;%ifan%&quot;</span>)))).<span class="built_in">all</span>()</span><br><span class="line"><span class="comment"># 多个In条件组合</span></span><br><span class="line"><span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> tuple_</span><br><span class="line">query.<span class="built_in">filter</span>(tuple_(User.name, User.nickname).in_([(<span class="string">&#x27;ed&#x27;</span>, <span class="string">&#x27;edsnickname&#x27;</span>), (<span class="string">&#x27;wendy&#x27;</span>, <span class="string">&#x27;windy&#x27;</span>)]))</span><br><span class="line"><span class="comment"># not in </span></span><br><span class="line">session.query.<span class="built_in">filter</span>(~User.name.in_([<span class="string">&#x27;ed&#x27;</span>, <span class="string">&#x27;wendy&#x27;</span>, <span class="string">&#x27;jack&#x27;</span>]))</span><br><span class="line"><span class="comment"># is None</span></span><br><span class="line">session.query(User).<span class="built_in">filter</span>(User.name.is_not(<span class="literal">None</span>)).<span class="built_in">all</span>()</span><br><span class="line"><span class="comment"># and</span></span><br><span class="line"><span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> and_</span><br><span class="line">session.query.<span class="built_in">filter</span>(and_(User.name == <span class="string">&#x27;ed&#x27;</span>, User.fullname == <span class="string">&#x27;Ed Jones&#x27;</span>))</span><br><span class="line"><span class="comment"># or</span></span><br><span class="line"><span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> or_</span><br><span class="line">session.query.<span class="built_in">filter</span>(or_(User.name == <span class="string">&#x27;ed&#x27;</span>, User.name == <span class="string">&#x27;wendy&#x27;</span>))</span><br><span class="line"><span class="comment"># 存在则返回，否则返回None</span></span><br><span class="line">session.query.<span class="built_in">filter</span>(User.<span class="built_in">id</span> == <span class="number">1</span>).one_or_none()</span><br><span class="line"><span class="comment"># 使用文本的查询</span></span><br><span class="line"><span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> text</span><br><span class="line">session.query.<span class="built_in">filter</span>(text(<span class="string">&quot;id = 1&quot;</span>)).order_by(text(<span class="string">&quot;id&quot;</span>).<span class="built_in">all</span>()</span><br><span class="line">session.query(User).<span class="built_in">filter</span>(text(<span class="string">&quot;id&lt;:value and name=:name&quot;</span>)).params(value=<span class="number">224</span>, name=<span class="string">&#x27;fred&#x27;</span>).order_by(User.<span class="built_in">id</span>).one()</span><br><span class="line">session.query(User).from_statement(text(<span class="string">&quot;SELECT * FROM users where name=:name&quot;</span>)).params(name=<span class="string">&#x27;ed&#x27;</span>).<span class="built_in">all</span>()</span><br><span class="line">stmt = text(<span class="string">&quot;SELECT name, id, fullname, nickname FROM users where name=:name&quot;</span>)</span><br><span class="line">stmt = stmt.columns(User.name, User.<span class="built_in">id</span>, User.fullname, User.nickname)</span><br><span class="line">session.query(User).from_statement(stmt).params(name=<span class="string">&#x27;ed&#x27;</span>).<span class="built_in">all</span>()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 限制返回</span></span><br><span class="line"><span class="keyword">for</span> user <span class="keyword">in</span> session.query(User).<span class="built_in">filter</span>(User.age == <span class="number">18</span>)[:<span class="number">18</span>]:</span><br><span class="line">    <span class="built_in">print</span>(user.username, user.age)</span><br></pre></td></tr></table></figure><h3 id="分组查询"><a href="#分组查询" class="headerlink" title="分组查询"></a>分组查询</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 分组查询</span></span><br><span class="line"><span class="keyword">from</span> sqlalchemy <span class="keyword">import</span> func</span><br><span class="line">session.query(func.count(User.name), User.name).group_by(User.name).<span class="built_in">all</span>()</span><br><span class="line"><span class="comment"># count</span></span><br><span class="line">session.query(func.count(<span class="string">&#x27;*&#x27;</span>)).select_from(User).scalar()</span><br><span class="line">session.query(func.count(User.<span class="built_in">id</span>)).scalar()</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;增删改查&quot;&gt;&lt;a href=&quot;#增删改查&quot; class=&quot;headerlink&quot; title=&quot;增删改查&quot;&gt;&lt;/a&gt;增删改查&lt;/h1&gt;&lt;h2 id=&quot;添加&quot;&gt;&lt;a href=&quot;#添加&quot; class=&quot;headerlink&quot; title=&quot;添加&quot;&gt;&lt;/a&gt;添加&lt;/h</summary>
      
    
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/categories/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/categories/Sqlalchemy/ORM/"/>
    
    
    <category term="Sqlalchemy" scheme="https://blog.ifan.host/tags/Sqlalchemy/"/>
    
    <category term="ORM" scheme="https://blog.ifan.host/tags/ORM/"/>
    
  </entry>
  
  <entry>
    <title>Mac clashx 自动切换代理</title>
    <link href="https://blog.ifan.host/2022/11/27/tools/clashx%E8%87%AA%E5%8A%A8%E5%88%87%E6%8D%A2%E4%BB%A3%E7%90%86/"/>
    <id>https://blog.ifan.host/2022/11/27/tools/clashx%E8%87%AA%E5%8A%A8%E5%88%87%E6%8D%A2%E4%BB%A3%E7%90%86/</id>
    <published>2022-11-27T14:00:00.000Z</published>
    <updated>2023-12-25T05:56:09.182Z</updated>
    
    <content type="html"><![CDATA[<p><a href="https://lancellc.gitbook.io/clash/clash-config-file/proxy-groups/auto">设置自动切换代理</a></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></pre></td><td class="code"><pre><span class="line">proxy-groups:</span><br><span class="line">- name: &quot;auto&quot;</span><br><span class="line">  type: url-test</span><br><span class="line">  proxies:</span><br><span class="line">    - ss1</span><br><span class="line">    - ss2</span><br><span class="line">    - vmess1</span><br><span class="line">  url: &#x27;http://www.gstatic.com/generate_204&#x27;</span><br><span class="line">  interval: 300</span><br><span class="line"> #tolerance: 50</span><br><span class="line"> #lazy: true</span><br><span class="line"> #disable-udp: true</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;&lt;a href=&quot;https://lancellc.gitbook.io/clash/clash-config-file/proxy-groups/auto&quot;&gt;设置自动切换代理&lt;/a&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight plaintext&quot;&gt;&lt;tab</summary>
      
    
    
    
    <category term="工具" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Mac" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/Mac/"/>
    
    
    <category term="工具" scheme="https://blog.ifan.host/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Mac" scheme="https://blog.ifan.host/tags/Mac/"/>
    
  </entry>
  
  <entry>
    <title>Mac parallels 初始化网络失败</title>
    <link href="https://blog.ifan.host/2022/11/27/tools/mac/mac-parallels%E5%88%9D%E5%A7%8B%E5%8C%96%E7%BD%91%E7%BB%9C%E5%A4%B1%E8%B4%A5/"/>
    <id>https://blog.ifan.host/2022/11/27/tools/mac/mac-parallels%E5%88%9D%E5%A7%8B%E5%8C%96%E7%BD%91%E7%BB%9C%E5%A4%B1%E8%B4%A5/</id>
    <published>2022-11-27T14:00:00.000Z</published>
    <updated>2023-12-25T05:56:09.185Z</updated>
    
    <content type="html"><![CDATA[<h2 id="1-parallels-初始化网络失败"><a href="#1-parallels-初始化网络失败" class="headerlink" title="1. parallels 初始化网络失败"></a>1. parallels 初始化网络失败</h2><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">sudo vim /Library/Preferences/Parallels/network.desktop.xml</span><br></pre></td></tr></table></figure><p>将  <code>&lt;UseKextless&gt;-1&lt;/UseKextless&gt;</code> 改为 <code>&lt;UseKextless&gt;0&lt;/UseKextless&gt;</code></p><h2 id="2-操作失败"><a href="#2-操作失败" class="headerlink" title="2. 操作失败"></a>2. 操作失败</h2><ol><li>在创建前选择【安装前设置】</li><li>选择【硬件】-&gt;【CPU和内存】-&gt;【高级】</li><li>选择【虚拟机监控程序】-&gt; 【Parallels】</li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;1-parallels-初始化网络失败&quot;&gt;&lt;a href=&quot;#1-parallels-初始化网络失败&quot; class=&quot;headerlink&quot; title=&quot;1. parallels 初始化网络失败&quot;&gt;&lt;/a&gt;1. parallels 初始化网络失败&lt;/h2&gt;&lt;fi</summary>
      
    
    
    
    <category term="工具" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Mac" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/Mac/"/>
    
    
    <category term="工具" scheme="https://blog.ifan.host/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Mac" scheme="https://blog.ifan.host/tags/Mac/"/>
    
  </entry>
  
  <entry>
    <title>Mac 关闭特定的软件随系统的颜色变化</title>
    <link href="https://blog.ifan.host/2022/11/27/tools/mac/mac-%E5%85%B3%E9%97%AD%E7%89%B9%E5%AE%9A%E8%BD%AF%E4%BB%B6%E7%9A%84%E9%9A%8F%E7%B3%BB%E7%BB%9F%E9%A2%9C%E8%89%B2%E7%9A%84%E5%8F%98%E5%8C%96/"/>
    <id>https://blog.ifan.host/2022/11/27/tools/mac/mac-%E5%85%B3%E9%97%AD%E7%89%B9%E5%AE%9A%E8%BD%AF%E4%BB%B6%E7%9A%84%E9%9A%8F%E7%B3%BB%E7%BB%9F%E9%A2%9C%E8%89%B2%E7%9A%84%E5%8F%98%E5%8C%96/</id>
    <published>2022-11-27T14:00:00.000Z</published>
    <updated>2023-12-25T05:56:09.185Z</updated>
    
    <content type="html"><![CDATA[<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">osascript -e &#x27;id of app &quot;Mybase&quot;&#x27;</span><br><span class="line"></span><br><span class="line">defaults write com.wjjsoft.mybase8 NSRequiresAquaSystemAppearance -bool Yes</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;figure class=&quot;highlight plaintext&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 c</summary>
      
    
    
    
    <category term="工具" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Mac" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/Mac/"/>
    
    
    <category term="工具" scheme="https://blog.ifan.host/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="Mac" scheme="https://blog.ifan.host/tags/Mac/"/>
    
  </entry>
  
  <entry>
    <title>Mysql 统计数据库存储使用大小</title>
    <link href="https://blog.ifan.host/2022/11/27/database/mysql/mysql-%E7%BB%9F%E8%AE%A1%E5%AD%98%E5%82%A8%E7%A9%BA%E9%97%B4/"/>
    <id>https://blog.ifan.host/2022/11/27/database/mysql/mysql-%E7%BB%9F%E8%AE%A1%E5%AD%98%E5%82%A8%E7%A9%BA%E9%97%B4/</id>
    <published>2022-11-27T13:00:00.000Z</published>
    <updated>2023-12-25T05:56:09.166Z</updated>
    
    <content type="html"><![CDATA[<p><strong>前言</strong>在 mysql 中有一个默认的数据表 <code>information_schema</code>，<code>information_schema</code> 这张数据表保存了 MySQL 服务器所有数据库的信息。如数据库名，数据库的表，表栏的数据类型与访问权限等。</p><p>再简单点，这台 MySQL 服务器上，到底有哪些数据库、各个数据库有哪些表，每张表的字段类型是什么，各个数据库要什么权限才能访问，等等信息都保存在 information_schema 表里面，所以请勿删改此表。</p><p><strong>代码</strong></p><p>1，切换数据库</p><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">use information_schema; </span><br></pre></td></tr></table></figure><p>2，查看数据库使用大小 </p><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">select concat(round(sum(data_length/1024/1024),2),’MB’) as data from tables where table_schema=’DB_Name’ ; </span><br></pre></td></tr></table></figure><p>3，查看表使用大小 </p><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">select concat(round(sum(data_length/1024/1024),2),’MB’) as data from tables where table_schema=’DB_Name’ and table_name=’Table_Name’; </span><br></pre></td></tr></table></figure><p>网上找的一个，亲测可用:</p><p> 先进去 MySQL 自带管理库：information_schema</p><p> 然后查询 data_length,index_length</p><p> 你自己的数据库名：dbname</p><p> 你自己的表名：tablename </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></pre></td><td class="code"><pre><span class="line">mysql&gt; use information_schema;    </span><br><span class="line">Database changed    </span><br><span class="line">mysql&gt; select data_length,index_length    </span><br><span class="line">    -&gt; from tables where    </span><br><span class="line">    -&gt; table_schema=&#x27;dbname&#x27;    </span><br><span class="line">    -&gt; and table_name = &#x27;tablename&#x27;;   </span><br><span class="line">+-------------+--------------+    </span><br><span class="line">| data_length | index_length |    </span><br><span class="line">+-------------+--------------+    </span><br><span class="line">|   166379520 |    235782144 |    </span><br><span class="line">+-------------+--------------+    </span><br><span class="line">row in set (0.02 sec)    </span><br><span class="line">mysql&gt; select concat(round(sum(data_length/1024/1024),2),&#x27;MB&#x27;) as data_length_MB,    </span><br><span class="line">    -&gt; concat(round(sum(index_length/1024/1024),2),&#x27;MB&#x27;) as index_length_MB    </span><br><span class="line">    -&gt; from tables where    </span><br><span class="line">    -&gt; table_schema=&#x27;dbname&#x27;    </span><br><span class="line">    -&gt; and table_name = &#x27;tablename&#x27;;   </span><br><span class="line">+----------------+-----------------+    </span><br><span class="line">| data_length_MB | index_length_MB |    </span><br><span class="line">+----------------+-----------------+    </span><br><span class="line">| 158.67MB       | 224.86MB        |    </span><br><span class="line">+----------------+-----------------+    </span><br><span class="line">row in set (0.03 sec) </span><br></pre></td></tr></table></figure><h3 id="1-查看所有数据库容量大小"><a href="#1-查看所有数据库容量大小" class="headerlink" title="1. 查看所有数据库容量大小"></a>1. 查看所有数据库容量大小</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><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">select  </span><br><span class="line">table_schema as &#x27;数据库&#x27;,  </span><br><span class="line">sum(table_rows) as &#x27;记录数&#x27;,  </span><br><span class="line">sum(truncate(data_length/1024/1024, 2)) as &#x27;数据容量(MB)&#x27;,  </span><br><span class="line">sum(truncate(index_length/1024/1024, 2)) as &#x27;索引容量(MB)&#x27;  </span><br><span class="line">from information_schema.tables  </span><br><span class="line">group by table_schema  </span><br><span class="line">order by sum(data_length) desc, sum(index_length) desc;  </span><br></pre></td></tr></table></figure><h3 id="2-查看所有数据库各表容量大小"><a href="#2-查看所有数据库各表容量大小" class="headerlink" title="2.查看所有数据库各表容量大小"></a>2.查看所有数据库各表容量大小</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span>  </span><br><span class="line">table_schema <span class="keyword">as</span> <span class="string">&#x27;数据库&#x27;</span>,  </span><br><span class="line">table_name <span class="keyword">as</span> <span class="string">&#x27;表名&#x27;</span>,  </span><br><span class="line">table_rows <span class="keyword">as</span> <span class="string">&#x27;记录数&#x27;</span>,  </span><br><span class="line"><span class="keyword">truncate</span>(data_length<span class="operator">/</span><span class="number">1024</span><span class="operator">/</span><span class="number">1024</span>, <span class="number">2</span>) <span class="keyword">as</span> <span class="string">&#x27;数据容量(MB)&#x27;</span>,  </span><br><span class="line"><span class="keyword">truncate</span>(index_length<span class="operator">/</span><span class="number">1024</span><span class="operator">/</span><span class="number">1024</span>, <span class="number">2</span>) <span class="keyword">as</span> <span class="string">&#x27;索引容量(MB)&#x27;</span>  </span><br><span class="line"><span class="keyword">from</span> information_schema.tables  </span><br><span class="line"><span class="keyword">order</span> <span class="keyword">by</span> data_length <span class="keyword">desc</span>, index_length <span class="keyword">desc</span>; </span><br></pre></td></tr></table></figure><h3 id="3-查看指定数据库容量大小"><a href="#3-查看指定数据库容量大小" class="headerlink" title="3. 查看指定数据库容量大小"></a>3. 查看指定数据库容量大小</h3><p>例：查看 mysql 库容量大小 </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></pre></td><td class="code"><pre><span class="line">select  </span><br><span class="line">table_schema as &#x27;数据库&#x27;,  </span><br><span class="line">sum(table_rows) as &#x27;记录数&#x27;,  </span><br><span class="line">sum(truncate(data_length/1024/1024, 2)) as &#x27;数据容量(MB)&#x27;,  </span><br><span class="line">sum(truncate(index_length/1024/1024, 2)) as &#x27;索引容量(MB)&#x27;  </span><br><span class="line">from information_schema.tables  </span><br><span class="line">where table_schema=&#x27;mysql&#x27;; </span><br></pre></td></tr></table></figure><h3 id="4-查看指定数据库各表容量大小"><a href="#4-查看指定数据库各表容量大小" class="headerlink" title="4. 查看指定数据库各表容量大小"></a>4. 查看指定数据库各表容量大小</h3><p>例：查看 mysql 库各表容量大小 </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></pre></td><td class="code"><pre><span class="line">select  </span><br><span class="line">table_schema as &#x27;数据库&#x27;,  </span><br><span class="line">table_name as &#x27;表名&#x27;,  </span><br><span class="line">table_rows as &#x27;记录数&#x27;,  </span><br><span class="line">truncate(data_length/1024/1024, 2) as &#x27;数据容量(MB)&#x27;,  </span><br><span class="line">truncate(index_length/1024/1024, 2) as &#x27;索引容量(MB)&#x27;  </span><br><span class="line">from information_schema.tables  </span><br><span class="line">where table_schema=&#x27;mysql&#x27;  </span><br><span class="line">order by data_length desc, index_length desc;  </span><br><span class="line">select concat(round(sum(data_length/1024/1024),2),&#x27;MB&#x27;) as data_length_MB, concat(round(sum(index_length/1024/1024),2),&#x27;MB&#x27;) as index_length_MB  </span><br><span class="line">from tables  </span><br><span class="line">where table_schema=&#x27;passport&#x27; and table_name=&#x27;tb_user_info&#x27;; </span><br></pre></td></tr></table></figure><p>– 569.98MB 141.98MB </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">select concat(round(sum(data_length/1024/1024),2),&#x27;MB&#x27;) as data_length_MB, concat(round(sum(index_length/1024/1024),2),&#x27;MB&#x27;) as index_length_MB  </span><br><span class="line">from tables  </span><br><span class="line">where table_schema=&#x27;passport_v2&#x27; and table_name=&#x27;tb_user_info&#x27;; </span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;&lt;strong&gt;前言&lt;/strong&gt;在 mysql 中有一个默认的数据表 &lt;code&gt;information_schema&lt;/code&gt;，&lt;code&gt;information_schema&lt;/code&gt; 这张数据表保存了 MySQL 服务器所有数据库的信息。如数据库名，数据</summary>
      
    
    
    
    <category term="数据库" scheme="https://blog.ifan.host/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    <category term="MySQL" scheme="https://blog.ifan.host/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/MySQL/"/>
    
    
    <category term="数据库" scheme="https://blog.ifan.host/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    <category term="MySQL" scheme="https://blog.ifan.host/tags/MySQL/"/>
    
  </entry>
  
  <entry>
    <title>NodeJS http-proxy-middleware</title>
    <link href="https://blog.ifan.host/2022/11/27/language/javascript/libs/http-proxy-middleware/"/>
    <id>https://blog.ifan.host/2022/11/27/language/javascript/libs/http-proxy-middleware/</id>
    <published>2022-11-27T12:00:00.000Z</published>
    <updated>2023-12-25T05:56:09.175Z</updated>
    
    <content type="html"><![CDATA[<h1 id="http-proxy-middleware"><a href="#http-proxy-middleware" class="headerlink" title="http-proxy-middleware"></a>http-proxy-middleware</h1><p>用于把请求代理转发到其他服务器的中间件</p><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">npm install --save-dev http-proxy-middleware</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 引用依赖</span></span><br><span class="line"><span class="keyword">var</span> express = <span class="built_in">require</span>(<span class="string">&#x27;express&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> proxy = <span class="built_in">require</span>(<span class="string">&#x27;http-proxy-middleware&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// proxy 中间件的选择项</span></span><br><span class="line"><span class="keyword">var</span> options = &#123;</span><br><span class="line">        <span class="attr">target</span>: <span class="string">&#x27;http://www.example.org&#x27;</span>, <span class="comment">// 目标服务器 host</span></span><br><span class="line">        <span class="attr">changeOrigin</span>: <span class="literal">true</span>,               <span class="comment">// 默认false，是否需要改变原始主机头为目标URL</span></span><br><span class="line">        <span class="attr">ws</span>: <span class="literal">true</span>,                         <span class="comment">// 是否代理websockets</span></span><br><span class="line">        <span class="attr">pathRewrite</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;^/api/old-path&#x27;</span> : <span class="string">&#x27;/api/new-path&#x27;</span>,     <span class="comment">// 重写请求，比如我们源访问的是api/old-path，那么请求会被解析为/api/new-path</span></span><br><span class="line">            <span class="string">&#x27;^/api/remove/path&#x27;</span> : <span class="string">&#x27;/path&#x27;</span>           <span class="comment">// 同上</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">router</span>: &#123;</span><br><span class="line">            <span class="comment">// 如果请求主机 == &#x27;dev.localhost:3000&#x27;,</span></span><br><span class="line">            <span class="comment">// 重写目标服务器 &#x27;http://www.example.org&#x27; 为 &#x27;http://localhost:8000&#x27;</span></span><br><span class="line">            <span class="string">&#x27;dev.localhost:3000&#x27;</span> : <span class="string">&#x27;http://localhost:8000&#x27;</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建代理</span></span><br><span class="line"><span class="keyword">var</span> exampleProxy = <span class="title function_">proxy</span>(options);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用代理</span></span><br><span class="line"><span class="keyword">var</span> app = <span class="title function_">express</span>();</span><br><span class="line">    app.<span class="title function_">use</span>(<span class="string">&#x27;/api&#x27;</span>, exampleProxy);</span><br><span class="line">    app.<span class="title function_">listen</span>(<span class="number">3000</span>);</span><br></pre></td></tr></table></figure><h2 id="路径匹配"><a href="#路径匹配" class="headerlink" title="路径匹配"></a>路径匹配</h2><ul><li><code>proxy(&#123;...&#125;)</code>: 匹配任何路径，将所有请求转发</li><li><code>proxy(&#123;&#39;/&#39;, &#123;...&#125;&#125;)</code>: 匹配任何路径，将所有请求转发</li><li><code>proxy(&#123;&#39;/api&#39;, &#123;...&#125;&#125;)</code>: 匹配 <code>/api</code> 开头的请求</li><li><code>proxy([&#39;/api&#39;, &#39;/ajax&#39;], &#123;....&#125;)</code>: 匹配多个路径转发</li><li><code>proxy(&#39;**&#39;, &#123;...&#125;)</code>: 匹配任何路径，将所有请求转发</li><li><code>proxy(&#39;**/*.html&#39;, &#123;...&#125;)</code>: 匹配任何以html结尾的</li><li><code>proxy(&#39;/api/**/*.html&#39;, &#123;...&#125;)</code>: 匹配 <code>/api</code> 下以 <code>html</code> 结尾的请求</li><li><code>proxy([&#39;/api/**&#39;, &#39;/ajax/**&#39;], &#123;...&#125;)</code>: 组合</li><li><code>proxy([&#39;/api/**&#39;, &#39;!**/bad.json&#39;], &#123;...&#125;)</code>: 不包括 <code>**/bad.json</code></li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> filter = <span class="keyword">function</span> (<span class="params">pathname, req</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (pathname.<span class="title function_">match</span>(<span class="string">&#x27;^/api&#x27;</span>) &amp;&amp; req.<span class="property">method</span> === <span class="string">&#x27;GET&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">var</span> apiProxy = <span class="title function_">proxy</span>(filter, &#123;<span class="attr">target</span>: <span class="string">&#x27;http://www.example.org&#x27;</span>&#125;)</span><br></pre></td></tr></table></figure><h3 id="重写请求"><a href="#重写请求" class="headerlink" title="重写请求"></a>重写请求</h3><h4 id="pathRewrite-重写目标url请求"><a href="#pathRewrite-重写目标url请求" class="headerlink" title="pathRewrite 重写目标url请求"></a>pathRewrite 重写目标url请求</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 重写</span></span><br><span class="line"><span class="attr">pathRewrite</span>: &#123;<span class="string">&#x27;^/old/api&#x27;</span> : <span class="string">&#x27;/new/api&#x27;</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 移除</span></span><br><span class="line"><span class="attr">pathRewrite</span>: &#123;<span class="string">&#x27;^/remove/api&#x27;</span> : <span class="string">&#x27;&#x27;</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加</span></span><br><span class="line"><span class="attr">pathRewrite</span>: &#123;<span class="string">&#x27;^/&#x27;</span> : <span class="string">&#x27;/basepath/&#x27;</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 自定义</span></span><br><span class="line"><span class="attr">pathRewrite</span>: <span class="keyword">function</span> (<span class="params">path, req</span>) &#123; <span class="keyword">return</span> path.<span class="title function_">replace</span>(<span class="string">&#x27;/api&#x27;</span>, <span class="string">&#x27;/base/api&#x27;</span>) &#125;</span><br></pre></td></tr></table></figure><h4 id="router-重新指定请求转发目标"><a href="#router-重新指定请求转发目标" class="headerlink" title="router 重新指定请求转发目标"></a>router 重新指定请求转发目标</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用主机或者路径进行匹配，返回最先匹配到结果</span></span><br><span class="line"><span class="comment">// 所以配置的顺序很重要</span></span><br><span class="line"><span class="attr">router</span>: &#123;</span><br><span class="line">    <span class="string">&#x27;integration.localhost:3000&#x27;</span> : <span class="string">&#x27;http://localhost:8001&#x27;</span>,  <span class="comment">// host only</span></span><br><span class="line">    <span class="string">&#x27;staging.localhost:3000&#x27;</span>     : <span class="string">&#x27;http://localhost:8002&#x27;</span>,  <span class="comment">// host only</span></span><br><span class="line">    <span class="string">&#x27;localhost:3000/api&#x27;</span>         : <span class="string">&#x27;http://localhost:8003&#x27;</span>,  <span class="comment">// host + path</span></span><br><span class="line">    <span class="string">&#x27;/rest&#x27;</span>                      : <span class="string">&#x27;http://localhost:8004&#x27;</span>   <span class="comment">// path only</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 自定义</span></span><br><span class="line"><span class="attr">router</span>: <span class="keyword">function</span>(<span class="params">req</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&#x27;http://localhost:8004&#x27;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="http-proxy"><a href="#http-proxy" class="headerlink" title="http proxy"></a>http proxy</h3><h4 id="onError"><a href="#onError" class="headerlink" title="onError"></a>onError</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 监听proxy的onerr事件</span></span><br><span class="line">proxy.<span class="title function_">on</span>(<span class="string">&#x27;error&#x27;</span>, <span class="keyword">function</span> (<span class="params">err, req, res</span>) &#123;</span><br><span class="line">  res.<span class="title function_">writeHead</span>(<span class="number">500</span>, &#123;</span><br><span class="line">    <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;text/plain&#x27;</span></span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  res.<span class="title function_">end</span>(<span class="string">&#x27;Something went wrong. And we are reporting a custom error message.&#x27;</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="onProxyRes-监听proxy的回应事件"><a href="#onProxyRes-监听proxy的回应事件" class="headerlink" title="onProxyRes 监听proxy的回应事件"></a>onProxyRes 监听proxy的回应事件</h4><figure class="highlight javascript"><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">proxy.<span class="title function_">on</span>(<span class="string">&#x27;proxyRes&#x27;</span>, <span class="keyword">function</span> (<span class="params">proxyRes, req, res</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;RAW Response from the target&#x27;</span>, <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(proxyRes.<span class="property">headers</span>, <span class="literal">true</span>, <span class="number">2</span>));</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="onProxyReq-监听proxy的请求事件"><a href="#onProxyReq-监听proxy的请求事件" class="headerlink" title="onProxyReq: 监听proxy的请求事件"></a>onProxyReq: 监听proxy的请求事件</h4><figure class="highlight javascript"><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">proxy.<span class="title function_">on</span>(<span class="string">&#x27;proxyReq&#x27;</span>, <span class="keyword">function</span> <span class="title function_">onProxyReq</span>(<span class="params">proxyReq, req, res</span>) &#123;</span><br><span class="line">    proxyReq.<span class="title function_">setHeader</span>(<span class="string">&#x27;x-added&#x27;</span>, <span class="string">&#x27;foobar&#x27;</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="onProxyReqWs"><a href="#onProxyReqWs" class="headerlink" title="onProxyReqWs"></a>onProxyReqWs</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">onProxyReqWs</span>(<span class="params">proxyReq, req, socket, options, head</span>) &#123;</span><br><span class="line">    proxyReq.<span class="title function_">setHeader</span>(<span class="string">&#x27;X-Special-Proxy-Header&#x27;</span>, <span class="string">&#x27;foobar&#x27;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="onOpen-监听来自目标服务器的信息"><a href="#onOpen-监听来自目标服务器的信息" class="headerlink" title="onOpen: 监听来自目标服务器的信息"></a>onOpen: 监听来自目标服务器的信息</h4><figure class="highlight javascript"><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">proxy.<span class="title function_">on</span>(<span class="string">&#x27;open&#x27;</span>, <span class="keyword">function</span> (<span class="params">proxySocket</span>) &#123;</span><br><span class="line">  proxySocket.<span class="title function_">on</span>(<span class="string">&#x27;data&#x27;</span>, hybiParseAndLogMessage);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="onClose-链接断开"><a href="#onClose-链接断开" class="headerlink" title="onClose: 链接断开"></a>onClose: 链接断开</h4><figure class="highlight javascript"><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">proxy.<span class="title function_">on</span>(<span class="string">&#x27;close&#x27;</span>, <span class="keyword">function</span> (<span class="params">res, socket, head</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Client disconnected&#x27;</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;http-proxy-middleware&quot;&gt;&lt;a href=&quot;#http-proxy-middleware&quot; class=&quot;headerlink&quot; title=&quot;http-proxy-middleware&quot;&gt;&lt;/a&gt;http-proxy-middleware&lt;/</summary>
      
    
    
    
    <category term="NodeJS" scheme="https://blog.ifan.host/categories/NodeJS/"/>
    
    
    <category term="NodeJS" scheme="https://blog.ifan.host/tags/NodeJS/"/>
    
  </entry>
  
  <entry>
    <title>Frida 学习</title>
    <link href="https://blog.ifan.host/2022/08/11/spider/frida/"/>
    <id>https://blog.ifan.host/2022/08/11/spider/frida/</id>
    <published>2022-08-11T06:10:00.000Z</published>
    <updated>2023-12-25T05:56:09.178Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Frida-学习笔记"><a href="#Frida-学习笔记" class="headerlink" title="Frida 学习笔记"></a>Frida 学习笔记</h1><h2 id="环境开发"><a href="#环境开发" class="headerlink" title="环境开发"></a>环境开发</h2><p>查看安卓手机的版本</p><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">adb shell getprop ro.product.cpu.abi</span><br></pre></td></tr></table></figure><p>安装Python环境和frida-server</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></pre></td><td class="code"><pre><span class="line">pip install frida==15.0.11</span><br><span class="line">pip install frida-tools==10.2.1</span><br><span class="line">pip install objection</span><br><span class="line">wget https://github.com/frida/frida/releases?page=7#:~:text=frida%2Dserver%2D15.0.11%2Dandroid%2Darm64.xz</span><br><span class="line">adb push frida-server-15.0.11 /data/local/tmp/</span><br><span class="line">adb shell </span><br><span class="line">su root </span><br><span class="line">cd /data/local/tmp</span><br><span class="line">chmod +x frida-server-15.0.11</span><br><span class="line">./frida-server-15.0.11 -l 0.0.0.0:12345</span><br></pre></td></tr></table></figure><h2 id="frida-基础"><a href="#frida-基础" class="headerlink" title="frida 基础"></a>frida 基础</h2><p>一些函数签名</p><table><thead><tr><th>Field Descriptor</th><th>Java Language Type</th></tr></thead><tbody><tr><td>Z</td><td>boolean</td></tr><tr><td>B</td><td>byte</td></tr><tr><td>C</td><td>char</td></tr><tr><td>S</td><td>short</td></tr><tr><td>I</td><td>int</td></tr><tr><td>J</td><td>long</td></tr><tr><td>F</td><td>float</td></tr><tr><td>D</td><td>double</td></tr><tr><td><code>[</code></td><td>array</td></tr></tbody></table><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 修改静态参数和非静态参数</span></span><br><span class="line"><span class="comment">// 如果类中 成员函数 和 成员变量名称相同，则成员变量前添加 _</span></span><br><span class="line"><span class="title class_">Java</span>.<span class="title function_">perform</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;start&quot;</span>)</span><br><span class="line">    <span class="keyword">var</span> <span class="title class_">FridaActivity2</span> = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;com.example.androiddemo.Activity.FridaActivity2&quot;</span>)</span><br><span class="line">    <span class="comment">//hook静态函数直接调用</span></span><br><span class="line">    <span class="title class_">FridaActivity2</span>.<span class="title function_">setStatic_bool_var</span>()</span><br><span class="line">    <span class="comment">//hook动态函数，找到instance实例，从实例调用函数方法</span></span><br><span class="line">    <span class="title class_">Java</span>.<span class="title function_">choose</span>(<span class="string">&quot;com.example.androiddemo.Activity.FridaActivity2&quot;</span>, &#123;</span><br><span class="line">        <span class="attr">onMatch</span>: <span class="keyword">function</span> (<span class="params">instance</span>) &#123;</span><br><span class="line">            instance.<span class="title function_">setBool_var</span>()</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">onComplete</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;end&quot;</span>)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Hook 内部类</span></span><br><span class="line"><span class="keyword">var</span> <span class="title class_">InnerClasses</span> = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;com.example.androiddemo.Activity.FridaActivity4$InnerClasses&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 修改默认的Java Loader</span></span><br><span class="line"><span class="title class_">Java</span>.<span class="title function_">enumerateClassLoaders</span>(&#123;</span><br><span class="line">    <span class="attr">onMatch</span>: <span class="keyword">function</span> (<span class="params">loader</span>) &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">// 查看当前Loader中是否含有该类</span></span><br><span class="line">            <span class="keyword">if</span>(loader.<span class="title function_">findClass</span>(<span class="string">&quot;com.example.androiddemo.Dynamic.DynamicCheck&quot;</span>))&#123;</span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;Successfully found loader&quot;</span>)</span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">log</span>(loader);</span><br><span class="line">                <span class="comment">// 如果存在则设置为默认的Loader</span></span><br><span class="line">                <span class="title class_">Java</span>.<span class="property">classFactory</span>.<span class="property">loader</span> = loader ;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">catch</span>(error)&#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;find error:&quot;</span> + error)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">onComplete</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;end1&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"><span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;com.example.androiddemo.Dynamic.DynamicCheck&quot;</span>).<span class="property">check</span>.<span class="property">implementation</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 遍历所有静态类</span></span><br><span class="line"><span class="title class_">Java</span>.<span class="title function_">enumerateLoadedClasses</span>(&#123;</span><br><span class="line">    <span class="attr">onMatch</span>: <span class="keyword">function</span> (<span class="params">name, handle</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span> (name.<span class="title function_">indexOf</span>(<span class="string">&quot;com.example.androiddemo.Activity.Frida6&quot;</span>) != -<span class="number">1</span>) &#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;name:&quot;</span> + name + <span class="string">&quot; handle:&quot;</span> + handle)</span><br><span class="line">            <span class="title class_">Java</span>.<span class="title function_">use</span>(name).<span class="property">check</span>.<span class="property">implementation</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">onComplete</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;end&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 搜索interface的具体实现类 利用反射得到类里面实现的interface数组，并打印出来。</span></span><br><span class="line"><span class="title class_">Java</span>.<span class="title function_">enumerateLoadedClasses</span>(&#123;</span><br><span class="line">    <span class="attr">onMatch</span>: <span class="keyword">function</span> (<span class="params">class_name</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span> (class_name.<span class="title function_">indexOf</span>(<span class="string">&quot;com.example.androiddemo&quot;</span>) &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">var</span> hook_cls = <span class="title class_">Java</span>.<span class="title function_">use</span>(class_name)</span><br><span class="line">            <span class="keyword">var</span> interfaces = hook_cls.<span class="property">class</span>.<span class="title function_">getInterfaces</span>()</span><br><span class="line">            <span class="keyword">if</span> (interfaces.<span class="property">length</span> &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">log</span>(class_name + <span class="string">&quot;: &quot;</span>)</span><br><span class="line">                <span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> interfaces) &#123;</span><br><span class="line">                    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;\t&quot;</span>, interfaces[i].<span class="title function_">toString</span>())</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">onComplete</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;end&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Hook 构造函数</span></span><br><span class="line"><span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;com.tlamb96.kgbmessenger.b.a&quot;</span>).<span class="property">$init</span>.<span class="property">implementation</span> = <span class="keyword">function</span> (<span class="params">i, str1, str2, z</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.$init(i, str1, str2, z)</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(i, str1, str2, z)</span><br><span class="line">    <span class="title function_">printStack</span>(<span class="string">&quot;com.tlamb96.kgbmessenger.b.a&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 强制转换</span></span><br><span class="line"><span class="title class_">Java</span>.<span class="title function_">cast</span>(<span class="title class_">Childer</span>, <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;com.androidapp.Father&quot;</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment">// 新建Class</span></span><br><span class="line"><span class="keyword">var</span> interfaceClass = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;com.androidapp.InterfaceClazz&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> newClass = <span class="title class_">Java</span>.<span class="title function_">registerClass</span>(&#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&#x27;com.androidapp.newClass&#x27;</span>,</span><br><span class="line">    <span class="attr">implements</span>: [interfaceClass],</span><br><span class="line">    <span class="attr">methods</span>: &#123;</span><br><span class="line">        <span class="attr">flow</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&quot;OK&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(newClass.$new().<span class="title function_">flow</span>())  </span><br><span class="line"></span><br><span class="line"><span class="comment">// 枚举类</span></span><br><span class="line"><span class="title class_">Java</span>.<span class="title function_">choose</span>(<span class="string">&quot;com.exampleapp.Signal&quot;</span>,&#123;</span><br><span class="line">    <span class="attr">onMatch</span>:<span class="keyword">function</span>(<span class="params">instance</span>)&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;instance.name:&quot;</span>,instance.<span class="title function_">name</span>());</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;instance.getDeclaringClass:&quot;</span>,instance.<span class="title function_">getDeclaringClass</span>());                </span><br><span class="line">    &#125;,<span class="attr">onComplete</span>:<span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;search completed!&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h3 id="外部调用"><a href="#外部调用" class="headerlink" title="外部调用"></a>外部调用</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> frida</span><br><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">HookManager</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, arg, Flag</span>):</span><br><span class="line">        <span class="variable language_">self</span>.arg = arg</span><br><span class="line">        <span class="variable language_">self</span>.js_code = <span class="string">&#x27;&#x27;</span></span><br><span class="line">        <span class="variable language_">self</span>.JS_FILE = <span class="string">&#x27;jscode/&#x27;</span></span><br><span class="line">        <span class="variable language_">self</span>.load_js()</span><br><span class="line">        <span class="keyword">if</span> flag: <span class="variable language_">self</span>.log = <span class="built_in">open</span>(<span class="string">&#x27;log/&#x27;</span> + arg + <span class="string">&#x27;.txt&#x27;</span>, <span class="string">&#x27;w+&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">load_js</span>(<span class="params">self</span>):</span><br><span class="line">        file_names = os.listdir(<span class="variable language_">self</span>.JS_FILE)</span><br><span class="line">        <span class="keyword">for</span> filename <span class="keyword">in</span> file_names:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;载入：&#x27;</span> + filename)</span><br><span class="line">            <span class="keyword">with</span> <span class="built_in">open</span>(<span class="variable language_">self</span>.JS_FILE + filename, <span class="string">&#x27;r&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">                <span class="variable language_">self</span>.js_code += f.read()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">message</span>(<span class="params">self, msg, data</span>):</span><br><span class="line">        <span class="keyword">if</span> msg[<span class="string">&quot;type&quot;</span>] == <span class="string">&#x27;send&#x27;</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">u&quot;[*] &#123;0&#125;&quot;</span>.<span class="built_in">format</span>(msg[<span class="string">&#x27;payload&#x27;</span>]))</span><br><span class="line">            <span class="keyword">if</span> <span class="keyword">not</span> <span class="variable language_">self</span>.log: <span class="keyword">return</span></span><br><span class="line">            <span class="variable language_">self</span>.log.write(<span class="string">u&quot;[*] &#123;0&#125;\n&quot;</span>.<span class="built_in">format</span>(msg[<span class="string">&#x27;payload&#x27;</span>]))</span><br><span class="line">            <span class="variable language_">self</span>.log.flush()</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(msg)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">hooking</span>(<span class="params">self, host</span>):</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            process = frida.get_device_manager().add_remote_device(host).attach(<span class="variable language_">self</span>.arg)</span><br><span class="line">            <span class="comment"># one devices use</span></span><br><span class="line">            <span class="comment"># process = frida.get_remote_device(host).attach(self.arg)</span></span><br><span class="line">            script = process.create_script(<span class="variable language_">self</span>.js_code)</span><br><span class="line">            script.on(<span class="string">&quot;message&quot;</span>, <span class="variable language_">self</span>.message)</span><br><span class="line">            script.load()</span><br><span class="line">            sys.stdin.read()</span><br><span class="line">        <span class="keyword">except</span> frida.ServerNotRunningError:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;没有开启对应app， 或没有开启映射端口&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">close</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="variable language_">self</span>.log.close()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line"></span><br><span class="line">    bak = <span class="string">&quot;com.example.test&quot;</span></span><br><span class="line">    host_list = [</span><br><span class="line">        <span class="string">&quot;192.168.191.2:9898&quot;</span>,</span><br><span class="line">    ]</span><br><span class="line"></span><br><span class="line">    flag = <span class="literal">True</span> <span class="keyword">if</span> <span class="built_in">len</span>(host_list) ==<span class="number">1</span> <span class="keyword">else</span> flag == <span class="literal">False</span>  <span class="comment"># 只有一台机子的时候默认是调试模式， 多台就是控制模式</span></span><br><span class="line">    hk = HookManager(bak, flag)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> host <span class="keyword">in</span> host_list:</span><br><span class="line">        hk.hooking(host)</span><br><span class="line"></span><br><span class="line">    hk.close()</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="frida-tools-方法"><a href="#frida-tools-方法" class="headerlink" title="frida-tools 方法"></a>frida-tools 方法</h2><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">frida-ps -U # 查看当前存在的进程</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line">1. 脱离PC使用Frida的几种方式</span><br><span class="line">    a) 在手机上使用Termux终端</span><br><span class="line">    b) frida-inject</span><br><span class="line">    c) frida-gadget.so</span><br><span class="line">        优点：可以免root使用frida、frida-gadget比较稳定</span><br><span class="line">            缺点：需要重打包app，局限性较大。但是我们可以通过魔改系统，让系统帮我们注入so，免去重打包的繁琐</span><br><span class="line"></span><br><span class="line">2. frida-inject的配置、选项和使用</span><br><span class="line">    -f、-p、-n、-s、-e</span><br><span class="line"></span><br><span class="line">3. 脱离pc后，如何判断hook是否生效</span><br><span class="line">    a) 写文件，然后查看文件内容</span><br><span class="line">    b) 主动调用Log的方法输出信息，然后使用logcat查看</span><br><span class="line">    c) 修改某些方法逻辑</span><br></pre></td></tr></table></figure><h2 id="objection"><a href="#objection" class="headerlink" title="objection"></a>objection</h2><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></pre></td><td class="code"><pre><span class="line"># 启动并注入内存</span><br><span class="line">objection -g xxx.xxx.xxx explore -P /Users/username/.objection/plugins</span><br><span class="line"></span><br><span class="line">启动前就hook</span><br><span class="line">objection -N -h &lt;ip&gt; -p &lt;port&gt; -g &lt;进程名&gt; explore --startup-command &quot;android hooking watch class &lt;路径.类名&gt;&quot;</span><br><span class="line"></span><br><span class="line">启动前就hook打印参数、返回值、函数调用栈</span><br><span class="line">objection -N -h &lt;ip&gt; -p &lt;port&gt; -g &lt;进程名&gt; explore -s &quot;android hooking watch class_method &lt;路径.类名.方法名&gt;  --dump-args --dump-return --dump-backtrace&quot;</span><br><span class="line"></span><br><span class="line">如果启动前需要运行多条命令，可以写到一个文件中，使用-c选项</span><br><span class="line">objection -g &lt;进程名&gt; explore -c &quot;路径&quot;</span><br><span class="line"></span><br></pre></td></tr></table></figure><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><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"># 查看当前加载的module</span><br><span class="line">memory list modules</span><br><span class="line"></span><br><span class="line"># 查看库的导出函数</span><br><span class="line">memory list exports libssl.so</span><br><span class="line"></span><br><span class="line"># 内存搜索 </span><br><span class="line">memory search </span><br><span class="line"></span><br><span class="line"># 列出内存中所有的类 </span><br><span class="line">android hooking list classes</span><br><span class="line"></span><br><span class="line"># 在内存中所有已加载的类的方法中搜索包含特定关键词的方法 </span><br><span class="line">android hooking search methods display</span><br><span class="line"></span><br><span class="line"># 内存中搜索指定类的所有方法 </span><br><span class="line">android hooking list class_methods 类名</span><br><span class="line"></span><br><span class="line"># 在内存中所有已加载的类中搜索包含特定关键词的类。 </span><br><span class="line">android hooking search classes display</span><br><span class="line"></span><br><span class="line"># 搜索堆中的实例</span><br><span class="line">android heap search instances &lt;类名&gt;</span><br><span class="line"></span><br><span class="line"># Hook该类的全部方法 打印入参 调用栈 返回</span><br><span class="line">android hooking watch class 类名 --dump-args --dump-backtrace --dump-return</span><br><span class="line"># Hook具体的方法的所有重载方法</span><br><span class="line">android hooking watch class_method 方法名</span><br><span class="line"></span><br><span class="line"># 调用实例的方法 </span><br><span class="line">android heap execute 实例ID 实例方法</span><br><span class="line"></span><br><span class="line"># 直接启动activity或者服务 </span><br><span class="line">android intent launch_activity/launch_service activity/服务</span><br><span class="line"></span><br><span class="line"># 查看当前可用的activity或者service </span><br><span class="line">android hooking list activities/services</span><br><span class="line"></span><br><span class="line"># 内存堆搜索实例 </span><br><span class="line">android heap search instances 类名</span><br><span class="line"></span><br><span class="line"># 通过实例调用静态和实例方法</span><br><span class="line">android heap execute &lt;handle&gt; &lt;方法名&gt;</span><br><span class="line"></span><br><span class="line"># 打印所有 activities （页面）</span><br><span class="line">android hooking list activities </span><br><span class="line"></span><br><span class="line">查看与取消hook</span><br><span class="line">jobs list</span><br><span class="line">jobs kill &lt;jobId&gt;</span><br><span class="line"></span><br><span class="line"># 关闭ssl校验</span><br><span class="line">android sslpinning disable</span><br><span class="line"></span><br><span class="line"># 关闭root检测</span><br><span class="line">android root disable</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 直接生成该类的Hook方法</span><br><span class="line">android hooking generate  simple  com.android.settings.DisplaySettings</span><br></pre></td></tr></table></figure><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><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></pre></td><td class="code"><pre><span class="line">！             # 执行操作系统的命令(注意:不是在所连接device上执行命令)</span><br><span class="line">android     # 执行指定的 Android 命令</span><br><span class="line">        clipboard</span><br><span class="line">                monitor</span><br><span class="line">        deoptimize    # Force the VM to execute everything in the interpreter</span><br><span class="line">        heap</span><br><span class="line">                evaluate    # 在 Java 类中执行 JavaScript 脚本。</span><br><span class="line">                execute     # 在 Java 类中执行 方法。android heap execute 实例ID 实例方法</span><br><span class="line">                print</span><br><span class="line">                search</span><br><span class="line">                        instances  # 在当前Android heap上搜索类的实例。android heap search instances 类名</span><br><span class="line">        hooking</span><br><span class="line">                generate</span><br><span class="line">                        class    #  A generic hook manager for Classes</span><br><span class="line">                        simple   #  Simple hooks for each Class method</span><br><span class="line">                get</span><br><span class="line">                        current_activity    #  获取当前 前景(foregrounded) activity</span><br><span class="line">                list</span><br><span class="line">                        activities    # 列出已经登记的 Activities</span><br><span class="line">                        class_loaders # 列出已经登记的 class loaders </span><br><span class="line">                        class_methods # 列出一个类上的可用的方法</span><br><span class="line">                        classes       # 列出当前载入的所有类</span><br><span class="line">                        receivers     # 列出已经登记的 BroadcastReceivers</span><br><span class="line">                        services      # 列出已经登记的 Services</span><br><span class="line">                search</span><br><span class="line">                        classes 关键字    # 搜索与名称匹配的Java类</span><br><span class="line">                        methods 关键字    # 搜索与名称匹配的Java方法</span><br><span class="line">                set</span><br><span class="line">                        return_value    # 设置一个方法的返回值。只支持布尔返回</span><br><span class="line">                watch</span><br><span class="line">                        class           # Watches for invocations of all methods in a class</span><br><span class="line">                        class_method    # Watches for invocations of a specific class method</span><br><span class="line">        intent</span><br><span class="line">                launch_activity    # 使用Intent启动Activity类</span><br><span class="line">                launch_service     # Launch a Service class using an Intent</span><br><span class="line">        keystore</span><br><span class="line">                clear    # 清除 Android KeyStore</span><br><span class="line">                list     # 列出 Android KeyStore 中的条目</span><br><span class="line">                watch    # 监视 Android KeyStore 的使用</span><br><span class="line">        proxy    </span><br><span class="line">                set      # 为应用程序设置代理</span><br><span class="line">        root</span><br><span class="line">            disable    # 试图禁用 root 检测</span><br><span class="line">            simulate   # 试图模拟已经 root 的环境</span><br><span class="line">        shell_exec     # 执行shell命令</span><br><span class="line">        sslpinning</span><br><span class="line">                disable    # 尝试禁用 SSL pinning 在各种 Java libraries/classes</span><br><span class="line">        ui</span><br><span class="line">            FLAG_SECURE    # Control FLAG_SECURE of the current Activity</span><br><span class="line">            screenshot     # 在当前 Activity 进行截图</span><br><span class="line">cd          # 改变当前工作目录</span><br><span class="line">commands        </span><br><span class="line">        clear    # 清除当前会话命令的历史记录</span><br><span class="line">        history  # 列出当前会话命令历史记录</span><br><span class="line">        save     # 将在此会话中运行的所有惟一命令保存到一个文件中</span><br><span class="line">env         # 打印环境信息</span><br><span class="line">evaluate    # 执行 JavaScript。( Evaluate JavaScript within the agent )</span><br><span class="line">exit        # 退出</span><br><span class="line">file</span><br><span class="line">        cat         # 打印文件内容</span><br><span class="line">        download    # 下载一个文件</span><br><span class="line">        http        </span><br><span class="line">                start    # Start&#x27;s an HTTP server in the current working directory</span><br><span class="line">                status   # Get the status of the HTTP server</span><br><span class="line">                stop     # Stop&#x27;s a running HTTP server</span><br><span class="line">        upload           # 上传一个文件</span><br><span class="line">frida       # 获取关于 frida 环境的信息</span><br><span class="line">import      # 从完整路径导入 frida 脚本并运行</span><br><span class="line">ios         执行指定的 ios 命令</span><br><span class="line">        bundles</span><br><span class="line">        cookies</span><br><span class="line">        heap</span><br><span class="line">        hooking</span><br><span class="line">        info</span><br><span class="line">        jailbreak</span><br><span class="line">        keychain</span><br><span class="line">        monitor</span><br><span class="line">        nsurlcredentialstorage</span><br><span class="line">        nsuserdefaults</span><br><span class="line">        pasteboard</span><br><span class="line">        plist</span><br><span class="line">        sslpinning</span><br><span class="line">        ui</span><br><span class="line">jobs</span><br><span class="line">        kill    # 结束一个任务。这个操作不会写在卸载或者退出当前脚本</span><br><span class="line">        list    # 列出当前所有的任务</span><br><span class="line">ls              # 列出当前工作目录下的文件</span><br><span class="line">memory</span><br><span class="line">        dump</span><br><span class="line">                all 文件名                      # Dump 当前进程的整个内存</span><br><span class="line">                from_base 起始地址 字节数 文件  # 将(x)个字节的内存从基址转储到文件</span><br><span class="line">        list</span><br><span class="line">                exports    # List the exports of a module. (列出模块的导出)</span><br><span class="line">                modules    # List loaded modules in the current process. (列出当前进程中已加载的模块)</span><br><span class="line">        search    # 搜索模块。用法：memory search &quot;&lt;pattern eg: 41 41 41 ?? 41&gt;&quot; (--string) (--offsets-only)</span><br><span class="line">        write     # 将原始字节写入内存地址。小心使用!</span><br><span class="line">ping        # ping agent</span><br><span class="line">plugin      </span><br><span class="line">        load    # 载入插接</span><br><span class="line">pwd             # 打印当前工作目录</span><br><span class="line">reconnect       # 重新连接 device</span><br><span class="line">rm              # 从 device 上删除文件 </span><br><span class="line">sqlite          # sqlite 数据库命令</span><br><span class="line">        connect  # 连接到SQLite数据库文件</span><br><span class="line">ui</span><br><span class="line">        alert    # 显示警报消息，可选地指定要显示的消息。(目前iOS崩溃)</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="wallbreaker"><a href="#wallbreaker" class="headerlink" title="wallbreaker"></a>wallbreaker</h3><figure class="highlight plaintext"><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">cd ~/.objection/plugins</span><br><span class="line">git clone https://github.com/hluwa/Wallbreaker.git</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"># 搜索类</span><br><span class="line">plugin wallbreaker classsearch &lt;pattern&gt;</span><br><span class="line"></span><br><span class="line"># 搜索对象</span><br><span class="line">plugin wallbreaker objectsearch &lt;classname&gt;</span><br><span class="line"></span><br><span class="line"># 根据类名搜索内存中已经被创建的实例，列出 handle 和 toString() 的结果。</span><br><span class="line">plugin wallbreaker classdump &lt;classname&gt; [--fullname]</span><br><span class="line">plugin wallbreaker objectdump &lt;handle&gt; [--fullname]</span><br></pre></td></tr></table></figure><h3 id="frida-dexdump"><a href="#frida-dexdump" class="headerlink" title="frida-dexdump"></a>frida-dexdump</h3><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">pip3 install frida-dexdump</span><br></pre></td></tr></table></figure><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">frida-dexdump -FU</span><br><span class="line">frida-dexdump -U -f com.app.pkgname</span><br><span class="line"></span><br><span class="line">    -o OUTPUT, --output OUTPUT  Output folder path, default is &#x27;./&lt;appname&gt;/&#x27;.</span><br><span class="line">    -d, --deep-search           Enable deep search mode.</span><br><span class="line">    --sleep SLEEP               Waiting times for start, spawn mode default is 5s.</span><br></pre></td></tr></table></figure><h2 id="工具方法"><a href="#工具方法" class="headerlink" title="工具方法"></a>工具方法</h2><h3 id="打印调用栈"><a href="#打印调用栈" class="headerlink" title="打印调用栈"></a>打印调用栈</h3><figure class="highlight javascript"><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"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">printStack1</span>(<span class="params">name</span>) &#123;</span><br><span class="line">    <span class="title class_">Java</span>.<span class="title function_">perform</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">var</span> <span class="title class_">Exception</span> = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.lang.Exception&quot;</span>);</span><br><span class="line">        <span class="keyword">var</span> ins = <span class="title class_">Exception</span>.$new(<span class="string">&quot;Exception&quot;</span>);</span><br><span class="line">        <span class="keyword">var</span> straces = ins.<span class="title function_">getStackTrace</span>();</span><br><span class="line">        <span class="keyword">if</span> (straces != <span class="literal">undefined</span> &amp;&amp; straces != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="keyword">var</span> strace = straces.<span class="title function_">toString</span>();</span><br><span class="line">            <span class="keyword">var</span> replaceStr = strace.<span class="title function_">replace</span>(<span class="regexp">/,/g</span>, <span class="string">&quot;\\n&quot;</span>);</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;=============================&quot;</span> + name + <span class="string">&quot; Stack strat=======================&quot;</span>);</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(replaceStr);</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;=============================&quot;</span> + name + <span class="string">&quot; Stack end=======================\r\n&quot;</span>);</span><br><span class="line">            <span class="title class_">Exception</span>.$dispose();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">printStack2</span>(<span class="params">str_tag</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> <span class="title class_">Exception</span>=  <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.lang.Exception&quot;</span>);</span><br><span class="line">    <span class="keyword">var</span> ins = <span class="title class_">Exception</span>.$new(<span class="string">&quot;Exception&quot;</span>);</span><br><span class="line">    <span class="keyword">var</span> straces = ins.<span class="title function_">getStackTrace</span>();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (<span class="literal">undefined</span> == straces || <span class="literal">null</span>  == straces) </span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;=============================&quot;</span> + str_tag + <span class="string">&quot; Stack strat=======================&quot;</span>);</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; straces.<span class="property">length</span>; i++)</span><br><span class="line">     &#123;</span><br><span class="line">            <span class="keyword">var</span> str = <span class="string">&quot;   &quot;</span> + straces[i].<span class="title function_">toString</span>();</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(str);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;&quot;</span>);</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;=============================&quot;</span> + str_tag + <span class="string">&quot; Stack end=======================\r\n&quot;</span>);</span><br><span class="line">    <span class="title class_">Exception</span>.$dispose();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="byte2String"><a href="#byte2String" class="headerlink" title="byte2String"></a>byte2String</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">byteToString</span>(<span class="params">bytes</span>)&#123;</span><br><span class="line">    <span class="keyword">const</span> <span class="title class_">JString</span> = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&#x27;java.lang.String&#x27;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="title class_">JString</span>.$new(bytes);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="Hook-Md5-aes-base64-等"><a href="#Hook-Md5-aes-base64-等" class="headerlink" title="Hook Md5 aes base64 等"></a>Hook Md5 aes base64 等</h3><figure class="highlight javascript"><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><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//frida hook aes</span></span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">hook_cipher</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> cipher = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;javax.crypto.Cipher&quot;</span>);</span><br><span class="line">    cipher.<span class="property">doFinal</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">data, offset, length</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">doFinal</span>(data, offset, length);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;doFinal: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_aes</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> aes = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;javax.crypto.spec.SecretKeySpec&quot;</span>);</span><br><span class="line">    aes.<span class="property">getEncoded</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">getEncoded</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;getEncoded: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_base64</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> base64 = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;android.util.Base64&quot;</span>);</span><br><span class="line">    base64.<span class="property">encodeToString</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">data, flags</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">encodeToString</span>(data, flags);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;encodeToString: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_md5</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> md5 = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.security.MessageDigest&quot;</span>);</span><br><span class="line">    md5.<span class="property">digest</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">digest</span>(data);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;digest: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_sha1</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> sha1 = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.security.MessageDigest&quot;</span>);</span><br><span class="line">    sha1.<span class="property">digest</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">digest</span>(data);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;digest: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_sha256</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> sha256 = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.security.MessageDigest&quot;</span>);</span><br><span class="line">    sha256.<span class="property">digest</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">digest</span>(data);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;digest: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_sha512</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> sha512 = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.security.MessageDigest&quot;</span>);</span><br><span class="line">    sha512.<span class="property">digest</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">digest</span>(data);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;digest: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_hmac</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> hmac = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;javax.crypto.Mac&quot;</span>);</span><br><span class="line">    hmac.<span class="property">doFinal</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">doFinal</span>(data);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;doFinal: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_rsa</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> rsa = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.security.interfaces.RSAPublicKey&quot;</span>);</span><br><span class="line">    rsa.<span class="property">getEncoded</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">getEncoded</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;getEncoded: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_map</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> map = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.util.HashMap&quot;</span>);</span><br><span class="line">    map.<span class="property">put</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">key, value</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">put</span>(key, value);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;put: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">       </span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_list</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> list = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.util.ArrayList&quot;</span>);</span><br><span class="line">    list.<span class="property">add</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">value</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">add</span>(value);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;add: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_perform_click</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> click = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;android.view.View&quot;</span>);</span><br><span class="line">    click.<span class="property">performClick</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">performClick</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;performClick: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_set_text</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> text = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;android.widget.TextView&quot;</span>);</span><br><span class="line">    text.<span class="property">setText</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">text</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">setText</span>(text);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;setText: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_get_text</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> text = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;android.widget.TextView&quot;</span>); </span><br><span class="line">    text.<span class="property">getText</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">getText</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;getText: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;   </span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_get_package_name</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> package_name = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;android.content.Context&quot;</span>);</span><br><span class="line">    package_name.<span class="property">getPackageName</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">getPackageName</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;getPackageName: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//frida byte to string </span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_byte_to_string</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> byte = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;[B&quot;</span>);</span><br><span class="line">    byte.<span class="property">toString</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">toString</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;toString: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//frida string to byte</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_string_to_byte</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> string = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.lang.String&quot;</span>);</span><br><span class="line">    string.<span class="property">getBytes</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">getBytes</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;getBytes: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_response</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> response = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;okhttp3.Response&quot;</span>);</span><br><span class="line">    response.<span class="property">body</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">body</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;body: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_request_url</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> request = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;okhttp3.Request&quot;</span>);</span><br><span class="line">    request.<span class="property">url</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">url</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;url: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_url</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> url = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.net.URL&quot;</span>);</span><br><span class="line">    url.<span class="property">toString</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">toString</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;toString: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_url_connection</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> url_connection = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.net.URLConnection&quot;</span>);</span><br><span class="line">    url_connection.<span class="property">getInputStream</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">getInputStream</span>();</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;getInputStream: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_output_stream</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> output_stream = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.io.OutputStream&quot;</span>);</span><br><span class="line">    output_stream.<span class="property">write</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">data</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">write</span>(data);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;write: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">hook_loadLibrary</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> lib = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;java.lang.System&quot;</span>);</span><br><span class="line">    lib.<span class="property">loadLibrary</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">name</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">loadLibrary</span>(name);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;loadLibrary: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> linker = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;dalvik.system.DexClassLoader&quot;</span>);</span><br><span class="line">    linker.<span class="property">loadClass</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">name</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">loadClass</span>(name);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;loadClass: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">libart_hook</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> libart = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;libart.DexFile&quot;</span>);</span><br><span class="line">    libart.<span class="property">openDexFile</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">path,name,flags</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">openDexFile</span>(path,name,flags);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;openDexFile: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> libart_native = <span class="title class_">Java</span>.<span class="title function_">use</span>(<span class="string">&quot;libart.DexFile.Native&quot;</span>);</span><br><span class="line">    libart_native.<span class="property">dexFileOpen</span>.<span class="property">implementation</span> = <span class="keyword">function</span>(<span class="params">path,name,flags</span>)&#123;</span><br><span class="line">        <span class="keyword">var</span> ret = <span class="variable language_">this</span>.<span class="title function_">dexFileOpen</span>(path,name,flags);</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;dexFileOpen: &quot;</span> + ret);</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="自吐算法"><a href="#自吐算法" class="headerlink" title="自吐算法"></a>自吐算法</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><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><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># -*- coding: UTF-8 -*-</span></span><br><span class="line"><span class="keyword">import</span> frida, sys</span><br><span class="line"> </span><br><span class="line">jsCode = <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    function showStacks() &#123;</span></span><br><span class="line"><span class="string">        Java.perform(function () &#123;</span></span><br><span class="line"><span class="string">            send(Java.use(&quot;android.util.Log&quot;).getStackTraceString(Java.use(&quot;java.lang.Exception&quot;).$new()));</span></span><br><span class="line"><span class="string">        &#125;);</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">(function () &#123;</span></span><br><span class="line"><span class="string">    var base64EncodeChars = &#x27;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&#x27;,</span></span><br><span class="line"><span class="string">    base64DecodeChars = new Array((-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), 62, (-1), (-1), (-1), 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, (-1), (-1), (-1), (-1), (-1), (-1), (-1), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, (-1), (-1), (-1), (-1), (-1), (-1), 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, (-1), (-1), (-1), (-1), (-1));</span></span><br><span class="line"><span class="string">    this.stringToBase64 = function (e) &#123;</span></span><br><span class="line"><span class="string">        var r,a,c,h,o,t;</span></span><br><span class="line"><span class="string">        for (c = e.length, a = 0, r = &#x27;&#x27;; a &lt; c; ) &#123;</span></span><br><span class="line"><span class="string">            if (h = 255 &amp; e.charCodeAt(a++), a == c) &#123;</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt(h &gt;&gt; 2),</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt((3 &amp; h) &lt;&lt; 4),</span></span><br><span class="line"><span class="string">                r += &#x27;==&#x27;;</span></span><br><span class="line"><span class="string">                break</span></span><br><span class="line"><span class="string">            &#125;</span></span><br><span class="line"><span class="string">            if (o = e.charCodeAt(a++), a == c) &#123;</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt(h &gt;&gt; 2),</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt((3 &amp; h) &lt;&lt; 4 | (240 &amp; o) &gt;&gt; 4),</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt((15 &amp; o) &lt;&lt; 2),</span></span><br><span class="line"><span class="string">                r += &#x27;=&#x27;;</span></span><br><span class="line"><span class="string">                break</span></span><br><span class="line"><span class="string">            &#125;</span></span><br><span class="line"><span class="string">            t = e.charCodeAt(a++),</span></span><br><span class="line"><span class="string">            r += base64EncodeChars.charAt(h &gt;&gt; 2),</span></span><br><span class="line"><span class="string">            r += base64EncodeChars.charAt((3 &amp; h) &lt;&lt; 4 | (240 &amp; o) &gt;&gt; 4),</span></span><br><span class="line"><span class="string">            r += base64EncodeChars.charAt((15 &amp; o) &lt;&lt; 2 | (192 &amp; t) &gt;&gt; 6),</span></span><br><span class="line"><span class="string">            r += base64EncodeChars.charAt(63 &amp; t)</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        return r</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    this.base64ToString = function (e) &#123;</span></span><br><span class="line"><span class="string">        var r,a,c,h,o,t,d;</span></span><br><span class="line"><span class="string">        for (t = e.length, o = 0, d = &#x27;&#x27;; o &lt; t; ) &#123;</span></span><br><span class="line"><span class="string">            do</span></span><br><span class="line"><span class="string">                r = base64DecodeChars[255 &amp; e.charCodeAt(o++)];</span></span><br><span class="line"><span class="string">            while (o &lt; t &amp;&amp; r == -1);</span></span><br><span class="line"><span class="string">            if (r == -1)</span></span><br><span class="line"><span class="string">                break;</span></span><br><span class="line"><span class="string">            do</span></span><br><span class="line"><span class="string">                a = base64DecodeChars[255 &amp; e.charCodeAt(o++)];</span></span><br><span class="line"><span class="string">            while (o &lt; t &amp;&amp; a == -1);</span></span><br><span class="line"><span class="string">            if (a == -1)</span></span><br><span class="line"><span class="string">                break;</span></span><br><span class="line"><span class="string">            d += String.fromCharCode(r &lt;&lt; 2 | (48 &amp; a) &gt;&gt; 4);</span></span><br><span class="line"><span class="string">            do &#123;</span></span><br><span class="line"><span class="string">                if (c = 255 &amp; e.charCodeAt(o++), 61 == c)</span></span><br><span class="line"><span class="string">                    return d;</span></span><br><span class="line"><span class="string">                c = base64DecodeChars[c]</span></span><br><span class="line"><span class="string">            &#125; while (o &lt; t &amp;&amp; c == -1);</span></span><br><span class="line"><span class="string">            if (c == -1)</span></span><br><span class="line"><span class="string">                break;</span></span><br><span class="line"><span class="string">            d += String.fromCharCode((15 &amp; a) &lt;&lt; 4 | (60 &amp; c) &gt;&gt; 2);</span></span><br><span class="line"><span class="string">            do &#123;</span></span><br><span class="line"><span class="string">                if (h = 255 &amp; e.charCodeAt(o++), 61 == h)</span></span><br><span class="line"><span class="string">                    return d;</span></span><br><span class="line"><span class="string">                h = base64DecodeChars[h]</span></span><br><span class="line"><span class="string">            &#125; while (o &lt; t &amp;&amp; h == -1);</span></span><br><span class="line"><span class="string">            if (h == -1)</span></span><br><span class="line"><span class="string">                break;</span></span><br><span class="line"><span class="string">            d += String.fromCharCode((3 &amp; c) &lt;&lt; 6 | h)</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        return d</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    this.hexToBase64 = function (str) &#123;</span></span><br><span class="line"><span class="string">        return base64Encode(String.fromCharCode.apply(null, str.replace(/\r|\n/g, &quot;&quot;).replace(/([\da-fA-F]&#123;2&#125;) ?/g, &quot;0x$1 &quot;).replace(/ +$/, &quot;&quot;).split(&quot; &quot;)));</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    this.base64ToHex = function (str) &#123;</span></span><br><span class="line"><span class="string">        for (var i = 0, bin = base64Decode(str.replace(/[ \r\n]+$/, &quot;&quot;)), hex = []; i &lt; bin.length; ++i) &#123;</span></span><br><span class="line"><span class="string">            var tmp = bin.charCodeAt(i).toString(16);</span></span><br><span class="line"><span class="string">            if (tmp.length === 1)</span></span><br><span class="line"><span class="string">                tmp = &quot;0&quot; + tmp;</span></span><br><span class="line"><span class="string">            hex[hex.length] = tmp;</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        return hex.join(&quot;&quot;);</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    this.hexToBytes = function (str) &#123;</span></span><br><span class="line"><span class="string">        var pos = 0;</span></span><br><span class="line"><span class="string">        var len = str.length;</span></span><br><span class="line"><span class="string">        if (len % 2 != 0) &#123;</span></span><br><span class="line"><span class="string">            return null;</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        len /= 2;</span></span><br><span class="line"><span class="string">        var hexA = new Array();</span></span><br><span class="line"><span class="string">        for (var i = 0; i &lt; len; i++) &#123;</span></span><br><span class="line"><span class="string">            var s = str.substr(pos, 2);</span></span><br><span class="line"><span class="string">            var v = parseInt(s, 16);</span></span><br><span class="line"><span class="string">            hexA.push(v);</span></span><br><span class="line"><span class="string">            pos += 2;</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        return hexA;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    this.bytesToHex = function (arr) &#123;</span></span><br><span class="line"><span class="string">        var str = &#x27;&#x27;;</span></span><br><span class="line"><span class="string">        var k,j;</span></span><br><span class="line"><span class="string">        for(var i = 0; i&lt;arr.length; i++) &#123;</span></span><br><span class="line"><span class="string">            k = arr[i];</span></span><br><span class="line"><span class="string">            j = k;</span></span><br><span class="line"><span class="string">            if (k &lt; 0) &#123;</span></span><br><span class="line"><span class="string">                j = k + 256;</span></span><br><span class="line"><span class="string">            &#125;</span></span><br><span class="line"><span class="string">            if (j &lt; 16) &#123;</span></span><br><span class="line"><span class="string">                str += &quot;0&quot;;</span></span><br><span class="line"><span class="string">            &#125;</span></span><br><span class="line"><span class="string">            str += j.toString(16);</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        return str;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    this.stringToHex = function (str) &#123;</span></span><br><span class="line"><span class="string">        var val = &quot;&quot;;</span></span><br><span class="line"><span class="string">        for (var i = 0; i &lt; str.length; i++) &#123;</span></span><br><span class="line"><span class="string">            if (val == &quot;&quot;)</span></span><br><span class="line"><span class="string">                val = str.charCodeAt(i).toString(16);</span></span><br><span class="line"><span class="string">            else</span></span><br><span class="line"><span class="string">                val += str.charCodeAt(i).toString(16);</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        return val</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    this.stringToBytes = function (str) &#123;  </span></span><br><span class="line"><span class="string">        var ch, st, re = []; </span></span><br><span class="line"><span class="string">        for (var i = 0; i &lt; str.length; i++ ) &#123; </span></span><br><span class="line"><span class="string">            ch = str.charCodeAt(i);  </span></span><br><span class="line"><span class="string">            st = [];                 </span></span><br><span class="line"><span class="string">           do &#123;  </span></span><br><span class="line"><span class="string">                st.push( ch &amp; 0xFF );  </span></span><br><span class="line"><span class="string">                ch = ch &gt;&gt; 8;          </span></span><br><span class="line"><span class="string">            &#125;    </span></span><br><span class="line"><span class="string">            while ( ch );  </span></span><br><span class="line"><span class="string">            re = re.concat( st.reverse() ); </span></span><br><span class="line"><span class="string">        &#125;  </span></span><br><span class="line"><span class="string">        return re;  </span></span><br><span class="line"><span class="string">    &#125; </span></span><br><span class="line"><span class="string">    //将byte[]转成String的方法</span></span><br><span class="line"><span class="string">    this.bytesToString = function (arr) &#123;  </span></span><br><span class="line"><span class="string">        var str = &#x27;&#x27;;</span></span><br><span class="line"><span class="string">        arr = new Uint8Array(arr);</span></span><br><span class="line"><span class="string">        for(i in arr)&#123;</span></span><br><span class="line"><span class="string">            str += String.fromCharCode(arr[i]);</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        return str;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    this.bytesToBase64=function(e)&#123;</span></span><br><span class="line"><span class="string">        var r,a,c,h,o,t;</span></span><br><span class="line"><span class="string">        for (c = e.length, a = 0, r = &#x27;&#x27;; a &lt; c; ) &#123;</span></span><br><span class="line"><span class="string">            if (h = 255 &amp; e[a++], a == c) &#123;</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt(h &gt;&gt; 2),</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt((3 &amp; h) &lt;&lt; 4),</span></span><br><span class="line"><span class="string">                r += &#x27;==&#x27;;</span></span><br><span class="line"><span class="string">                break</span></span><br><span class="line"><span class="string">            &#125;</span></span><br><span class="line"><span class="string">            if (o = e[a++], a == c) &#123;</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt(h &gt;&gt; 2),</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt((3 &amp; h) &lt;&lt; 4 | (240 &amp; o) &gt;&gt; 4),</span></span><br><span class="line"><span class="string">                r += base64EncodeChars.charAt((15 &amp; o) &lt;&lt; 2),</span></span><br><span class="line"><span class="string">                r += &#x27;=&#x27;;</span></span><br><span class="line"><span class="string">                break</span></span><br><span class="line"><span class="string">            &#125;</span></span><br><span class="line"><span class="string">            t = e[a++],</span></span><br><span class="line"><span class="string">            r += base64EncodeChars.charAt(h &gt;&gt; 2),</span></span><br><span class="line"><span class="string">            r += base64EncodeChars.charAt((3 &amp; h) &lt;&lt; 4 | (240 &amp; o) &gt;&gt; 4),</span></span><br><span class="line"><span class="string">            r += base64EncodeChars.charAt((15 &amp; o) &lt;&lt; 2 | (192 &amp; t) &gt;&gt; 6),</span></span><br><span class="line"><span class="string">            r += base64EncodeChars.charAt(63 &amp; t)</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        return r</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    this.base64ToBytes=function(e)&#123;</span></span><br><span class="line"><span class="string">        var r,a,c,h,o,t,d;</span></span><br><span class="line"><span class="string">        for (t = e.length, o = 0, d = []; o &lt; t; ) &#123;</span></span><br><span class="line"><span class="string">            do</span></span><br><span class="line"><span class="string">                r = base64DecodeChars[255 &amp; e.charCodeAt(o++)];</span></span><br><span class="line"><span class="string">            while (o &lt; t &amp;&amp; r == -1);</span></span><br><span class="line"><span class="string">            if (r == -1)</span></span><br><span class="line"><span class="string">                break;</span></span><br><span class="line"><span class="string">            do</span></span><br><span class="line"><span class="string">                a = base64DecodeChars[255 &amp; e.charCodeAt(o++)];</span></span><br><span class="line"><span class="string">            while (o &lt; t &amp;&amp; a == -1);</span></span><br><span class="line"><span class="string">            if (a == -1)</span></span><br><span class="line"><span class="string">                break;</span></span><br><span class="line"><span class="string">            d.push(r &lt;&lt; 2 | (48 &amp; a) &gt;&gt; 4);</span></span><br><span class="line"><span class="string">            do &#123;</span></span><br><span class="line"><span class="string">                if (c = 255 &amp; e.charCodeAt(o++), 61 == c)</span></span><br><span class="line"><span class="string">                    return d;</span></span><br><span class="line"><span class="string">                c = base64DecodeChars[c]</span></span><br><span class="line"><span class="string">            &#125; while (o &lt; t &amp;&amp; c == -1);</span></span><br><span class="line"><span class="string">            if (c == -1)</span></span><br><span class="line"><span class="string">                break;</span></span><br><span class="line"><span class="string">            d.push((15 &amp; a) &lt;&lt; 4 | (60 &amp; c) &gt;&gt; 2);</span></span><br><span class="line"><span class="string">            do &#123;</span></span><br><span class="line"><span class="string">                if (h = 255 &amp; e.charCodeAt(o++), 61 == h)</span></span><br><span class="line"><span class="string">                    return d;</span></span><br><span class="line"><span class="string">                h = base64DecodeChars[h]</span></span><br><span class="line"><span class="string">            &#125; while (o &lt; t &amp;&amp; h == -1);</span></span><br><span class="line"><span class="string">            if (h == -1)</span></span><br><span class="line"><span class="string">                break;</span></span><br><span class="line"><span class="string">            d.push((3 &amp; c) &lt;&lt; 6 | h)</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        return d</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">&#125;)();</span></span><br><span class="line"><span class="string">//stringToBase64 stringToHex stringToBytes</span></span><br><span class="line"><span class="string">//base64ToString base64ToHex base64ToBytes</span></span><br><span class="line"><span class="string">//               hexToBase64  hexToBytes    </span></span><br><span class="line"><span class="string">// bytesToBase64 bytesToHex bytesToString</span></span><br><span class="line"><span class="string">Java.perform(function () &#123;</span></span><br><span class="line"><span class="string">    var secretKeySpec = Java.use(&#x27;javax.crypto.spec.SecretKeySpec&#x27;);</span></span><br><span class="line"><span class="string">    secretKeySpec.$init.overload(&#x27;[B&#x27;,&#x27;java.lang.String&#x27;).implementation = function (a,b) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.$init(a, b);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;算法名：&quot; + b + &quot;|Dec密钥:&quot; + bytesToString(a));</span></span><br><span class="line"><span class="string">        send(&quot;算法名：&quot; + b + &quot;|Hex密钥:&quot; + bytesToHex(a));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    var mac = Java.use(&#x27;javax.crypto.Mac&#x27;);</span></span><br><span class="line"><span class="string">    mac.getInstance.overload(&#x27;java.lang.String&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.getInstance(a);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;算法名：&quot; + a);</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    mac.update.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        this.update(a);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;update:&quot; + bytesToString(a))</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    mac.update.overload(&#x27;[B&#x27;,&#x27;int&#x27;,&#x27;int&#x27;).implementation = function (a,b,c) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        this.update(a,b,c)</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;update:&quot; + bytesToString(a) + &quot;|&quot; + b + &quot;|&quot; + c);</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    mac.doFinal.overload().implementation = function () &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.doFinal();</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;doFinal结果:&quot; + bytesToHex(result));</span></span><br><span class="line"><span class="string">        send(&quot;doFinal结果:&quot; + bytesToBase64(result));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    mac.doFinal.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.doFinal(a);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;doFinal参数:&quot; + bytesToString(a));</span></span><br><span class="line"><span class="string">        send(&quot;doFinal结果:&quot; + bytesToHex(result));</span></span><br><span class="line"><span class="string">        send(&quot;doFinal结果:&quot; + bytesToBase64(result));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">        var md = Java.use(&#x27;java.security.MessageDigest&#x27;);</span></span><br><span class="line"><span class="string">    md.getInstance.overload(&#x27;java.lang.String&#x27;,&#x27;java.lang.String&#x27;).implementation = function (a,b) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;算法名：&quot; + a);</span></span><br><span class="line"><span class="string">        return this.getInstance(a, b);</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    md.getInstance.overload(&#x27;java.lang.String&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;算法名：&quot; + a);</span></span><br><span class="line"><span class="string">        return this.getInstance(a);</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    md.update.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;update:&quot; + bytesToString(a))</span></span><br><span class="line"><span class="string">        return this.update(a);</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    md.update.overload(&#x27;[B&#x27;,&#x27;int&#x27;,&#x27;int&#x27;).implementation = function (a,b,c) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;update:&quot; + bytesToString(a) + &quot;|&quot; + b + &quot;|&quot; + c);</span></span><br><span class="line"><span class="string">        return this.update(a,b,c);</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    md.digest.overload().implementation = function () &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        var result = this.digest();</span></span><br><span class="line"><span class="string">        send(&quot;digest结果:&quot; + bytesToHex(result));</span></span><br><span class="line"><span class="string">        send(&quot;digest结果:&quot; + bytesToBase64(result));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    md.digest.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;digest参数:&quot; + bytesToString(a));</span></span><br><span class="line"><span class="string">        var result = this.digest(a);</span></span><br><span class="line"><span class="string">        send(&quot;digest结果:&quot; + bytesToHex(result));</span></span><br><span class="line"><span class="string">        send(&quot;digest结果:&quot; + bytesToBase64(result));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">        var ivParameterSpec = Java.use(&#x27;javax.crypto.spec.IvParameterSpec&#x27;);</span></span><br><span class="line"><span class="string">    ivParameterSpec.$init.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.$init(a);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;iv向量:&quot; + bytesToString(a));</span></span><br><span class="line"><span class="string">        send(&quot;iv向量:&quot; + bytesToHex(a));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    var cipher = Java.use(&#x27;javax.crypto.Cipher&#x27;);</span></span><br><span class="line"><span class="string">    cipher.getInstance.overload(&#x27;java.lang.String&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.getInstance(a);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;模式填充:&quot; + a);</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    cipher.update.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.update(a);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;update:&quot; + bytesToString(a));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    cipher.update.overload(&#x27;[B&#x27;,&#x27;int&#x27;,&#x27;int&#x27;).implementation = function (a,b,c) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.update(a,b,c);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;update:&quot; + bytesToString(a) + &quot;|&quot; + b + &quot;|&quot; + c);</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    cipher.doFinal.overload().implementation = function () &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.doFinal();</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;doFinal结果:&quot; + bytesToHex(result));</span></span><br><span class="line"><span class="string">        send(&quot;doFinal结果:&quot; + bytesToBase64(result));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    cipher.doFinal.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.doFinal(a);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;doFinal参数:&quot; + bytesToString(a));</span></span><br><span class="line"><span class="string">        send(&quot;doFinal结果:&quot; + bytesToHex(result));</span></span><br><span class="line"><span class="string">        send(&quot;doFinal结果:&quot; + bytesToBase64(result));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    var x509EncodedKeySpec = Java.use(&#x27;java.security.spec.X509EncodedKeySpec&#x27;);</span></span><br><span class="line"><span class="string">    x509EncodedKeySpec.$init.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.$init(a);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        send(&quot;RSA密钥:&quot; + bytesToBase64(a));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    var rSAPublicKeySpec = Java.use(&#x27;java.security.spec.RSAPublicKeySpec&#x27;);</span></span><br><span class="line"><span class="string">    rSAPublicKeySpec.$init.overload(&#x27;java.math.BigInteger&#x27;,&#x27;java.math.BigInteger&#x27;).implementation = function (a,b) &#123;</span></span><br><span class="line"><span class="string">        showStacks();</span></span><br><span class="line"><span class="string">        var result = this.$init(a,b);</span></span><br><span class="line"><span class="string">        send(&quot;======================================&quot;);</span></span><br><span class="line"><span class="string">        //send(&quot;RSA密钥:&quot; + bytesToBase64(a));</span></span><br><span class="line"><span class="string">        send(&quot;RSA密钥N:&quot; + a.toString(16));</span></span><br><span class="line"><span class="string">        send(&quot;RSA密钥E:&quot; + b.toString(16));</span></span><br><span class="line"><span class="string">        return result;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">&#125;);</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span>;</span><br><span class="line"> </span><br><span class="line">fw = <span class="built_in">open</span>(sys.argv[<span class="number">1</span>],<span class="string">&#x27;w+&#x27;</span>,encoding=<span class="string">&#x27;utf-8&#x27;</span>)</span><br><span class="line"> </span><br><span class="line"><span class="keyword">def</span> <span class="title function_">message</span>(<span class="params">message, data</span>):</span><br><span class="line">    <span class="keyword">if</span> message[<span class="string">&quot;type&quot;</span>] == <span class="string">&#x27;send&#x27;</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">u&quot;[*] &#123;0&#125;&quot;</span>.<span class="built_in">format</span>(message[<span class="string">&#x27;payload&#x27;</span>]))</span><br><span class="line">        fw.write(<span class="string">u&quot;[*] &#123;0&#125;\n&quot;</span>.<span class="built_in">format</span>(message[<span class="string">&#x27;payload&#x27;</span>]))</span><br><span class="line">        fw.flush()</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(message)</span><br><span class="line"> </span><br><span class="line">process = frida.get_remote_device().attach(sys.argv[<span class="number">1</span>])</span><br><span class="line">script= process.create_script(jsCode)</span><br><span class="line">script.on(<span class="string">&quot;message&quot;</span>, message)</span><br><span class="line">script.load()</span><br><span class="line">sys.stdin.read()</span><br></pre></td></tr></table></figure><h3 id="常见算法hook"><a href="#常见算法hook" class="headerlink" title="常见算法hook"></a>常见算法hook</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><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></pre></td><td class="code"><pre><span class="line">Java.perform(function () &#123;</span><br><span class="line">    var secretKeySpec = Java.use(&#x27;javax.crypto.spec.SecretKeySpec&#x27;);</span><br><span class="line">    secretKeySpec.$init.overload(&#x27;[B&#x27;, &#x27;java.lang.String&#x27;).implementation = function (a, b) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.$init(a, b);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;算法名：&quot; + b + &quot;|Dec密钥:&quot; + bytesToString(a));</span><br><span class="line">        send(&quot;算法名：&quot; + b + &quot;|Hex密钥:&quot; + bytesToHex(a));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    var mac = Java.use(&#x27;javax.crypto.Mac&#x27;);</span><br><span class="line">    mac.getInstance.overload(&#x27;java.lang.String&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.getInstance(a);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;算法名：&quot; + a);</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    mac.update.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        this.update(a);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;update:&quot; + bytesToString(a))</span><br><span class="line">    &#125;</span><br><span class="line">    mac.update.overload(&#x27;[B&#x27;, &#x27;int&#x27;, &#x27;int&#x27;).implementation = function (a, b, c) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        this.update(a, b, c)</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;update:&quot; + bytesToString(a) + &quot;|&quot; + b + &quot;|&quot; + c);</span><br><span class="line">    &#125;</span><br><span class="line">    mac.doFinal.overload().implementation = function () &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.doFinal();</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;doFinal结果:&quot; + bytesToHex(result));</span><br><span class="line">        send(&quot;doFinal结果:&quot; + bytesToBase64(result));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    mac.doFinal.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.doFinal(a);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;doFinal参数:&quot; + bytesToString(a));</span><br><span class="line">        send(&quot;doFinal结果:&quot; + bytesToHex(result));</span><br><span class="line">        send(&quot;doFinal结果:&quot; + bytesToBase64(result));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    var md = Java.use(&#x27;java.security.MessageDigest&#x27;);</span><br><span class="line">    md.getInstance.overload(&#x27;java.lang.String&#x27;, &#x27;java.lang.String&#x27;).implementation = function (a, b) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;算法名：&quot; + a);</span><br><span class="line">        return this.getInstance(a, b);</span><br><span class="line">    &#125;</span><br><span class="line">    md.getInstance.overload(&#x27;java.lang.String&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;算法名：&quot; + a);</span><br><span class="line">        return this.getInstance(a);</span><br><span class="line">    &#125;</span><br><span class="line">    md.update.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;update:&quot; + bytesToString(a))</span><br><span class="line">        return this.update(a);</span><br><span class="line">    &#125;</span><br><span class="line">    md.update.overload(&#x27;[B&#x27;, &#x27;int&#x27;, &#x27;int&#x27;).implementation = function (a, b, c) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;update:&quot; + bytesToString(a) + &quot;|&quot; + b + &quot;|&quot; + c);</span><br><span class="line">        return this.update(a, b, c);</span><br><span class="line">    &#125;</span><br><span class="line">    md.digest.overload().implementation = function () &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        var result = this.digest();</span><br><span class="line">        send(&quot;digest结果:&quot; + bytesToHex(result));</span><br><span class="line">        send(&quot;digest结果:&quot; + bytesToBase64(result));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    md.digest.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;digest参数:&quot; + bytesToString(a));</span><br><span class="line">        var result = this.digest(a);</span><br><span class="line">        send(&quot;digest结果:&quot; + bytesToHex(result));</span><br><span class="line">        send(&quot;digest结果:&quot; + bytesToBase64(result));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    var ivParameterSpec = Java.use(&#x27;javax.crypto.spec.IvParameterSpec&#x27;);</span><br><span class="line">    ivParameterSpec.$init.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.$init(a);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;iv向量:&quot; + bytesToString(a));</span><br><span class="line">        send(&quot;iv向量:&quot; + bytesToHex(a));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    var cipher = Java.use(&#x27;javax.crypto.Cipher&#x27;);</span><br><span class="line">    cipher.getInstance.overload(&#x27;java.lang.String&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.getInstance(a);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;模式填充:&quot; + a);</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    cipher.update.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.update(a);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;update:&quot; + bytesToString(a));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    cipher.update.overload(&#x27;[B&#x27;, &#x27;int&#x27;, &#x27;int&#x27;).implementation = function (a, b, c) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.update(a, b, c);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;update:&quot; + bytesToString(a) + &quot;|&quot; + b + &quot;|&quot; + c);</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    cipher.doFinal.overload().implementation = function () &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.doFinal();</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;doFinal结果:&quot; + bytesToHex(result));</span><br><span class="line">        send(&quot;doFinal结果:&quot; + bytesToBase64(result));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    cipher.doFinal.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.doFinal(a);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;doFinal参数:&quot; + bytesToString(a));</span><br><span class="line">        send(&quot;doFinal结果:&quot; + bytesToHex(result));</span><br><span class="line">        send(&quot;doFinal结果:&quot; + bytesToBase64(result));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    var x509EncodedKeySpec = Java.use(&#x27;java.security.spec.X509EncodedKeySpec&#x27;);</span><br><span class="line">    x509EncodedKeySpec.$init.overload(&#x27;[B&#x27;).implementation = function (a) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.$init(a);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        send(&quot;RSA密钥:&quot; + bytesToBase64(a));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">    var rSAPublicKeySpec = Java.use(&#x27;java.security.spec.RSAPublicKeySpec&#x27;);</span><br><span class="line">    rSAPublicKeySpec.$init.overload(&#x27;java.math.BigInteger&#x27;, &#x27;java.math.BigInteger&#x27;).implementation = function (a, b) &#123;</span><br><span class="line">        showStacks();</span><br><span class="line">        var result = this.$init(a, b);</span><br><span class="line">        send(&quot;======================================&quot;);</span><br><span class="line">        //send(&quot;RSA密钥:&quot; + bytesToBase64(a));</span><br><span class="line">        send(&quot;RSA密钥N:&quot; + a.toString(16));</span><br><span class="line">        send(&quot;RSA密钥E:&quot; + b.toString(16));</span><br><span class="line">        return result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Frida-学习笔记&quot;&gt;&lt;a href=&quot;#Frida-学习笔记&quot; class=&quot;headerlink&quot; title=&quot;Frida 学习笔记&quot;&gt;&lt;/a&gt;Frida 学习笔记&lt;/h1&gt;&lt;h2 id=&quot;环境开发&quot;&gt;&lt;a href=&quot;#环境开发&quot; class=&quot;head</summary>
      
    
    
    
    <category term="爬虫" scheme="https://blog.ifan.host/categories/%E7%88%AC%E8%99%AB/"/>
    
    <category term="frida" scheme="https://blog.ifan.host/categories/%E7%88%AC%E8%99%AB/frida/"/>
    
    
    <category term="爬虫" scheme="https://blog.ifan.host/tags/%E7%88%AC%E8%99%AB/"/>
    
    <category term="frida" scheme="https://blog.ifan.host/tags/frida/"/>
    
  </entry>
  
  <entry>
    <title>VS Code 开发配置</title>
    <link href="https://blog.ifan.host/2022/08/10/tools/development-tool/vscode-config/"/>
    <id>https://blog.ifan.host/2022/08/10/tools/development-tool/vscode-config/</id>
    <published>2022-08-10T01:00:00.000Z</published>
    <updated>2024-10-29T07:20:39.682Z</updated>
    
    <content type="html"><![CDATA[<h2 id="tasks-json"><a href="#tasks-json" class="headerlink" title="tasks.json"></a>tasks.json</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="comment">// See https://go.microsoft.com/fwlink/?LinkId=733558</span></span><br><span class="line">    <span class="comment">// for the documentation about the tasks.json format</span></span><br><span class="line">    <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;tasks&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;label&quot;</span><span class="punctuation">:</span> <span class="string">&quot;任务名称&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;shell&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;command&quot;</span><span class="punctuation">:</span> <span class="string">&quot;$&#123;config:python.pythonPath&#125;&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;args&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                <span class="string">&quot;$&#123;workspaceFolder&#125;/manager.py&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="string">&quot;-web&quot;</span></span><br><span class="line">            <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;presentation&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;echo&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;reveal&quot;</span><span class="punctuation">:</span> <span class="string">&quot;always&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;focus&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;panel&quot;</span><span class="punctuation">:</span> <span class="string">&quot;shared&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;showReuseMessage&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;clear&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;problemMatcher&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="punctuation">]</span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Python Debugger: bx.py with Arguments&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;debugpy&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;request&quot;</span><span class="punctuation">:</span> <span class="string">&quot;launch&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;program&quot;</span><span class="punctuation">:</span> <span class="string">&quot;$&#123;workspaceFolder&#125;/manager.py&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;console&quot;</span><span class="punctuation">:</span> <span class="string">&quot;integratedTerminal&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;args&quot;</span><span class="punctuation">:</span> <span class="string">&quot;$&#123;command:pickArgs&#125;&quot;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h2 id="sftp-json"><a href="#sftp-json" class="headerlink" title="sftp.json"></a>sftp.json</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sftp name&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;host&quot;</span><span class="punctuation">:</span> <span class="string">&quot;172.x.x.x&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;protocol&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sftp&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;port&quot;</span><span class="punctuation">:</span> <span class="number">22</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;username&quot;</span><span class="punctuation">:</span> <span class="string">&quot;username&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;password&quot;</span><span class="punctuation">:</span> <span class="string">&quot;password&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;remotePath&quot;</span><span class="punctuation">:</span> <span class="string">&quot;远程地址&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;uploadOnSave&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;useTempFile&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;openSsh&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;ignore&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">            <span class="string">&quot;.idea&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="string">&quot;.vscode&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="string">&quot;.git&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="string">&quot;.DS_Store&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="string">&quot;venv&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="string">&quot;__pycache__&quot;</span></span><br><span class="line">        <span class="punctuation">]</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">]</span></span><br></pre></td></tr></table></figure><h2 id="settings-json"><a href="#settings-json" class="headerlink" title="settings.json"></a>settings.json</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;editor.fontSize&quot;</span><span class="punctuation">:</span> <span class="number">18</span><span class="punctuation">,</span> <span class="comment">//编辑器字体大小</span></span><br><span class="line">    <span class="attr">&quot;workbench.colorTheme&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Winter is Coming (Dark Blue)&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;workbench.iconTheme&quot;</span><span class="punctuation">:</span> <span class="string">&quot;vscode-icons&quot;</span><span class="punctuation">,</span> <span class="comment">//vscode文件图标主题</span></span><br><span class="line">    <span class="attr">&quot;go.formatTool&quot;</span><span class="punctuation">:</span> <span class="string">&quot;goimports&quot;</span><span class="punctuation">,</span> <span class="comment">//golang格式化工具</span></span><br><span class="line">    <span class="attr">&quot;editor.defaultFormatter&quot;</span><span class="punctuation">:</span> <span class="string">&quot;esbenp.prettier-vscode&quot;</span><span class="punctuation">,</span> <span class="comment">//编辑器格式化工具</span></span><br><span class="line">    <span class="attr">&quot;[javascript]&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;editor.defaultFormatter&quot;</span><span class="punctuation">:</span> <span class="string">&quot;rvest.vs-code-prettier-eslint&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span> <span class="comment">//javascript格式化工具</span></span><br><span class="line">    <span class="attr">&quot;[vue]&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;editor.defaultFormatter&quot;</span><span class="punctuation">:</span> <span class="string">&quot;octref.vetur&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span> <span class="comment">//vue格式化工具</span></span><br><span class="line">    <span class="attr">&quot;[go]&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;editor.insertSpaces&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;editor.formatOnSave&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;editor.codeActionsOnSave&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;source.organizeImports&quot;</span><span class="punctuation">:</span> <span class="string">&quot;explicit&quot;</span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;editor.defaultFormatter&quot;</span><span class="punctuation">:</span> <span class="string">&quot;golang.go&quot;</span><span class="punctuation">,</span> <span class="comment">//格式化器</span></span><br><span class="line">        <span class="attr">&quot;editor.suggest.snippetsPreventQuickSuggestions&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;[python]&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="comment">// Python 格式化工具</span></span><br><span class="line">        <span class="attr">&quot;editor.defaultFormatter&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ms-python.black-formatter&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;editor.formatOnSave&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="comment">// &quot;black-formatter.args&quot;: [ // black 格式化参数</span></span><br><span class="line">    <span class="comment">//     &quot;--line-length&quot;,</span></span><br><span class="line">    <span class="comment">//     &quot;200&quot;</span></span><br><span class="line">    <span class="comment">// ],</span></span><br><span class="line">    <span class="attr">&quot;editor.insertSpaces&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;workbench.editor.enablePreview&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span> <span class="comment">//打开文件不覆盖</span></span><br><span class="line">    <span class="attr">&quot;search.followSymlinks&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span> <span class="comment">//关闭rg.exe进程</span></span><br><span class="line">    <span class="attr">&quot;editor.minimap.enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span> <span class="comment">//关闭快速预览</span></span><br><span class="line">    <span class="attr">&quot;files.autoSave&quot;</span><span class="punctuation">:</span> <span class="string">&quot;afterDelay&quot;</span><span class="punctuation">,</span> <span class="comment">//编辑自动保存</span></span><br><span class="line">    <span class="attr">&quot;editor.lineNumbers&quot;</span><span class="punctuation">:</span> <span class="string">&quot;on&quot;</span><span class="punctuation">,</span> <span class="comment">//开启行数提示</span></span><br><span class="line">    <span class="attr">&quot;editor.quickSuggestions&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="comment">//开启自动显示建议</span></span><br><span class="line">        <span class="attr">&quot;other&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;comments&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;strings&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;editor.tabSize&quot;</span><span class="punctuation">:</span> <span class="number">4</span><span class="punctuation">,</span> <span class="comment">//制表符符号eslint</span></span><br><span class="line">    <span class="attr">&quot;editor.formatOnSave&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span> <span class="comment">//每次保存自动格式化</span></span><br><span class="line">    <span class="attr">&quot;prettier.eslintIntegration&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span> <span class="comment">//让prettier使用eslint的代码格式进行校验</span></span><br><span class="line">    <span class="attr">&quot;prettier.semi&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span> <span class="comment">//去掉代码结尾的分号</span></span><br><span class="line">    <span class="attr">&quot;prettier.singleQuote&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span> <span class="comment">//使用单引号替代双引号</span></span><br><span class="line">    <span class="attr">&quot;javascript.format.insertSpaceBeforeFunctionParenthesis&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span> <span class="comment">//让函数(名)和后面的括号之间加个空格</span></span><br><span class="line">    <span class="attr">&quot;vetur.format.defaultFormatter.html&quot;</span><span class="punctuation">:</span> <span class="string">&quot;js-beautify-html&quot;</span><span class="punctuation">,</span> <span class="comment">//格式化.vue中html</span></span><br><span class="line">    <span class="attr">&quot;vetur.format.defaultFormatter.js&quot;</span><span class="punctuation">:</span> <span class="string">&quot;vscode-typescript&quot;</span><span class="punctuation">,</span> <span class="comment">//让vue中的js按编辑器自带的ts格式进行格式化</span></span><br><span class="line">    <span class="attr">&quot;vetur.format.defaultFormatterOptions&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;js-beautify-html&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;wrap_attributes&quot;</span><span class="punctuation">:</span> <span class="string">&quot;force-aligned&quot;</span> <span class="comment">//属性强制折行对齐</span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;prettier&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;semi&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;singleQuote&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;vscode-typescript&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;semi&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;singleQuote&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;eslint.validate&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="string">&quot;vue&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="comment">// &quot;javascript&quot;,</span></span><br><span class="line">        <span class="string">&quot;typescript&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;typescriptreact&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="string">&quot;html&quot;</span></span><br><span class="line">    <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;editor.codeActionsOnSave&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;source.fixAll.eslint&quot;</span><span class="punctuation">:</span> <span class="string">&quot;explicit&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;editor.suggestSelection&quot;</span><span class="punctuation">:</span> <span class="string">&quot;first&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;vsintellicode.modify.editor.suggestSelection&quot;</span><span class="punctuation">:</span> <span class="string">&quot;automaticallyOverrodeDefaultValue&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;editor.fontLigatures&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;terminal.integrated.tabs.enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;terminal.integrated.env.osx&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="comment">// 命令行环境变量</span></span><br><span class="line">        <span class="attr">&quot;PYTHONPATH&quot;</span><span class="punctuation">:</span> <span class="string">&quot;$PYTHONPATH:$&#123;workspaceRoot&#125;&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;code-runner.runInTerminal&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span> <span class="comment">// 在终端运行方法</span></span><br><span class="line">    <span class="attr">&quot;code-runner.cwd&quot;</span><span class="punctuation">:</span> <span class="string">&quot;$&#123;workspaceRoot&#125;&quot;</span><span class="punctuation">,</span> <span class="comment">// 运行时的父地址</span></span><br><span class="line">    <span class="attr">&quot;rest-client.environmentVariables&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="comment">// rest-client 使用的公共参数</span></span><br><span class="line">        <span class="attr">&quot;$shared&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;tasks-json&quot;&gt;&lt;a href=&quot;#tasks-json&quot; class=&quot;headerlink&quot; title=&quot;tasks.json&quot;&gt;&lt;/a&gt;tasks.json&lt;/h2&gt;&lt;figure class=&quot;highlight json&quot;&gt;&lt;table&gt;&lt;tr</summary>
      
    
    
    
    <category term="工具" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="编程工具" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/%E7%BC%96%E7%A8%8B%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="工具" scheme="https://blog.ifan.host/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="编程工具" scheme="https://blog.ifan.host/tags/%E7%BC%96%E7%A8%8B%E5%B7%A5%E5%85%B7/"/>
    
  </entry>
  
  <entry>
    <title>地铁线路图</title>
    <link href="https://blog.ifan.host/2022/08/09/tools/Metro/"/>
    <id>https://blog.ifan.host/2022/08/09/tools/Metro/</id>
    <published>2022-08-09T01:00:00.000Z</published>
    <updated>2023-12-25T05:56:09.182Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/images/tools/%E5%8C%97%E4%BA%AC%E5%9C%B0%E9%93%81.gif"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;&lt;img src=&quot;/images/tools/%E5%8C%97%E4%BA%AC%E5%9C%B0%E9%93%81.gif&quot;&gt;&lt;/p&gt;
</summary>
      
    
    
    
    <category term="工具" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="生活" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/%E7%94%9F%E6%B4%BB/"/>
    
    
    <category term="工具" scheme="https://blog.ifan.host/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="生活" scheme="https://blog.ifan.host/tags/%E7%94%9F%E6%B4%BB/"/>
    
  </entry>
  
  <entry>
    <title>京东京造键位图</title>
    <link href="https://blog.ifan.host/2022/08/09/tools/keyboard/"/>
    <id>https://blog.ifan.host/2022/08/09/tools/keyboard/</id>
    <published>2022-08-09T00:56:00.000Z</published>
    <updated>2023-12-25T05:56:09.184Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/images/tools/v2-1355cb41278f2f529049add1a01094a6.jpeg"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;&lt;img src=&quot;/images/tools/v2-1355cb41278f2f529049add1a01094a6.jpeg&quot;&gt;&lt;/p&gt;
</summary>
      
    
    
    
    <category term="工具" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="生活" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/%E7%94%9F%E6%B4%BB/"/>
    
    
    <category term="工具" scheme="https://blog.ifan.host/tags/%E5%B7%A5%E5%85%B7/"/>
    
    <category term="生活" scheme="https://blog.ifan.host/tags/%E7%94%9F%E6%B4%BB/"/>
    
  </entry>
  
  <entry>
    <title>Typora 修改源码模式和预览模式的宽度</title>
    <link href="https://blog.ifan.host/2022/08/03/tools/typora/"/>
    <id>https://blog.ifan.host/2022/08/03/tools/typora/</id>
    <published>2022-08-03T00:56:00.000Z</published>
    <updated>2023-12-25T05:56:09.185Z</updated>
    
    <content type="html"><![CDATA[<h2 id="修改源码模式和预览模式的宽度"><a href="#修改源码模式和预览模式的宽度" class="headerlink" title="修改源码模式和预览模式的宽度"></a>修改源码模式和预览模式的宽度</h2><h3 id="源码模式"><a href="#源码模式" class="headerlink" title="源码模式"></a>源码模式</h3><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">/Applications/Typora.app/Contents/Resources/TypeMark/style/base-control.css</span><br></pre></td></tr></table></figure><p>找到<code>.CodeMirror-lines</code>下的<code>max-width</code>将其修改为<code>2048</code></p><p><img src="/images/tools/typora/20220803.jpg"></p><h3 id="预览模式"><a href="#预览模式" class="headerlink" title="预览模式"></a>预览模式</h3><p>找到【外观】、【打开主题文件夹】、【找到自己使用的主题】</p><p>搜索 <code>#write</code> ，修改其属性 <code>max-width</code> 的值改为你想要设置的宽度</p><blockquote><p>都需要关闭之后重新打开才能生效</p></blockquote>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;修改源码模式和预览模式的宽度&quot;&gt;&lt;a href=&quot;#修改源码模式和预览模式的宽度&quot; class=&quot;headerlink&quot; title=&quot;修改源码模式和预览模式的宽度&quot;&gt;&lt;/a&gt;修改源码模式和预览模式的宽度&lt;/h2&gt;&lt;h3 id=&quot;源码模式&quot;&gt;&lt;a href=&quot;#源</summary>
      
    
    
    
    <category term="工具" scheme="https://blog.ifan.host/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="工具" scheme="https://blog.ifan.host/tags/%E5%B7%A5%E5%85%B7/"/>
    
  </entry>
  
  <entry>
    <title>大数据 Hbase 列族的配置</title>
    <link href="https://blog.ifan.host/2022/07/10/bigdata/hbase/rank-family/"/>
    <id>https://blog.ifan.host/2022/07/10/bigdata/hbase/rank-family/</id>
    <published>2022-07-10T06:25:00.000Z</published>
    <updated>2023-12-25T05:56:09.157Z</updated>
    
    <content type="html"><![CDATA[<h1 id="列族的配置"><a href="#列族的配置" class="headerlink" title="列族的配置"></a>列族的配置</h1><h2 id="一、创建表及属性查看"><a href="#一、创建表及属性查看" class="headerlink" title="一、创建表及属性查看"></a>一、创建表及属性查看</h2><p>创建一个测试表 test，列族为 cf：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">create &#x27;test&#x27;, &#123;NAME =&gt; &#x27;cf&#x27;&#125;</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></pre></td><td class="code"><pre><span class="line">hbase &gt; describe &#x27;test&#x27;</span><br><span class="line"></span><br><span class="line">&#123;</span><br><span class="line">NAME =&gt; &#x27;cf&#x27;, </span><br><span class="line">BLOOMFILTER =&gt; &#x27;ROW&#x27;, </span><br><span class="line">VERSIONS =&gt; &#x27;1&#x27;, </span><br><span class="line">IN_MEMORY =&gt; &#x27;false&#x27;, </span><br><span class="line">KEEP_DELETED_CELLS =&gt; &#x27;FALSE&#x27;, </span><br><span class="line">DATA_BLOCK_ENCODING =&gt; &#x27;NONE&#x27;, </span><br><span class="line">TTL =&gt; &#x27;FOREVER&#x27;, </span><br><span class="line">COMPRESSION =&gt; &#x27;GZ&#x27;, </span><br><span class="line">MIN_VERSIONS =&gt; &#x27;0&#x27;, </span><br><span class="line">BLOCKCACHE =&gt; &#x27;true&#x27;,</span><br><span class="line">BLOCKSIZE =&gt; &#x27;65536&#x27;, </span><br><span class="line">REPLICATION_SCOPE =&gt; &#x27;0&#x27;</span><br><span class="line">&#125;   </span><br></pre></td></tr></table></figure><h2 id="二、列族属性配置"><a href="#二、列族属性配置" class="headerlink" title="二、列族属性配置"></a>二、列族属性配置</h2><h3 id="2-1、版本数量（VERSIONS）"><a href="#2-1、版本数量（VERSIONS）" class="headerlink" title="2.1、版本数量（VERSIONS）"></a>2.1、版本数量（VERSIONS）</h3><p>HBase 一切操作均为更新，Hbase Put 操作不会去覆盖一个值，只会在后面追加写，用时间戳（版本号）来区分，HBase 版本维度<strong>按递减顺序存储</strong>，以便在从存储文件读取时，首先找到最近的值；Hbase Delete 操作也不是真正删除了记录，而是放置了一个墓碑标记，过早的版本会在执行 Major Compaction 时真正删除。</p><p>0.96版本默认是3个， 0.98版本之后是1， 要根据业务来划分，版本是历史记录，版本增多意味空间消耗。</p><p>插入数据的时候，版本默认是当前时间；查询的时候可以指定要获取的版本个数 <code>get &#39;test&#39;, &#123; COLUMN =&gt; &#39;cf&#39;, VERSIONS =&gt; 2&#125;</code>；</p><p>获取多个版本的时候，<strong>多个数据是按照时间戳倒序排序</strong>，也可以通过这个特性，来保存类似于事件发生的数据，查询时间历史的时候，拿出来的数据是按照时间排好序，如果要拿最新的事件，不指定版本即可。</p><p>版本的时间戳，也可以自定义，不使用默认生成的时间戳，可以自己指定业务相关的ID。</p><p><strong>使用方法:</strong></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">create &#x27;test1&#x27;, &#123;NAME =&gt; &#x27;cf&#x27;, VERSIONS =&gt; 3&#125;</span><br></pre></td></tr></table></figure><p><strong>更改版本号：</strong></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">alter &#x27;test1&#x27;, NAME =&gt; &#x27;cf&#x27;, VERSIONS =&gt; 5</span><br></pre></td></tr></table></figure><h3 id="2-2、存活时间（TTL）"><a href="#2-2、存活时间（TTL）" class="headerlink" title="2.2、存活时间（TTL）"></a>2.2、存活时间（TTL）</h3><p>TTL 全称是 Time To Live，ColumnFamilies 可以设置 TTL(单位是s)，HBase 会自动检查 TTL 值是否达到上限，如果 TTL 达到上限后自动删除行。当然真正删除是在<strong>Major Compaction过程</strong>中执行的。</p><p>试验一下：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><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">alter &#x27;test1&#x27;, NAME =&gt; &#x27;cf&#x27;, VERSIONS =&gt; 5, TTL =&gt; 10</span><br><span class="line"></span><br><span class="line">put &#x27;test1&#x27;, &#x27;0001&#x27;, &#x27;cf:name&#x27;, &#x27;james&#x27;</span><br><span class="line"></span><br><span class="line">get &#x27;test1&#x27;, &#x27;0001&#x27;</span><br></pre></td></tr></table></figure><p>发现过 10s 后数据已经删除。</p><h3 id="2-3、最小版本数（MIN-VERSIONS-）"><a href="#2-3、最小版本数（MIN-VERSIONS-）" class="headerlink" title="2.3、最小版本数（MIN_VERSIONS ）"></a>2.3、最小版本数（MIN_VERSIONS ）</h3><p>如果 <strong>HBase 中的表设置了 TTL 的时候</strong>，MIN_VERSIONS 才会起作用。</p><p>每个列族可以设置最小版本数，最小版本数缺省值是0，表示禁用该特性。最小版本数参数和存活时间是一起使用的，允许配置“<strong>如保存最后T秒有价值的数据，最多N个版本，但最少M个版本</strong>”（M是最小版本，M&lt;N）。</p><ul><li>MIN_VERSION &gt; 0时：Cell 至少有 MIN_VERSION 个最新版本会保留下来；</li><li>MIN_VERSION &#x3D; 0时：Cell 中的数据超过TTL时间时，全部清空，不保留最低版本。</li></ul><h3 id="2-4、保留删除的单元格（KEEP-DELETED-CELLS）"><a href="#2-4、保留删除的单元格（KEEP-DELETED-CELLS）" class="headerlink" title="2.4、保留删除的单元格（KEEP_DELETED_CELLS）"></a>2.4、保留删除的单元格（KEEP_DELETED_CELLS）</h3><p>HBase 的<code>delete</code> 命令，并不是真的删除数据，而是设置一个标记（<code>delete marker</code>）。用户在检索数据的时候，会过滤掉这些标示的数据。<br>该属性可以设置为 <code>FALSE</code>（默认）、<code>TRUE</code>、<code>TTL</code>。</p><p>可以从 java API 源码中看到：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> <span class="title class_">KeepDeletedCells</span> &#123;</span><br><span class="line">  <span class="comment">/** Deleted Cells are not retained. */</span></span><br><span class="line">  FALSE,</span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * Deleted Cells are retained until they are removed by other means</span></span><br><span class="line"><span class="comment">   * such TTL or VERSIONS.</span></span><br><span class="line"><span class="comment">   * If no TTL is specified or no new versions of delete cells are</span></span><br><span class="line"><span class="comment">   * written, they are retained forever.</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  TRUE,</span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * Deleted Cells are retained until the delete marker expires due to TTL.</span></span><br><span class="line"><span class="comment">   * This is useful when TTL is combined with MIN_VERSIONS and one</span></span><br><span class="line"><span class="comment">   * wants to keep a minimum number of versions around but at the same</span></span><br><span class="line"><span class="comment">   * time remove deleted cells after the TTL.</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  TTL;</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">static</span> KeepDeletedCells <span class="title function_">getValue</span><span class="params">(String val)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> valueOf(val.toUpperCase());</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>FALSE：不保留删除的单元格。</li><li>TRUE：删除的单元格会保留，超期（TTL）或者数据版本数超过 VERSIONS 设置的值才会被删除；如果没有指定 TTL 或没有超出VERSIONS 值，则会永久保留它们。</li><li>TTL：超期（TTL）才会删除，当 TTL 与 MIN_VERSIONS 结合使用时，会删除过期后的数据，但是同时会保留最少数量的版本。</li></ul><h3 id="2-5、数据块大小（BLOCKSIZE-）"><a href="#2-5、数据块大小（BLOCKSIZE-）" class="headerlink" title="2.5、数据块大小（BLOCKSIZE ）"></a>2.5、数据块大小（BLOCKSIZE ）</h3><p>HBase 默认的块大小是 64kb，不同于 HDFS 默认 64MB 的块大小。</p><p>数据块索引存储每个 HFile 数据块的起始键，数据块大小配置会影响数据块索引的大小。数据块越小，数据块索引越大，因而占用的内存空间越大。</p><p>同时，加载进内存的数据块更小，随机查找性能更好，因为一旦找到了行键所在的块，接下来就会定位对应的单元格，使用更小的数据块效率更优。</p><p>但是如果需要更好的顺序扫描性能，那么一次能够加载更多 HFile 数据进入内存则更为合理，这意味数据块大小应该设置更大的值。相应索引将变小，将在随机读性能上付出代价。</p><p><strong>对于不同的业务数据，块大小的合理设置对读写性能有很大的影响。如果业务请求以 Get 请求为主，可以考虑将块大小设置较小；如果以 Scan 请求为主，可以将块大小调大；默认的 64K 块大小是在 Scan 和 Get 之间取得的一个平衡。</strong></p><p>默认块大小适用于多种数据使用模式，调整块大小是比较高级的操作。配置错误将对性能产生负面影响。因此建议在调整之后进行测试，根据测试结果决定是否可以线上使用。</p><h3 id="2-6、块缓存（BLOCKCACHE）"><a href="#2-6、块缓存（BLOCKCACHE）" class="headerlink" title="2.6、块缓存（BLOCKCACHE）"></a>2.6、块缓存（BLOCKCACHE）</h3><p>默认是 true。缓存是内存存储，HBase 使用块缓存将最近使用的块加载到内存中。块缓存会根据<strong>最近最久未使用（LRU）</strong>的规则删除数据块。</p><p>如果使用场景是经常顺序访问 Scan 或者很少被访问，可以关闭列族的缓存。列族缓存默认是打开的。</p><h3 id="2-7、激进缓存（IN-MEMORY）"><a href="#2-7、激进缓存（IN-MEMORY）" class="headerlink" title="2.7、激进缓存（IN_MEMORY）"></a>2.7、激进缓存（IN_MEMORY）</h3><p>HBase 可以选择一个列族赋予更高的优先级缓存，激进缓存（表示优先级更高），<code>IN_MEMORY</code> 默认是false。</p><p>如果设置为true，HBase 会尝试将整个列族保存在内存中，只有在需要保存是才会持久化写入磁盘。但是在运行时 HBase 会尝试将整张表加载到内存里。</p><p>这个参数通常适合较小的列族。</p><h3 id="2-8、压缩（COMPRESSION）"><a href="#2-8、压缩（COMPRESSION）" class="headerlink" title="2.8、压缩（COMPRESSION）"></a>2.8、压缩（COMPRESSION）</h3><p>数据压缩是 HBase 提供的一个特性，HBase 在写入数据块到 HDFS 之前会首<strong>先对数据块进行压缩，再落盘</strong>，从而可以减少磁盘空间使用量。</p><p>而在读数据的时候首先从 HDFS 中加载出 block 块之后<strong>进行解压缩，然后再缓存到BlockCache</strong>，最后返回给用户。</p><p>写路径和读路径分别如下：</p><ul><li><strong>写路径</strong>： <em>Finish DataBlock</em> –&gt; <em>Encoding KVs</em> –&gt; <strong>Compress DataBlock</strong> –&gt; <em>Flush</em></li><li><strong>读路径</strong>： <em>Read Block From Disk</em> –&gt; <strong>DeCompress DataBlock</strong> –&gt; <em>Cache DataBlock</em> –&gt; <em>Decoding Scan KVs</em></li></ul><p>压缩可以<strong>节省空间</strong>，但读写数据会<strong>增加CPU负载</strong>，默认为 <strong>NONE</strong>，不使用用压缩，HBase 目前提供了三种常用的压缩方式： <strong>GZip, LZO, Snappy</strong>：</p><ol><li>GZIP 的压缩率最高，但是 CPU 密集型的，对 CPU 的消耗比其他算法要多，压缩和解压速度也慢；</li><li>LZO 的压缩率居中，比 GZIP 要低一些，但是压缩和解压速度明显要比GZIP 快很多，其中解压速度快的更多；</li><li>Snappy 的压缩率最低，而压缩和解压速度要稍微比 LZO 要快一些。</li></ol><p>综合来看，<strong>Snappy</strong> 的压缩率最低，但是编解码速率最高，对 CPU 的消耗也最小，目前一般建议使用 <strong>Snappy</strong>。</p><h3 id="2-9、布隆过滤器（BLOOMFILTER）"><a href="#2-9、布隆过滤器（BLOOMFILTER）" class="headerlink" title="2.9、布隆过滤器（BLOOMFILTER）"></a>2.9、布隆过滤器（BLOOMFILTER）</h3><p>布隆过滤器用自己的算法，实现了<strong>快速的检索一个元素是否在一个较大的元素列表之中</strong>。</p><p>它的基本思想是：当一个元素被加入集合时，通过 K 个散列函数将这个元素映射成一个位数组中的 K 个点，把它们置为1；检索时，只要看看这些点是不是都是1 就（大约）知道集合中有没有它了——<strong>如果这些点有任何一个0，则被检元素一定不在，如果都是1，则被检元素很可能在</strong>。</p><p><em>它的优点是空间效率和查询时间都远远超过一般的算法，缺点是有一定的误识别率和删除困难使用了Hash算法，必然会存在极限巧合下的 hash 碰撞，会将不存在的数据认为是存在的。但是存在的数据一定是可以正确判断的。</em></p><p>HBase 中的 BloomFilter 主要用来过滤不存在待检索 RowKey 或者 Row-Col 的 HFile 文件，避免无用的 IO 操作。它可以判断 HFile 文件中是否可能存在待检索的KV，如果不存在，就可以不用消耗 IO 打开文件进行 seek。<strong>通过设置 BloomFilter 可以提升随机读写的性能。</strong></p><p>BloomFilter 是一个列族级别的配置属性，如果在表中设置了BloomFilter，那么HBase 会在生成 StoreFile 时包含一份 BloomFilter 结构的数据，称其为<code>MetaBlock</code> ，和 <code>DataBlock</code> (真实KeyValue数据)一起由 LRUBlockCache 维护。所以开启 BloomFilter 会有一定的存储即内存 Cache 的开销。</p><p>BloomFilter 取值有两个，<code>row</code> 和<code>rowcol</code>，需要根据业务来确定具体使用哪种。</p><ul><li>如果业务大多数随机查询时仅仅使用 row 作为查询条件，BloomFilter 设置为row；</li><li>如果大多数随机查询使用 row+cf 作为查询条件，BloomFilter 需要设置为rowcol；</li><li>如果不确定查询类型，建议设置为 row。</li></ul><h3 id="2-10、数据块编码（DATA-BLOCK-ENCODING）"><a href="#2-10、数据块编码（DATA-BLOCK-ENCODING）" class="headerlink" title="2.10、数据块编码（DATA_BLOCK_ENCODING）"></a>2.10、数据块编码（DATA_BLOCK_ENCODING）</h3><p>除了数据压缩之外，HBase 还提供了数据编码功能。</p><p>和压缩一样，数据在落盘之前首先会对 KV 数据进行编码；但又<strong>和压缩不同，数据块在缓存前并没有执行解码</strong>。因此即使后续<strong>命中缓存的查询是编码的数据块，需要解码后才能获取到具体的 KV 数据</strong>。</p><p>和不编码情况相比，编码后相同数据 block 块占用内存更少，即<strong>内存利用率更高</strong>，但是读取的时候需要解码，又不利于读性能，在内存不足的情况下，可以压榨 CPU 字段，换区更多的缓存数据。</p><p>HBase目前提供了四种常用的编码方式： <strong>Prefix_Tree</strong>、 Diff 、 Fast_Diff 、Prefix。</p><p>写路径和读路径分别如下：</p><ul><li><strong>写路径</strong>： <em>Finish DataBlock</em> –&gt; <strong>Encoding KVs</strong> –&gt; <em>Compress DataBlock</em> –&gt; <em>Flush</em></li><li><strong>读路径</strong>： <em>Read Block From Disk</em> –&gt; <em>DeCompress DataBlock</em> –&gt; <em>Cache DataBlock</em> –&gt; <strong>Decoding Scan KVs</strong></li></ul><h3 id="2-11、复制范围（REPLICATION-SCOPE-）"><a href="#2-11、复制范围（REPLICATION-SCOPE-）" class="headerlink" title="2.11、复制范围（REPLICATION_SCOPE ）"></a>2.11、复制范围（REPLICATION_SCOPE ）</h3><p>HBase 提供了跨级群同步的功能，本地集群的数据更新可以及时同步到其他集群。复制范围（replication scope）的参数默认为0，表示复制功能处于关闭状态。</p><h2 id="三、列族设置"><a href="#三、列族设置" class="headerlink" title="三、列族设置"></a>三、列族设置</h2><h3 id="3-1、列族数量"><a href="#3-1、列族数量" class="headerlink" title="3.1、列族数量"></a>3.1、列族数量</h3><p><strong>不要在一张表中定义太多的列族。</strong></p><p>目前 HBase 并不能很好的处理 2~3 以上的列族，<code>flush</code>和<code>compaction</code> 操作是针对一个 Region 的。</p><p>当一个列族操作大量数据的时候会引发一个 flush，它邻近的列族也会因关联效应被触发 flush，尽管它没有操作多少数据。compaction 操作是根据一个列族下的全部文件的数量触发的，而不是根据文件大小触发的。</p><p>当很多的列族在 flush 和 compaction 时，会造成很多没用的 IO 负载。</p><p>尽量在模式中只针对一个列族进行操作。将使用率相近的列归为一个列族，这样每次访问就只用访问一个列族，既能提升查询效率，也能保持尽可能少的访问不同的磁盘文件。</p><h3 id="3-2、列族的基数"><a href="#3-2、列族的基数" class="headerlink" title="3.2、列族的基数"></a>3.2、列族的基数</h3><p>如果一个表存在多个列族，要注意列族之间基数（如行数）相差不要太大。例如列族 A 有100 万行，列族 B 有 10 亿行，按照 RowKey 切分后，列族A可能被分散到很多很多 Region（及RegionServer），这导致扫描列族A十分低效。</p><h3 id="3-3、列族名、列名长度"><a href="#3-3、列族名、列名长度" class="headerlink" title="3.3、列族名、列名长度"></a>3.3、列族名、列名长度</h3><p>列族名和列名越短越好，冗长的名字虽然可读性好，但是更短的名字在 HBase 中更好。</p><p>一个具体的值由存储该值的行键、对应的列（<code>列族:列</code>）以及该值的时间戳决定。HBase 中索引是为了加速随机访问的速度，索引的创建是基于“<code>行键+列族:列+时间戳+值</code>”的，如果行键和列族的大小过大，甚至超过值本身的大小，那么将会增加索引的大小。并且在HBase中数据记录往往非常之多，重复的行键、列将不但使索引的大小过大，也将加重系统的负担。</p><h2 id="四、总结"><a href="#四、总结" class="headerlink" title="四、总结"></a>四、总结</h2><p>根据 HBase 列族属性配置，结合使用场景，HBase 列族可以进行如下优化：</p><ol><li>列族不宜过多，将相关性很强的 key-value 都放在同一个列族下；</li><li>尽量最小化行键和列族的大小；</li><li>提前预估数据量，再根据 RowKey 规则，提前规划好 Region 分区，在创建表的时候进行预分区；</li><li>在业务上没有特别要求的情况下，只使用一个版本，即最大版本和最小版本一样，均为1；</li><li>根据业务需求合理设置好失效时间（存储的时间越短越好）；</li><li>根据查询条件，设置合理的BloomFilter配置。</li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;列族的配置&quot;&gt;&lt;a href=&quot;#列族的配置&quot; class=&quot;headerlink&quot; title=&quot;列族的配置&quot;&gt;&lt;/a&gt;列族的配置&lt;/h1&gt;&lt;h2 id=&quot;一、创建表及属性查看&quot;&gt;&lt;a href=&quot;#一、创建表及属性查看&quot; class=&quot;headerlink&quot; </summary>
      
    
    
    
    <category term="数据库" scheme="https://blog.ifan.host/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    <category term="大数据" scheme="https://blog.ifan.host/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/%E5%A4%A7%E6%95%B0%E6%8D%AE/"/>
    
    <category term="HBase" scheme="https://blog.ifan.host/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/%E5%A4%A7%E6%95%B0%E6%8D%AE/HBase/"/>
    
    
    <category term="大数据" scheme="https://blog.ifan.host/tags/%E5%A4%A7%E6%95%B0%E6%8D%AE/"/>
    
    <category term="数据库" scheme="https://blog.ifan.host/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    <category term="HBase" scheme="https://blog.ifan.host/tags/HBase/"/>
    
  </entry>
  
  <entry>
    <title>Nginx 使用 goaccess 分析日志</title>
    <link href="https://blog.ifan.host/2022/07/01/web/nginx/goaccess-nginx-log/"/>
    <id>https://blog.ifan.host/2022/07/01/web/nginx/goaccess-nginx-log/</id>
    <published>2022-07-01T01:01:00.000Z</published>
    <updated>2023-12-25T05:56:09.187Z</updated>
    
    <content type="html"><![CDATA[<h2 id="安装-Goaccess"><a href="#安装-Goaccess" class="headerlink" title="安装 Goaccess"></a>安装 Goaccess</h2><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">sudo yum install access </span><br></pre></td></tr></table></figure><h2 id="创建分析脚本"><a href="#创建分析脚本" class="headerlink" title="创建分析脚本"></a>创建分析脚本</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><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="meta">#!/bin/bash</span></span><br><span class="line"><span class="comment"># 日志路径</span></span><br><span class="line">LOG_PATH=/tmp/logs</span><br><span class="line"><span class="comment"># 需要分析的APP</span></span><br><span class="line"><span class="comment"># PS 博客的日志为 blog.access.log 和 blog.error.log</span></span><br><span class="line"><span class="comment"># 则 APPS 中应该填入 blog</span></span><br><span class="line">APPS=(blog gogs)</span><br><span class="line"><span class="comment"># 创建 静态文件生成的路径</span></span><br><span class="line">STATIC_HMTL=/tmp/goaccess</span><br><span class="line"><span class="built_in">mkdir</span> -p <span class="variable">$STATIC_HMTL</span></span><br><span class="line"><span class="keyword">for</span>(( i=<span class="number">0</span>;i&lt;<span class="variable">$&#123;#APPS[@]&#125;</span>;i++))</span><br><span class="line"><span class="keyword">do</span></span><br><span class="line">    APP=<span class="variable">$&#123;APPS[i]&#125;</span>;</span><br><span class="line">    <span class="built_in">cat</span> <span class="variable">$LOG_PATH</span>/<span class="variable">$APP</span>.access.log <span class="variable">$LOG_PATH</span>/<span class="variable">$APP</span>.error.log &gt; <span class="variable">$APP</span>.<span class="built_in">log</span></span><br><span class="line">    goaccess -f <span class="variable">$APP</span>.<span class="built_in">log</span> -o <span class="variable">$STATIC_HMTL</span>/<span class="variable">$APP</span>.html</span><br><span class="line">    <span class="built_in">rm</span> <span class="variable">$APP</span>.<span class="built_in">log</span></span><br><span class="line"><span class="keyword">done</span></span><br><span class="line"><span class="comment"># 合并所有日志</span></span><br><span class="line"><span class="keyword">for</span>(( i=<span class="number">0</span>;i&lt;<span class="variable">$&#123;#APPS[@]&#125;</span>;i++))</span><br><span class="line"><span class="keyword">do</span></span><br><span class="line">    APP=<span class="variable">$&#123;APPS[i]&#125;</span>;</span><br><span class="line">    <span class="built_in">cat</span> <span class="variable">$LOG_PATH</span>/<span class="variable">$APP</span>.access.log <span class="variable">$LOG_PATH</span>/<span class="variable">$APP</span>.error.log &gt;&gt; all.log</span><br><span class="line"><span class="keyword">done</span></span><br><span class="line">goaccess -f all.log -o <span class="variable">$STATIC_HMTL</span>/all.html</span><br><span class="line"><span class="built_in">rm</span> all.log</span><br></pre></td></tr></table></figure><h2 id="创建定时任务"><a href="#创建定时任务" class="headerlink" title="创建定时任务"></a>创建定时任务</h2><figure class="highlight plaintext"><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"># 每10分钟分析一次</span><br><span class="line">*/10 * * * * &quot;bash /tmp/start-goaccess.sh&quot; &gt; /dev/null</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;安装-Goaccess&quot;&gt;&lt;a href=&quot;#安装-Goaccess&quot; class=&quot;headerlink&quot; title=&quot;安装 Goaccess&quot;&gt;&lt;/a&gt;安装 Goaccess&lt;/h2&gt;&lt;figure class=&quot;highlight plaintext&quot;&gt;&lt;</summary>
      
    
    
    
    <category term="WEB" scheme="https://blog.ifan.host/categories/WEB/"/>
    
    <category term="Nginx" scheme="https://blog.ifan.host/categories/WEB/Nginx/"/>
    
    
    <category term="HTTP" scheme="https://blog.ifan.host/tags/HTTP/"/>
    
    <category term="Nginx" scheme="https://blog.ifan.host/tags/Nginx/"/>
    
  </entry>
  
</feed>
