-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
137 lines (63 loc) · 196 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>PythonCookbook学习笔记</title>
<link href="/2021/08/06/python_hypr_cent/"/>
<url>/2021/08/06/python_hypr_cent/</url>
<content type="html"><![CDATA[<h3 id="第一章-数据结构和算法"><a href="#第一章-数据结构和算法" class="headerlink" title="第一章 数据结构和算法"></a>第一章 数据结构和算法</h3><h4 id="杂"><a href="#杂" class="headerlink" title="杂"></a>杂</h4><figure class="highlight py"><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">records = [(<span class="string">'foo1'</span>, <span class="number">1</span>, <span class="number">2</span>),</span><br><span class="line"></span><br><span class="line"> (<span class="string">'foo2'</span>, <span class="string">'sad'</span>),</span><br><span class="line"></span><br><span class="line"> (<span class="string">'foo1'</span>, <span class="number">4</span>, <span class="number">5</span>)]</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">fun1</span>(<span class="params">x, y</span>):</span></span><br><span class="line"></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'foo1'</span>, x, y)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">fun2</span>(<span class="params">n</span>):</span></span><br><span class="line"></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'fool2'</span>, n)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> fun_name, *args <span class="keyword">in</span> records:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> fun_name == <span class="string">'foo1'</span>:</span><br><span class="line"></span><br><span class="line"> fun1(*args)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> fun_name == <span class="string">'foo2'</span>:</span><br><span class="line"></span><br><span class="line"> fun2(*args)</span><br></pre></td></tr></table></figure><p>对于嵌套不必要类容丢失的分解:</p><figure class="highlight py"><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">record=(<span class="string">'ACME'</span>,<span class="number">50</span>,<span class="number">123.45</span>,(<span class="number">12</span>,<span class="number">18</span>,<span class="number">2012</span>))</span><br><span class="line"></span><br><span class="line">name,*_,(*_,year)=record</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(name,year)</span><br></pre></td></tr></table></figure><p><strong>%%%%%</strong></p><p>拆分方法的<strong>精巧</strong>函数:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">sum_Z</span>(<span class="params">items</span>):</span></span><br><span class="line"></span><br><span class="line"> head,*tail=items</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> head+sum_Z(tail) <span class="keyword">if</span> tail <span class="keyword">else</span> head</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure><p><strong>%%%</strong></p><p>建议python不要写递归,python递归很艹,是因为其内在的递归限制所致的.但是还是可以完成一些有趣的操作.</p><h4 id="1-3-保存最后N个元素"><a href="#1-3-保存最后N个元素" class="headerlink" title="1.3 保存最后N个元素"></a>1.3 保存最后N个元素</h4><p><strong>目的</strong>: 希望在迭代或是其他形式的处理过程中对最后几项记录做一个有限的历史纪录统计.</p><p><strong>解决方法</strong>: 利用collection.deque</p><p>下面的代码对一系列文本做简单的文本匹配操作,当发现输出前匹配行以及最后检查过的N行文本.</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> deque</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">search</span>(<span class="params">lines,pattern,history=<span class="number">5</span></span>):</span></span><br><span class="line"></span><br><span class="line"> previous_lines=deque(maxlen=history)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> lines:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> pattern <span class="keyword">in</span> line:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">yield</span> line,previous_lines</span><br><span class="line"></span><br><span class="line"> previous_lines.append(line)</span><br><span class="line"></span><br><span class="line">\<span class="comment">#Example use on a file</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__name__'</span>:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'somefime.txt'</span>) <span class="keyword">as</span> f:</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> line,prevlines <span class="keyword">in</span> search(f,<span class="string">'python'</span>,<span class="number">5</span>):</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> pline <span class="keyword">in</span> prevlines:</span><br><span class="line"></span><br><span class="line"> <span class="built_in">print</span>(pline,end=<span class="string">''</span>)</span><br><span class="line"></span><br><span class="line"> <span class="built_in">print</span>(line,end=<span class="string">""</span>)</span><br><span class="line"></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'-'</span>*<span class="number">20</span>) </span><br></pre></td></tr></table></figure><h4 id="1-4-找到最大或最小的N个元素"><a href="#1-4-找到最大或最小的N个元素" class="headerlink" title="1.4 找到最大或最小的N个元素"></a>1.4 找到最大或最小的N个元素</h4><p><strong>解决方法</strong>: heapq模块的两个元素 nlargest()和 nsmallest()</p><figure class="highlight py"><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="keyword">import</span> heapq</span><br><span class="line"></span><br><span class="line">nums=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>]</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(heapq.nlargest(<span class="number">3</span>,nums))</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(heapq.nsmallest(<span class="number">3</span>,nums))</span><br><span class="line"></span><br><span class="line"><span class="comment"># [10, 9, 8]</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># [1, 2, 3]</span></span><br></pre></td></tr></table></figure><figure class="highlight py"><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="keyword">import</span> heapq</span><br><span class="line"></span><br><span class="line">portfoli = [{<span class="string">'name'</span>: <span class="string">'IBM'</span>, <span class="string">'shares'</span>: <span class="number">100</span>, <span class="string">'price'</span>: <span class="number">91.1</span>},</span><br><span class="line"></span><br><span class="line"> {<span class="string">'name'</span>: <span class="string">'A'</span>, <span class="string">'shares'</span>: <span class="number">10</span>, <span class="string">'price'</span>: <span class="number">9.11</span>},</span><br><span class="line"></span><br><span class="line"> {<span class="string">'name'</span>: <span class="string">'B'</span>, <span class="string">'shares'</span>: <span class="number">50</span>, <span class="string">'price'</span>: <span class="number">90</span>},</span><br><span class="line"></span><br><span class="line"> {<span class="string">'name'</span>: <span class="string">'C'</span>, <span class="string">'shares'</span>: <span class="number">1</span>, <span class="string">'price'</span>: <span class="number">91</span>}]</span><br><span class="line"></span><br><span class="line">cheap = heapq.nsmallest(<span class="number">3</span>, portfoli, key=<span class="keyword">lambda</span> s: s[<span class="string">'price'</span>])</span><br><span class="line"></span><br><span class="line">expensive = heapq.nlargest(<span class="number">3</span>, portfoli, key=<span class="keyword">lambda</span> s: s[<span class="string">'price'</span>])</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(cheap)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(expensive)</span><br></pre></td></tr></table></figure><p>如果在寻找最大或最小的N个元素,且同集合中元素的总数比总数小的多,堆可以提供很好的性能,这些函数首先会在底层转化为列表,且元素会以堆的方式排列.</p><p>例:</p><figure class="highlight py"><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">nums=[-<span class="number">11</span>,<span class="number">8</span>,<span class="number">1</span>,-<span class="number">1123</span>,<span class="number">15</span>,<span class="number">512</span>,<span class="number">1020</span>,<span class="number">123</span>,<span class="number">921</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> heapq</span><br><span class="line"></span><br><span class="line">heap=<span class="built_in">list</span>(nums)</span><br><span class="line"></span><br><span class="line">heapq.heapify(heap)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(heap) </span><br><span class="line"><span class="comment">#[-1123, -11, 1, 8, 15, 512, 1020, 123, 921]</span></span><br></pre></td></tr></table></figure><p>堆最重要的特性就是heap[0]总是最小的拉一个元素.此外,接下来的元素可以依次通过heapq.heappop()的方法轻松得到.</p><p>该方法会将第一个元素(最小的)弹出,然后第二个最小的元素取而代之(复杂度是o(log(N)),N表示堆的大小).例如找到第三个最小的元素可以连续heappop()3次.</p><p>但是如果要找第N个最大或者最小的元素heapq里的函数nlargest()和nsmallest()才是最适用的,如果只是简单的找到最大或最小的一个元素max()和min()会更快.</p><p>同样,如果N和集合本身的大小差不多,更快的方法是对集合排序然后切片(例:sorted(list)[:N]或sorted(list)[-N:]).但是要注意的是nlargest()和nsmallest()的实际实现会根据使用它们的方式有所不同,会有一些优化(如N的大小和输出差不多时,会采用排序的方法).</p><h4 id="1-5-实现优先队列"><a href="#1-5-实现优先队列" class="headerlink" title="1.5 实现优先队列"></a>1.5 实现优先队列</h4><p><strong>问题</strong> 要想实现一个队列,它们能够以给定的优先级来对元素排序,且每次pop操作时都会返回优先级最高的元素.</p><p><strong>解决方法</strong></p><p>利用heapq模块实现一个简单的优先级队列.</p><figure class="highlight py"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> heapq</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">PriorityQueue</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self</span>):</span></span><br><span class="line"> self._queue=[]</span><br><span class="line"> self._index=<span class="number">0</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">push</span>(<span class="params">self,item,prioity</span>):</span></span><br><span class="line"> heapq.heappush(self._queue,(-prioity,self._index,item)) </span><br><span class="line"> self._index+=<span class="number">1</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">pop</span>(<span class="params">self</span>):</span></span><br><span class="line"> <span class="keyword">return</span> heapq.heappop(self._queue)[-<span class="number">1</span>]</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Item</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span>(<span class="params">self,name</span>):</span></span><br><span class="line"> self.name=name</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__repr__</span>(<span class="params">self</span>):</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">'Item({!r})'</span>.<span class="built_in">format</span>(self.name)</span><br><span class="line">q=PriorityQueue()</span><br><span class="line">q.push(Item(<span class="string">'bar'</span>),<span class="number">5</span>)</span><br><span class="line">q.push(Item(<span class="string">'foo'</span>),<span class="number">1</span>)</span><br><span class="line">q.push(Item(<span class="string">'spam'</span>),<span class="number">4</span>)</span><br><span class="line">q.push(Item(<span class="string">'grok'</span>),<span class="number">2</span>)</span><br><span class="line"><span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line"> <span class="built_in">print</span>(q.pop())</span><br><span class="line"><span class="comment">#Item('bar')</span></span><br><span class="line"><span class="comment">#Item('spam')</span></span><br><span class="line"><span class="comment">#Item('grok')</span></span><br><span class="line"><span class="comment">#Item('foo')</span></span><br></pre></td></tr></table></figure><p>核心是对heapq模块的使用.函数heaqp.heappush()以及heapq.heappop()分别实现将元素从列表_queue中插入和移除,且保证了列表中第一个元素的优先级最低.</p><p>heappop()方法总是返回’最小’的元素,因此这就是把元素正确弹出的关键.此外,由于push()和pop()操作的复杂度都是log(n),效率很高.</p><p>在这段代码中队列以元组的形式(-priority,index,item) 把priority取负是为了按照优先级由高到第的方式排顺序,变量index的作用是为了将具有相同优先级的元素以适当的顺序排序,通过增加一个不断递增的引索,元素将以它们入队时的顺序排列.但是index在对具有相同优先级的元素之间作比较也扮演了重要的角色.</p><p>为了说明Item实例是无法比较的:</p><figure class="highlight py"><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">a=Item(<span class="string">'dokuo'</span>)</span><br><span class="line"></span><br><span class="line">b=Item(<span class="string">'boki'</span>) </span><br><span class="line"></span><br><span class="line"><span class="comment">#print(a<b)</span></span><br><span class="line"><span class="comment">#Traceback (most recent call last):</span></span><br><span class="line"><span class="comment"># File "g:\Desktop\test\learn_py\struct_angl.py", line 94, in <module></span></span><br><span class="line"><span class="comment"># print(a<b)</span></span><br><span class="line"><span class="comment">#TypeError: '<' not supported between instances of 'Item' and 'Item'</span></span><br></pre></td></tr></table></figure><p>如果以元组(priority,item)的形式来表示元素,那么只要优先级不同,它们就可以进行比较.但是,如果两个元组的优先值相同,做比较操作还是会失败.</p><p>可以通过引入额外的引索值,以(priority,index,item)的方式建立元组,可以完全的避免这个问题.因为没有拉两组会有相同的index值.如果要用于线程间通信,还需要增加适当的锁和信号机制.</p><h4 id="1-6-在字典中将键映射到多个值上"><a href="#1-6-在字典中将键映射到多个值上" class="headerlink" title="1.6 在字典中将键映射到多个值上"></a>1.6 在字典中将键映射到多个值上</h4><p><strong>问题</strong> 建立多值字典(multidict)</p><p><strong>解决方法</strong></p><p>字典是一种关联容器,每一个键都将映射到一个单独的值上.如果想让键映射到多个值,需要将这些值保存在一个容器中(如:列表或集合).</p><p>例:</p><figure class="highlight py"><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">d = {</span><br><span class="line"></span><br><span class="line"> <span class="string">'a'</span>: [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</span><br><span class="line"></span><br><span class="line"> <span class="string">'b'</span>: [<span class="number">1</span>, <span class="number">41</span>]</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">e = {</span><br><span class="line"></span><br><span class="line"> <span class="string">'a'</span>: {<span class="number">1</span>, <span class="number">2</span>, <span class="number">34</span>},</span><br><span class="line"></span><br><span class="line"> <span class="string">'b'</span>: {<span class="number">61</span>, <span class="number">12</span>}</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>要使用集合还是列表取决于用途.如果希望保留插入顺序使用list,否则set.</p><p>为了方便的创建字典可以使用collections模块的defaultdict类.defaultdict的一个特点就是会自动初始化第一个值,这样只需要关注添加元素即可.</p><p>例如:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line"></span><br><span class="line">d=defaultdict(<span class="built_in">list</span>)</span><br><span class="line"></span><br><span class="line">d[<span class="string">'a'</span>].append(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">d[<span class="string">'a'</span>].append(<span class="number">2</span>)</span><br><span class="line"></span><br><span class="line">d[<span class="string">'b'</span>].append(<span class="number">4</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(d)</span><br><span class="line"><span class="comment">#defaultdict(<class 'list'>, {'a': [1, 2], 'b': [4]})</span></span><br></pre></td></tr></table></figure><p>也可以用dict本身的方法setdefault()来取代,但是setdefault()有点不自然每次调用时都会创建一个初始值的新实例.</p><p>原则上构建一个一键多值字典是很容易的.但是如果试着自己对一个值做初始化操作,这就会变得很杂乱.</p><p>例:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line">d={}</span><br><span class="line"><span class="keyword">for</span> key,value <span class="keyword">in</span> pairs:</span><br><span class="line"> <span class="keyword">if</span> key <span class="keyword">not</span> <span class="keyword">in</span> d:</span><br><span class="line"> d[key]=[]</span><br><span class="line"> d[key].append(value) </span><br><span class="line"><span class="comment">#在使用defaultdict后会清晰一些</span></span><br><span class="line">d=defaultdict(<span class="built_in">list</span>)</span><br><span class="line"><span class="keyword">for</span> key,value <span class="keyword">in</span> pairs:</span><br><span class="line"> d[key].append(value)</span><br></pre></td></tr></table></figure><h4 id="1-7-让字典保持有序"><a href="#1-7-让字典保持有序" class="headerlink" title="1.7 让字典保持有序"></a>1.7 让字典保持有序</h4><p><strong>问题</strong> 创建一个字典,同时当对字典做迭代或序列化操作时,也能控制其中元素的顺序.</p><p><strong>解决方案</strong>:</p><p>要控制字典中元素的顺序,可以使用collections 中的OrderedDict类.当对字典做迭代时,它会严格按照元素添加的顺序进行.</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> OrderedDict</span><br><span class="line">d=OrderedDict()</span><br><span class="line">d[<span class="string">'foo'</span>]=<span class="number">1</span></span><br><span class="line">d[<span class="string">'bar'</span>]=<span class="number">2</span></span><br><span class="line">d[<span class="string">'spam'</span>]=<span class="number">3</span></span><br><span class="line">d[<span class="string">'grok'</span>]=<span class="number">4</span></span><br><span class="line"><span class="keyword">for</span> key <span class="keyword">in</span> d:</span><br><span class="line"> <span class="built_in">print</span>(key,d[key])</span><br><span class="line"><span class="comment">#foo 1</span></span><br><span class="line"><span class="comment">#bar 2</span></span><br><span class="line"><span class="comment">#spam 3</span></span><br><span class="line"><span class="comment">#grok 4</span></span><br></pre></td></tr></table></figure><p>当想构建一个映射结构以便稍后对其做序列化操作或编码成为另一种格式时,OrderedDict 就显得有用.例如在进行JSON编码时精确控制各字段的顺序,那么只要首先在OrderedDict中构建数据就行了.</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> OrderedDict</span><br><span class="line">d=OrderedDict()</span><br><span class="line">d[<span class="string">'foo'</span>]=<span class="number">1</span></span><br><span class="line">d[<span class="string">'bar'</span>]=<span class="number">2</span></span><br><span class="line">d[<span class="string">'spam'</span>]=<span class="number">3</span></span><br><span class="line">d[<span class="string">'grok'</span>]=<span class="number">4</span></span><br><span class="line"><span class="comment"># for key in d:</span></span><br><span class="line"><span class="comment"># print(key,d[key])</span></span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line">x=json.dumps(d)</span><br><span class="line"><span class="built_in">print</span>(x)</span><br><span class="line"><span class="comment">#{"foo": 1, "bar": 2, "spam": 3, "grok": 4}</span></span><br></pre></td></tr></table></figure><p>OrderedDict内部维护了一个双向链表,会根据元素加入的顺序来排列键的位置.第一个新加入的元素排列在链表的尾部.接下来对已经存在的键做重新赋值不会改变键的顺序,但是OrderedDict的大小是普通字典的2倍多.是因为链表结构导致的.</p><h4 id="1-8-与字典有关的计算问题"><a href="#1-8-与字典有关的计算问题" class="headerlink" title="1.8 与字典有关的计算问题"></a>1.8 与字典有关的计算问题</h4><p>问题 对字典上的数据执行各种计算(求最大最小,排序)</p><p>解决方案 </p><figure class="highlight py"><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">prices={</span><br><span class="line"> <span class="string">'ACME'</span>:<span class="number">45.23</span>,</span><br><span class="line"> <span class="string">'AAPL'</span>:<span class="number">612.78</span>,</span><br><span class="line"> <span class="string">'IBM'</span>:<span class="number">205.55</span>,</span><br><span class="line"> <span class="string">'HPQ'</span>:<span class="number">37.20</span>,</span><br><span class="line"> <span class="string">'FB'</span>:<span class="number">10.75</span></span><br><span class="line">}</span><br><span class="line">min_price=<span class="built_in">min</span>(<span class="built_in">zip</span>(prices.values(),prices.keys()))</span><br><span class="line"><span class="built_in">print</span>(min_price)</span><br><span class="line">max_price=<span class="built_in">max</span>(<span class="built_in">zip</span>(prices.values(),prices.keys()))</span><br><span class="line"><span class="built_in">print</span>(max_price)</span><br><span class="line"><span class="comment">#同样排序只要使用zip()然后配合sorted()就可以了</span></span><br><span class="line">prices_sorted=<span class="built_in">sorted</span>(<span class="built_in">zip</span>(prices.values(),prices.keys()))</span><br><span class="line"><span class="built_in">print</span>(prices_sorted)</span><br><span class="line"><span class="comment">#当计算时,zip()建立了一个迭代器,内容只能被消费一次.</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">prices_and_name=<span class="built_in">zip</span>(prices.values(),prices.keys())</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">max</span>(prices_and_name))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">min</span>(prices_and_name))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="string">'''Output'''</span></span><br><span class="line"><span class="comment"># (10.75, 'FB')</span></span><br><span class="line"><span class="comment"># (612.78, 'AAPL')</span></span><br><span class="line"><span class="comment"># [(10.75, 'FB'), (37.2, 'HPQ'), (45.23, 'ACME'), (205.55, 'IBM'), (612.78, 'AAPL')]</span></span><br><span class="line"><span class="comment"># (612.78, 'AAPL')</span></span><br><span class="line"><span class="comment"># Traceback (most recent call last):</span></span><br><span class="line"><span class="comment"># File "G:/Desktop/test/learn_py/struct_angl.py", line 144, in <module></span></span><br><span class="line"><span class="comment"># print(min(prices_and_name))</span></span><br><span class="line"><span class="comment"># ValueError: min() arg is an empty sequence</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>如果尝试在字典上执行常见的数据操作,将会发现它们只会处理键,而不是值.</p><p>例:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">min</span>(prices)<span class="comment">#return 'AAPL'</span></span><br><span class="line"><span class="built_in">max</span>(prices)<span class="comment">#return 'IBM'</span></span><br></pre></td></tr></table></figure><p>并不是我们所期望的,因为实际上我们是尝试对字典的值做计算.</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">min</span>(prices.values())<span class="comment">#return '10.75'</span></span><br><span class="line"><span class="built_in">max</span>(prices.valuse())<span class="comment">#return '612.78'</span></span><br></pre></td></tr></table></figure><p>但是这也不是我们所期望的,我们需要一个对应关系什么的计算的对应的值和键.</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">min</span>(prices,key=<span class="keyword">lambda</span> k:prices[k]) <span class="comment">#return 'FB'</span></span><br><span class="line"><span class="built_in">max</span>(prices,key=<span class="keyword">lambda</span> k:prices[k]) <span class="comment">#return 'AAPL'</span></span><br><span class="line"><span class="comment">#如果要得到最小值的话,还要额外执行一次查找.</span></span><br><span class="line">min_value=prices[<span class="built_in">min</span>(prices,key=<span class="keyword">lambda</span> k:prices[k])]</span><br><span class="line"><span class="comment">#利用zip()的解决方法是通过键值对反转实现的这样的元组比较时是先比较值然后比较键符合我们的预期</span></span><br></pre></td></tr></table></figure><p>应当注意的是,当涉及(value,key) 的对比结果时比较key的大小.</p><figure class="highlight py"><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">prices={<span class="string">'AAA'</span>:<span class="number">45.33</span>,<span class="string">'ZZZ'</span>:<span class="number">45.33</span>}</span><br><span class="line">t1=<span class="built_in">min</span>(<span class="built_in">zip</span>(prices.values(),prices.keys()))</span><br><span class="line">t2=<span class="built_in">max</span>(<span class="built_in">zip</span>(prices.values(),prices.keys()))</span><br><span class="line"><span class="built_in">print</span>(t1)</span><br><span class="line"><span class="built_in">print</span>(t2)</span><br><span class="line"><span class="comment">#(45.33, 'AAA')</span></span><br><span class="line"><span class="comment">#(45.33, 'ZZZ')</span></span><br></pre></td></tr></table></figure><h4 id="1-9-在两个字典中寻找相同点"><a href="#1-9-在两个字典中寻找相同点" class="headerlink" title="1.9 在两个字典中寻找相同点"></a>1.9 在两个字典中寻找相同点</h4><p>问题 有两个字典,找出它们中间可能相同的地方(key,value)</p><p>解决方法</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">a={</span><br><span class="line"> <span class="string">'x'</span>:<span class="number">1</span>,</span><br><span class="line"> <span class="string">'y'</span>:<span class="number">2</span>,</span><br><span class="line"> <span class="string">'z'</span>:<span class="number">3</span></span><br><span class="line">}</span><br><span class="line">b={</span><br><span class="line"> <span class="string">'w'</span>:<span class="number">10</span>,</span><br><span class="line"> <span class="string">'x'</span>:<span class="number">11</span>,</span><br><span class="line"> <span class="string">'y'</span>:<span class="number">2</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">#要找出两个字典的相同之处,只要通过keys()或者items()的方法执行集合的操作</span></span><br><span class="line"><span class="comment">#Find keys in common</span></span><br><span class="line"><span class="built_in">print</span>(a.keys() & b.keys())<span class="comment">#('x','y')</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#Find keys in a that not in b</span></span><br><span class="line"><span class="built_in">print</span>(a.keys()-b.keys())</span><br><span class="line"><span class="comment">#{'z'}</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#Find (key ,value) pairs in common</span></span><br><span class="line"><span class="built_in">print</span>(a.items()&b.items())<span class="comment">#{('y', 2)}</span></span><br><span class="line"></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="comment">#example del some keys</span></span><br><span class="line"><span class="comment">#Make a new dictionary with certain keys removed</span></span><br><span class="line">c={key:a[key] <span class="keyword">for</span> key <span class="keyword">in</span> a.keys()-{<span class="string">'z'</span>,<span class="string">'w'</span>}}</span><br><span class="line"><span class="comment">#c is {'x':1,'y':2}</span></span><br></pre></td></tr></table></figure><p>字典就是一系例键和值的映射集合.字典的keys()方法会返回keys-view对象,其中,暴露了所有键.关于字典也支持集合的操作 如 求并集,交集,差集.因此,如果要对字典的键做集合的操作,不必转化为set() 直接使用keys-view对象. items()方法返回items-view 对象支持集合操作. 但是字典的value()方法不支持集合操作,是因为字典中的键和值是不同的不能保证所有值都是唯一的.所以可以先把values 转化为 set 来实现集合操作.</p><h4 id="1-10-从序列中移除重复项但是保持顺序不变"><a href="#1-10-从序列中移除重复项但是保持顺序不变" class="headerlink" title="1.10 从序列中移除重复项但是保持顺序不变"></a>1.10 从序列中移除重复项但是保持顺序不变</h4><p>问题 去除序列中重复的元素,但是保持剩下的元素顺序不变.</p><p>解决方法</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">dedupe</span>(<span class="params">items</span>):</span></span><br><span class="line"> seen =<span class="built_in">set</span>()</span><br><span class="line"> <span class="keyword">for</span> item <span class="keyword">in</span> items:</span><br><span class="line"> <span class="keyword">if</span> item <span class="keyword">not</span> <span class="keyword">in</span> seen:</span><br><span class="line"> <span class="keyword">yield</span> item</span><br><span class="line"> seen.add(item)</span><br><span class="line">a=[<span class="number">1</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">9</span>,<span class="number">1</span>,<span class="number">5</span>,<span class="number">10</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(dedupe(a)))</span><br><span class="line"><span class="comment">#只有当序列中的元素是可哈希的时候才能这样做,在不可哈希对象如列表中如以下</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">dedupe_</span>(<span class="params">items,key=<span class="literal">None</span></span>):</span></span><br><span class="line"> seen=<span class="built_in">set</span>()</span><br><span class="line"> <span class="keyword">for</span> item <span class="keyword">in</span> items:</span><br><span class="line"> val=item <span class="keyword">if</span> key <span class="keyword">is</span> <span class="literal">None</span> <span class="keyword">else</span> key(item)</span><br><span class="line"> <span class="keyword">if</span> val <span class="keyword">not</span> <span class="keyword">in</span> seen:</span><br><span class="line"> <span class="keyword">yield</span> item</span><br><span class="line"> seen.add(val)</span><br><span class="line"><span class="comment">#这里参数key的目的是指定一个函数用来将序列中的元素转化为可哈希的类型是为了检测重复项</span></span><br><span class="line">a=[{<span class="string">'x'</span>:<span class="number">1</span>,<span class="string">'y'</span>:<span class="number">2</span>},{<span class="string">'x'</span>:<span class="number">1</span>,<span class="string">'y'</span>:<span class="number">3</span>},{<span class="string">'x'</span>:<span class="number">1</span>,<span class="string">'y'</span>:<span class="number">2</span>},{<span class="string">'x'</span>:<span class="number">2</span>,<span class="string">'y'</span>:<span class="number">4</span>}]</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(dedupe_(a,key=<span class="keyword">lambda</span> d:(d[<span class="string">'x'</span>],d[<span class="string">'y'</span>]))))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(dedupe_(a,key=<span class="keyword">lambda</span> d:(d[<span class="string">'x'</span>]))))</span><br><span class="line"><span class="comment">#如果希望在一个复杂的数据结构中,只根据对象的某个字段或属性来去除重复项,拉莫最后一种解决方法同样</span></span><br><span class="line"><span class="comment">#能完美的完成工作</span></span><br></pre></td></tr></table></figure><p>如果只要求去除重复项,简单的办法就是构建一个集合.</p><p>如:</p><figure class="highlight py"><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">x=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3456</span>,<span class="number">123</span>,<span class="number">12</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">set</span>(x))</span><br><span class="line"><span class="comment">#{3456, 1, 2, 12, 123} 可见顺序被改变了.</span></span><br></pre></td></tr></table></figure><p>对生成器的使用反应了一个事实,我们可能会希望这个函数尽可能通用—–不必绑定在只能对列表进行处理.例如</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#想读取一个文件,去除其中重复的文本行可以这样处理</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(somefile,<span class="string">'r'</span>) <span class="keyword">as</span> f:</span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> dedupe_(f):</span><br><span class="line"> ...</span><br></pre></td></tr></table></figure><h4 id="1-11-对切片命名"><a href="#1-11-对切片命名" class="headerlink" title="1.11 对切片命名"></a>1.11 对切片命名</h4><p>问题 当代码繁杂无法阅读时想要把切片定义成宏之类的东西时.</p><p>解决方案</p><figure class="highlight py"><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">record=<span class="string">'...........100............513.25'</span></span><br><span class="line">x=record[<span class="number">11</span>:<span class="number">14</span>]</span><br><span class="line">y=record[<span class="number">26</span>:<span class="number">32</span>]</span><br><span class="line"><span class="built_in">print</span>(x,y)</span><br><span class="line"><span class="comment">#与其这样做不如命名</span></span><br><span class="line">SHARES=<span class="built_in">slice</span>(<span class="number">11</span>,<span class="number">14</span>)</span><br><span class="line">PRICE=<span class="built_in">slice</span>(<span class="number">26</span>,<span class="number">32</span>)</span><br><span class="line"><span class="built_in">print</span>(x,y)</span><br><span class="line"><span class="comment">#100 513.25</span></span><br><span class="line"><span class="comment">#100 513.25</span></span><br><span class="line"><span class="comment">#可以避免一些神秘难懂的编码引索,使代码变得清晰.</span></span><br></pre></td></tr></table></figure><p>作为一条基本准则,代码如果有过多的编码引索,会使可读性和维护性降低.</p><p>一般的来说内置的slice()函数会创建一个切片对象,可以用在任何允许使用切片的地方.</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></pre></td><td class="code"><pre><span class="line">>>>items=[1,2,3,4,5,6]</span><br><span class="line">>>>a=slice(2,4)</span><br><span class="line">>>>items(a)</span><br><span class="line">Traceback (most recent call last):</span><br><span class="line"> File "<input>", line 1, in <module></span><br><span class="line">TypeError: 'list' object is not callable</span><br><span class="line">>>>items[a]</span><br><span class="line">[3, 4]</span><br><span class="line">>>>items[a]=[1,2]</span><br><span class="line">>>>items</span><br><span class="line">[1, 2, 1, 2, 5, 6]</span><br><span class="line">>>>del items[a]</span><br><span class="line">>>>items</span><br><span class="line">[1, 2, 5, 6]</span><br></pre></td></tr></table></figure><p>如果有一个slice对象的实例,可以通过s.start,s.stop以及s.step属性来得到关于改对象的信息.</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">#承接上一个控制台</span><br><span class="line">>>>items</span><br><span class="line">[1, 2, 5, 6]</span><br><span class="line">>>>a.start</span><br><span class="line">2</span><br><span class="line">>>>a.step</span><br><span class="line">>>>a.stop</span><br><span class="line">4</span><br></pre></td></tr></table></figure><p>此外,可以通过使用indices(size)的方法将切片映射到特定大小的序列上.会返回一个(start,stop,step)元组,所有的值都已经恰当的限制在边界以内(当做引索操作时可以避免异常)</p><p>例如:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">>>>s='HelloWorld'</span><br><span class="line">>>>a.indices(len(s))</span><br><span class="line">(2, 4, 1)</span><br><span class="line">>>>for i in range(*a.indices(len(s))):</span><br><span class="line">... print(s[i])</span><br><span class="line">... </span><br><span class="line">l</span><br><span class="line">l</span><br></pre></td></tr></table></figure><h4 id="1-12-找出序列中出现次数最多的元素"><a href="#1-12-找出序列中出现次数最多的元素" class="headerlink" title="1.12 找出序列中出现次数最多的元素"></a>1.12 找出序列中出现次数最多的元素</h4><p>问题 统计</p><p>解决方案</p><p>collections 模块中有一个Counter类正式为此类问题设计的.有一个非常方便的most_common()方法可以直接告诉我们答案.</p><figure class="highlight py"><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">words=[<span class="number">1</span> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">3</span>)]+[<span class="number">2</span> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>) ]+[<span class="number">0</span> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">6</span>) ]+[<span class="number">3</span> <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>) ]</span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> Counter</span><br><span class="line">word_counts=Counter(words)</span><br><span class="line">top_three=word_counts.most_common(<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(top_three)</span><br><span class="line"><span class="comment">#[(3, 10), (0, 6), (2, 4)]</span></span><br></pre></td></tr></table></figure><p>可以给Counter对象提供任何可哈希的对象序列作为输入,在底层实现中,Counter 是一个字典,元素和它们之前出现的次数做了映射.</p><figure class="highlight py"><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="built_in">print</span>(word_counts[<span class="number">1</span>])</span><br><span class="line"><span class="built_in">print</span>(word_counts[<span class="number">2</span>])</span><br><span class="line"><span class="comment"># 3</span></span><br><span class="line"><span class="comment"># 4</span></span><br></pre></td></tr></table></figure><p>如果想增加计数可以改变映射值</p><p>如</p><figure class="highlight py"><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">word_counts[<span class="number">1</span>]=<span class="number">1</span></span><br><span class="line"><span class="comment">#或则另一种方法</span></span><br><span class="line">word_counts.update(morewords)</span><br></pre></td></tr></table></figure><p>Counter类可以轻松的同各类数学运算操作结合起来.</p><figure class="highlight py"><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">a=Counter(words)</span><br><span class="line">b=Counter(word_counts)</span><br><span class="line"><span class="built_in">print</span>(a,b)</span><br><span class="line"><span class="built_in">print</span>(a+b)</span><br><span class="line"><span class="built_in">print</span>(a-b)</span><br><span class="line"><span class="comment">#Counter({3: 10, 0: 6, 2: 4, 1: 3}) Counter({3: 10, 0: 6, 2: 4, 1: 3})</span></span><br><span class="line"><span class="comment">#Counter({3: 20, 0: 12, 2: 8, 1: 6})</span></span><br><span class="line"><span class="comment">#Counter()</span></span><br></pre></td></tr></table></figure><p>当面对任何需要数据制表或计数的问题时,Counter对象都是一种很好的选择.</p><h4 id="1-13-通过公共键对字典列表排序"><a href="#1-13-通过公共键对字典列表排序" class="headerlink" title="1.13 通过公共键对字典列表排序"></a>1.13 通过公共键对字典列表排序</h4><p>问题 有一个字典列表,想根据一个或多个字典中的值来对列表排序</p><p>解决方法</p><p>利用operator模块中的itemgetter函数对这类结构进行简单的排序.</p><p>假设通过查询数据库表获取网上的成员列表得到以下的数据结构.</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">rows=[</span><br><span class="line"> {<span class="string">'fname'</span>:<span class="string">'1'</span>,<span class="string">'lname'</span>:<span class="string">'1'</span>,<span class="string">'uid'</span>:<span class="string">'1'</span>},</span><br><span class="line">{<span class="string">'fname'</span>:<span class="string">'2'</span>,<span class="string">'lname'</span>:<span class="string">'2'</span>,<span class="string">'uid'</span>:<span class="string">'2'</span>},</span><br><span class="line">{<span class="string">'fname'</span>:<span class="string">'1'</span>,<span class="string">'lname'</span>:<span class="string">'2'</span>,<span class="string">'uid'</span>:<span class="string">'3'</span>},</span><br><span class="line">{<span class="string">'fname'</span>:<span class="string">'3'</span>,<span class="string">'lname'</span>:<span class="string">'11'</span>,<span class="string">'uid'</span>:<span class="string">'4'</span>},</span><br><span class="line">{<span class="string">'fname'</span>:<span class="string">'4'</span>,<span class="string">'lname'</span>:<span class="string">'11'</span>,<span class="string">'uid'</span>:<span class="string">'4'</span>}</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> operator <span class="keyword">import</span> itemgetter</span><br><span class="line">rows_by_fname=<span class="built_in">sorted</span>(rows,key=itemgetter(<span class="string">'fname'</span>))</span><br><span class="line">rows_by_uid=<span class="built_in">sorted</span>(rows,key=itemgetter(<span class="string">'uid'</span>))</span><br><span class="line"><span class="built_in">print</span>(rows_by_fname)</span><br><span class="line"><span class="built_in">print</span>(rows_by_uid)</span><br><span class="line"><span class="comment"># [{'fname': '1', 'lname': '1', 'uid': '1'}, </span></span><br><span class="line"><span class="comment"># {'fname': '1', 'lname': '2', 'uid': '3'}, </span></span><br><span class="line"><span class="comment"># {'fname': '2', 'lname': '2', 'uid': '2'}, </span></span><br><span class="line"><span class="comment"># {'fname': '3', 'lname': '11', 'uid': '4'}, </span></span><br><span class="line"><span class="comment"># {'fname': '4', 'lname': '11', 'uid': '4'}]</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># [{'fname': '1', 'lname': '1', 'uid': '1'}, </span></span><br><span class="line"><span class="comment"># {'fname': '2', 'lname': '2', 'uid': '2'}, </span></span><br><span class="line"><span class="comment"># {'fname': '1', 'lname': '2', 'uid': '3'},</span></span><br><span class="line"><span class="comment"># {'fname': '3', 'lname': '11', 'uid': '4'}, </span></span><br><span class="line"><span class="comment"># {'fname': '4', 'lname': '11', 'uid': '4'}]</span></span><br></pre></td></tr></table></figure><p>itemgetter()函数可以接受多个键.例如:</p><figure class="highlight py"><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">rows_by_lfname=<span class="built_in">sorted</span>(rows,key=itemgetter(<span class="string">'lname'</span>,<span class="string">'fname'</span>))</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(rows_by_lfname)</span><br><span class="line"><span class="comment">#[{'fname': '1', 'lname': '1', 'uid': '1'}, </span></span><br><span class="line"><span class="comment">#{'fname': '3', 'lname': '11', 'uid': '4'}, </span></span><br><span class="line"><span class="comment">#{'fname': '4', 'lname': '11', 'uid': '4'}, </span></span><br><span class="line"><span class="comment">#{'fname': '1', 'lname': '2', 'uid': '3'}, </span></span><br><span class="line"><span class="comment">#{'fname': '2', 'lname': '2', 'uid': '2'}]</span></span><br></pre></td></tr></table></figure><p>这个例子中rows被传递给内建的sorted()函数,该函数接受一个关键字参数key.这个参数应该代表一个可调用对象(callable),该对象从rows中接受一个单独的元素作为输入并返回一个用来排序依据的值.item getter()函数建立的就是这样一个可调用对象.</p><p>函数operator.itemgetter()接受的参数是可以作为查询的标记,用来从rows的记录中提取出所需要的值,可以是字典键的名称,用数字表示的列表元素或是任何可以传给对象的____getitem____() 方法的值如果传多个标记给itemgetter(),那么它产生的可调用对象将返回一个包含所有元素在内的元组,然后sorted()将根据元组排序的结果来排序输出的结果。如果同时针对多个字段排序这是非常有用的。</p><p>有时会用lambda函数来代替itemgetter()函数。</p><figure class="highlight py"><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">rows_by_fname=<span class="built_in">sorted</span>(rows,key=<span class="keyword">lambda</span> r:r[<span class="string">'fname'</span>])</span><br><span class="line">rows_by_lfname=<span class="built_in">sorted</span>(rows,key=<span class="keyword">lambda</span> r:(r[<span class="string">'fname'</span>],r[<span class="string">'lname'</span>]))</span><br></pre></td></tr></table></figure><p>也可以正常运行但是itemgetter()通常会更快一些。如果要考虑性能的话还是itemgetter()。同样也适用于max(),min().</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></pre></td><td class="code"><pre><span class="line">max(__iterable: Iterable[_T1],</span><br><span class="line"> *,</span><br><span class="line"> key: (_T1) -> SupportsLessThanT,</span><br><span class="line"> default: _T2) -> Union[_T1, _T2]</span><br><span class="line"></span><br><span class="line">min(__iterable: Iterable[_T1],</span><br><span class="line"> *,</span><br><span class="line"> key: (_T1) -> SupportsLessThanT,</span><br><span class="line"> default: _T2) -> Union[_T1, _T2]</span><br></pre></td></tr></table></figure><h4 id="1-14-对不原生支持比较的操作对象排序"><a href="#1-14-对不原生支持比较的操作对象排序" class="headerlink" title="1.14 对不原生支持比较的操作对象排序"></a>1.14 对不原生支持比较的操作对象排序</h4><p>问题 想在同一个类的实例中做排序,但是它们并不原生支持比较操作</p><p>解决方法</p><p>内建的sorted()函数可以接受一个用来传递可调用对象(callable)的参数key,而该可调用对象会返回待排序对象中的某一些值,sorted则利用这些值来比较对象。</p><p>例如有一些User对象实例,想通过user.id属性来比较它们的排序,则可以提供一个可调用对象User实例作为输入然后返回user——id.</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></pre></td><td class="code"><pre><span class="line">class User:</span><br><span class="line"> def __init__(self,user_id):</span><br><span class="line"> self.user_id=user_id</span><br><span class="line"> def __repr__(self):</span><br><span class="line"> return 'User({})'.format(self.user_id)</span><br><span class="line"></span><br><span class="line">users=[User(23),User(3),User(99)]</span><br><span class="line">print(users)</span><br><span class="line">x=sorted(users,key=lambda u:u.user_id)</span><br><span class="line"></span><br><span class="line">print(x)</span><br><span class="line"># [User(23), User(3), User(99)]</span><br><span class="line"># [User(3), User(23), User(99)]</span><br></pre></td></tr></table></figure><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">#除了lambda表达式之外还可以使用operator。attrgetter</span></span><br><span class="line"><span class="keyword">from</span> operator <span class="keyword">import</span> attrgetter</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">sorted</span>(users,key=attrgetter(<span class="string">'user_id'</span>)))</span><br><span class="line"><span class="comment">#[User(3), User(23), User(99)]</span></span><br></pre></td></tr></table></figure><p>lambda 和attrgetter都可以但是attrgeter要更快一些,且具有允许同时提取多个字段值的能力。同1.13中的itemgetter().</p><h4 id="1-15-根据字段将记录分组"><a href="#1-15-根据字段将记录分组" class="headerlink" title="1.15 根据字段将记录分组"></a>1.15 根据字段将记录分组</h4><p>问题 有一系列的字典或对象实例,我们想根据某个特定的字段(比如日期)来分组迭代数据。</p><p>解决方案</p><p>itertools.groupby()函数在对数据进行分组时特别有用.为了说明其用途,假设下面的字典.</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">rows=[</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5412 N CLARK'</span>,<span class="string">'date'</span>:<span class="string">'07/01/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5413 N CLARK'</span>, <span class="string">'date'</span>: <span class="string">'07/04/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5411 E 58TH'</span>, <span class="string">'date'</span>: <span class="string">'07/02/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5414 N CLARK'</span>, <span class="string">'date'</span>: <span class="string">'07/03/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5415 N RAVENSWOOD'</span>, <span class="string">'date'</span>: <span class="string">'07/04/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5416 N ADDISON'</span>, <span class="string">'date'</span>: <span class="string">'07/12/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5417 W CLARK'</span>, <span class="string">'date'</span>: <span class="string">'07/09/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5418 N BROADWAY'</span>, <span class="string">'date'</span>: <span class="string">'08/01/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5419 W GRANVILLE'</span>, <span class="string">'date'</span>: <span class="string">'02/01/2012'</span>}</span><br><span class="line">]</span><br><span class="line"><span class="comment">#现在想根据日期分组方式迭代数据.要做到这些,首先以目标字段(date)来对序列排序,然后使用itertools.groupby()</span></span><br><span class="line"><span class="keyword">from</span> operator <span class="keyword">import</span> itemgetter</span><br><span class="line"><span class="keyword">from</span> itertools <span class="keyword">import</span> groupby</span><br><span class="line"><span class="comment"># Sort by the desired field first</span></span><br><span class="line">rows.sort(key=itemgetter(<span class="string">'date'</span>))</span><br><span class="line"><span class="comment">#Iterate in groups</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> date,items <span class="keyword">in</span> groupby(rows,key=itemgetter(<span class="string">'date'</span>)):</span><br><span class="line"> <span class="built_in">print</span>(date)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> items:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">' '</span>,i)</span><br><span class="line"><span class="comment">#02 / 01 / 2012</span></span><br><span class="line"><span class="comment">#{'address': '5419 W GRANVILLE', 'date': '02/01/2012'}</span></span><br><span class="line"><span class="comment">#07 / 01 / 2012</span></span><br><span class="line"><span class="comment">#{'address': '5412 N CLARK', 'date': '07/01/2012'}</span></span><br><span class="line"><span class="comment"># 07 / 02 / 2012</span></span><br><span class="line"><span class="comment"># {'address': '5411 E 58TH', 'date': '07/02/2012'}</span></span><br><span class="line"><span class="comment"># 07 / 03 / 2012</span></span><br><span class="line"><span class="comment"># {'address': '5414 N CLARK', 'date': '07/03/2012'}</span></span><br><span class="line"><span class="comment"># 07 / 04 / 2012</span></span><br><span class="line"><span class="comment"># {'address': '5413 N CLARK', 'date': '07/04/2012'}</span></span><br><span class="line"><span class="comment"># {'address': '5415 N RAVENSWOOD', 'date': '07/04/2012'}</span></span><br><span class="line"><span class="comment"># 07 / 09 / 2012</span></span><br><span class="line"><span class="comment"># {'address': '5417 W CLARK', 'date': '07/09/2012'}</span></span><br><span class="line"><span class="comment"># 07 / 12 / 2012</span></span><br><span class="line"><span class="comment"># {'address': '5416 N ADDISON', 'date': '07/12/2012'}</span></span><br><span class="line"><span class="comment"># 08 / 01 / 2012</span></span><br><span class="line"><span class="comment"># {'address': '5418 N BROADWAY', 'date': '08/01/2012'}</span></span><br></pre></td></tr></table></figure><p>函数groupby()通过扫描序列找出拥有相同值(或是由参数key指定的函数所返回的值)的序列,并将它们分组.groupby()创建了一个迭代器,而且在每次迭代的时候都会返回一个值(value)和一个子迭代器(sub_iterator),这个子迭代器可以产生所有在改分组内具有该值的项.</p><p>在这里重要的首先要根据感兴趣的字段对数据进行排序.因为groupby()只能检查连续的项,不首先排序的话,将无法按所想的方式来对记录分组.</p><p>如果只是简单的根据日期分组到一起放进一个大的数据结构中以允许进行随机访问,那么利用defaultdict()构建一个一键多值字典(multidict(),)可能会更好</p><p>例如:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> defaultdict</span><br><span class="line">rows_by_date = defaultdict(<span class="built_in">list</span>)</span><br><span class="line"><span class="keyword">for</span> row <span class="keyword">in</span> rows:</span><br><span class="line"> rows_by_date[row[<span class="string">'date'</span>]].append(row)</span><br><span class="line"></span><br><span class="line"><span class="comment">#这使得我们可以方便的访问每个星期的日期的记录</span></span><br><span class="line"><span class="keyword">for</span> r <span class="keyword">in</span> rows_by_date[<span class="string">'07/01/2012'</span>]:</span><br><span class="line"> <span class="built_in">print</span>(r)</span><br><span class="line"><span class="comment"># {'address': '5412 N CLARK', 'date': '07/01/2012'}</span></span><br></pre></td></tr></table></figure><p>对于后面这个例子我们不需要先对记录做排序,因此如果不考虑内存方面的影响这种方式比先排序然后用groupby()要迭代的更快.</p><h4 id="1-16-筛选序列中的元素"><a href="#1-16-筛选序列中的元素" class="headerlink" title="1.16 筛选序列中的元素"></a>1.16 筛选序列中的元素</h4><p>问题 序列中含有一些数据,我们需要提取其中的值或根据某一些标准对序列做删减.</p><p>解决方案</p><p>列表推导式( list comprehension).</p><figure class="highlight py"><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">mylist=[<span class="number">1</span>,<span class="number">4</span>,-<span class="number">1</span>,<span class="number">10</span>,<span class="number">24</span>,<span class="number">12</span>,<span class="number">512</span>]</span><br><span class="line">x_p=[n <span class="keyword">for</span> n <span class="keyword">in</span> mylist <span class="keyword">if</span> n><span class="number">0</span>]</span><br><span class="line">x_n=[n <span class="keyword">for</span> n <span class="keyword">in</span> mylist <span class="keyword">if</span> n<<span class="number">0</span>]</span><br></pre></td></tr></table></figure><p>使用列表推导式的一个潜在缺点就是如果原始输入非常大的话,会产生一个很大的结果,如果这是要考虑的问题可以用使用生成器表达式通过迭代的方式产生筛选的结果.</p><figure class="highlight py"><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">mylist=[<span class="number">1</span>,<span class="number">4</span>,-<span class="number">1</span>,<span class="number">10</span>,<span class="number">24</span>,<span class="number">12</span>,<span class="number">512</span>]</span><br><span class="line">x_p=(n <span class="keyword">for</span> n <span class="keyword">in</span> mylist <span class="keyword">if</span> n><span class="number">0</span>)</span><br><span class="line">x_n=(n <span class="keyword">for</span> n <span class="keyword">in</span> mylist <span class="keyword">if</span> n<<span class="number">0</span>)</span><br><span class="line"><span class="built_in">print</span>(x_p,x_n)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> x_n:</span><br><span class="line"> <span class="built_in">print</span>(i)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> x_p:</span><br><span class="line"> <span class="built_in">print</span>(i)</span><br><span class="line"><span class="comment"># <generator object <genexpr> at 0x0000019B7DB0E580> <generator object <genexpr> at 0x0000019B7DB0E4A0></span></span><br><span class="line"><span class="comment"># -1</span></span><br><span class="line"><span class="comment"># 1</span></span><br><span class="line"><span class="comment"># 4</span></span><br><span class="line"><span class="comment"># 10</span></span><br><span class="line"><span class="comment"># 24</span></span><br><span class="line"><span class="comment"># 12</span></span><br><span class="line"><span class="comment"># 512</span></span><br></pre></td></tr></table></figure><p>有时候筛选的标准没法简单的表示在列表推导式或生成器表达式中.比如,假设筛选过程涉及异常处理或其他一些复杂的细节.基于此,可以将处理筛选的代码放在单独的函数中,然后使用内建的filter()函数处理.如下:</p><figure class="highlight py"><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">values=[<span class="string">'1'</span>,<span class="string">'2'</span>,<span class="string">'3'</span>,<span class="string">'4'</span>,<span class="string">'5'</span>,<span class="string">'-'</span>,<span class="string">'N/A'</span>,<span class="string">'5'</span>]</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">is_int</span>(<span class="params">val</span>):</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> x=<span class="built_in">int</span>(val)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">except</span> ValueError:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"></span><br><span class="line">ivals=<span class="built_in">list</span>(<span class="built_in">filter</span>(is_int,values))</span><br><span class="line"><span class="built_in">print</span>(ivals)</span><br><span class="line"><span class="comment"># ['1', '2', '3', '4', '5', '5']</span></span><br></pre></td></tr></table></figure><p>filter()创建了一个迭代器,因此如果我们想要的是列表形式的结果,请确保加上了list.</p><p>还有对数据的转化能力</p><figure class="highlight py"><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">mylist=[<span class="number">1</span>,<span class="number">4</span>,-<span class="number">5</span>,<span class="number">10</span>,-<span class="number">7</span>,<span class="number">2</span>,<span class="number">3</span>,-<span class="number">1</span>]</span><br><span class="line"><span class="keyword">import</span> math</span><br><span class="line">x=[math.sqrt(x) <span class="keyword">for</span> x <span class="keyword">in</span> mylist <span class="keyword">if</span> x><span class="number">0</span>]</span><br><span class="line"><span class="built_in">print</span>(x)</span><br><span class="line"><span class="comment"># [1.0, 2.0, 3.1622776601683795, 1.4142135623730951, 1.7320508075688772]</span></span><br></pre></td></tr></table></figure><p>关于数据筛选有可能是用新值换掉其他值而不是丢弃掉它们</p><figure class="highlight py"><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">mylist=[<span class="number">1</span>,<span class="number">4</span>,-<span class="number">5</span>,<span class="number">10</span>,-<span class="number">7</span>,<span class="number">2</span>,<span class="number">3</span>,-<span class="number">1</span>]</span><br><span class="line"><span class="comment"># import math</span></span><br><span class="line"><span class="comment"># x=[math.sqrt(x) for x in mylist if x>0]</span></span><br><span class="line"><span class="comment"># print(x)</span></span><br><span class="line"><span class="comment"># # [1.0, 2.0, 3.1622776601683795, 1.4142135623730951, 1.7320508075688772]</span></span><br><span class="line">clip_neq=[n <span class="keyword">if</span> n><span class="number">0</span> <span class="keyword">else</span> <span class="number">0</span> <span class="keyword">for</span> n <span class="keyword">in</span> mylist]</span><br><span class="line">clip_pos=[n <span class="keyword">if</span> n<<span class="number">0</span> <span class="keyword">else</span> <span class="number">0</span> <span class="keyword">for</span> n <span class="keyword">in</span> mylist]</span><br><span class="line"><span class="built_in">print</span>(clip_neq)</span><br><span class="line"><span class="built_in">print</span>(clip_pos)</span><br><span class="line"><span class="comment"># [1, 4, 0, 10, 0, 2, 3, 0]</span></span><br><span class="line"><span class="comment"># [0, 0, -5, 0, -7, 0, 0, -1]</span></span><br></pre></td></tr></table></figure><p>另一个工具是itertools.compress() 它接受一个可迭代对象以及一个布尔选择器序列对象作为输入,输出时他会给出所有在相应真的对象元素,如果想把一个序列筛选的结果施加到另一个相关序列上时,则将会非常有用.</p><figure class="highlight py"><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">rows=[</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5412 N CLARK'</span>,<span class="string">'date'</span>:<span class="string">'07/01/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5413 N CLARK'</span>, <span class="string">'date'</span>: <span class="string">'07/04/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5411 E 58TH'</span>, <span class="string">'date'</span>: <span class="string">'07/02/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5414 N CLARK'</span>, <span class="string">'date'</span>: <span class="string">'07/03/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5415 N RAVENSWOOD'</span>, <span class="string">'date'</span>: <span class="string">'07/04/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5416 N ADDISON'</span>, <span class="string">'date'</span>: <span class="string">'07/12/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5417 W CLARK'</span>, <span class="string">'date'</span>: <span class="string">'07/09/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5418 N BROADWAY'</span>, <span class="string">'date'</span>: <span class="string">'08/01/2012'</span>},</span><br><span class="line"> {<span class="string">'address'</span>: <span class="string">'5419 W GRANVILLE'</span>, <span class="string">'date'</span>: <span class="string">'02/01/2012'</span>}</span><br><span class="line">]</span><br><span class="line">addresses=[i[<span class="string">'address'</span>] <span class="keyword">for</span> i <span class="keyword">in</span> rows]</span><br><span class="line"><span class="comment"># for i in rows:</span></span><br><span class="line"><span class="comment"># print(i['address'])</span></span><br><span class="line">counts=[<span class="number">0</span>,<span class="number">3</span>,<span class="number">10</span>,<span class="number">4</span>,<span class="number">1</span>,<span class="number">7</span>,<span class="number">6</span>,<span class="number">1</span>]</span><br><span class="line"><span class="keyword">from</span> itertools <span class="keyword">import</span> compress</span><br><span class="line">more5=[n><span class="number">5</span> <span class="keyword">for</span> n <span class="keyword">in</span> counts]</span><br><span class="line"><span class="built_in">print</span>(more5)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(compress(addresses,more5)))</span><br><span class="line"><span class="comment"># [False, False, True, False, False, True, True, False]</span></span><br><span class="line"><span class="comment"># ['5411 E 58TH', '5416 N ADDISON', '5417 W CLARK']</span></span><br></pre></td></tr></table></figure><p>这里的关键在布尔序列对另一个序列做的映射</p><p>同filter()函数一样,正常情况下compress()会返回一个迭代器.因此如果需要的话,得使用list()将结果转化为列表.</p><h4 id="1-17-从字典中提取子集"><a href="#1-17-从字典中提取子集" class="headerlink" title="1.17 从字典中提取子集"></a>1.17 从字典中提取子集</h4><p>问题 创建是另一个字典子集的字典</p><p>解决方案</p><p>利用字典推导式</p><figure class="highlight py"><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">prices={<span class="string">'ACME'</span>:<span class="number">45.23</span>,<span class="string">'YYDS'</span>:<span class="number">11</span>,<span class="string">'YSXANBEI'</span>:<span class="number">114514</span>,<span class="string">'AAAAA'</span>:<span class="number">13341</span>}</span><br><span class="line"><span class="comment">#make a dict of all price over 200</span></span><br><span class="line">p1={key:value <span class="keyword">for</span> key,value <span class="keyword">in</span> prices.items() <span class="keyword">if</span> value><span class="number">200</span>}</span><br><span class="line"></span><br><span class="line"><span class="comment">#make a dict of tech stocks</span></span><br><span class="line">tech_names=[<span class="string">'ACME'</span>,<span class="string">'YYDS'</span>]</span><br><span class="line">p2={key:value <span class="keyword">for</span> key,value <span class="keyword">in</span> prices.items() <span class="keyword">if</span> key <span class="keyword">in</span> tech_names}</span><br><span class="line"><span class="built_in">print</span>(p1)</span><br><span class="line"><span class="built_in">print</span>(p2)</span><br><span class="line"><span class="comment"># {'YSXANBEI': 114514, 'AAAAA': 13341}</span></span><br><span class="line"><span class="comment"># {'ACME': 45.23, 'YYDS': 11}</span></span><br></pre></td></tr></table></figure><p>大部分字典推导式解决的问题也可以通过创建元组序列然后传给dict()解决</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">p1=<span class="built_in">dict</span>((key,value) <span class="keyword">for</span> key ,value <span class="keyword">in</span> prices.items() <span class="keyword">if</span> value ><span class="number">200</span>)</span><br></pre></td></tr></table></figure><p>但是字典推导方案更加清晰,运行效率也要快得多(本例2倍多).</p><figure class="highlight py"><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">tech_names={<span class="string">'A'</span>,<span class="string">'B'</span>,<span class="string">'C'</span>,<span class="string">'D'</span>}</span><br><span class="line">p2 ={key:prices[key] <span class="keyword">for</span> key <span class="keyword">in</span> prices.keys() &tech_names}</span><br></pre></td></tr></table></figure><p>但是要慢一些.</p><h4 id="1-18-将名称映射到序列的元素中"><a href="#1-18-将名称映射到序列的元素中" class="headerlink" title="1.18 将名称映射到序列的元素中"></a>1.18 将名称映射到序列的元素中</h4><p>问题 代码是通过位置来访问列表或者元组的,有时候会让代码难以阅读.希望用名称访问元素来减少对位置坐标的依赖性.</p><p>解决方案</p><p>相比普通的元组,collections.namedtuple()(命名元组)只增加了极小的开销就提供了这些便利.实际上collections.namedtuple()是一个工厂方法,它返回的是python中的标准元组的子类.提供一个类型名称和相应的字段,就返回一个可实例话的类.</p><p>Returns a new subclass of tuple with named fields.</p><blockquote><blockquote><blockquote><p>Point = namedtuple(‘Point’, [‘x’, ‘y’])<br>Point.<strong>doc</strong> # docstring for the new class<br>‘Point(x, y)’<br>p = Point(11, y=22) # instantiate with positional args or keywords<br>p[0] + p[1] # indexable like a plain tuple<br>33<br>x, y = p # unpack like a regular tuple<br>x, y<br>(11, 22)<br>p.x + p.y # fields also accessible by name<br>33<br>d = p._asdict() # convert to a dictionary<br>d[‘x’]<br>11<br>Point(**d) # convert from a dictionary<br>Point(x=11, y=22)<br>p._replace(x=100) # _replace() is like str.replace() but targets named fields<br>Point(x=100, y=22)</p></blockquote></blockquote></blockquote><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> namedtuple</span><br><span class="line">Subscriber = namedtuple(<span class="string">'Subscriber'</span>,[<span class="string">'addr'</span>,<span class="string">'joined'</span>])</span><br><span class="line">sub =Subscriber(<span class="string">'joinsy@example.com'</span>,<span class="string">'2012-10-19'</span>)</span><br><span class="line"><span class="built_in">print</span>(sub)</span><br><span class="line"><span class="built_in">print</span>(sub.addr)</span><br><span class="line"><span class="built_in">print</span>(sub.joined)</span><br><span class="line"><span class="comment"># Subscriber(addr='joinsy@example.com', joined='2012-10-19')</span></span><br><span class="line"><span class="comment"># joinsy@example.com</span></span><br><span class="line"><span class="comment"># 2012-10-19</span></span><br></pre></td></tr></table></figure><p>namedtuple的实例与普通元组是可以互换的,而且支持所有普通元组所支持的操作,例如引索(indexing)和分解(unpacking).</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="built_in">len</span>(sub))</span><br><span class="line">addr,joined=sub</span><br><span class="line"><span class="built_in">print</span>(addr,joined)</span><br><span class="line"><span class="comment"># 2</span></span><br><span class="line"><span class="comment"># joinsy@example.com 2012-10-19</span></span><br></pre></td></tr></table></figure><p>命名元组的主要作用是在与将代码同它所控制的元素位置间解耦.所以,如果从数据库调用中得到一个大型的元组列表,而且通过元组的位置来访问数据,那么假如在表单中新增一列数据,代码就会崩溃.但是如果首先将返回的元组转型为命名元组,就不会出现问题.</p><p>如下:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">compute_cost</span>(<span class="params">records</span>):</span></span><br><span class="line"> total=<span class="number">0.0</span></span><br><span class="line"> <span class="keyword">for</span> rec <span class="keyword">in</span> records:</span><br><span class="line"> total+=rec[<span class="number">1</span>]*rec[<span class="number">2</span>]</span><br><span class="line"> <span class="keyword">return</span> total</span><br><span class="line"><span class="comment">#通过位置应用元组常常使代码的表达能力不够强,而且也很依赖于具体的结构.</span></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> namedtuple</span><br><span class="line">Stock=namedtuple(<span class="string">'Stock'</span>,[<span class="string">'name'</span>,<span class="string">'shares'</span>,<span class="string">'price'</span>])</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">compute_cost_</span>(<span class="params">records</span>):</span></span><br><span class="line"> total=<span class="number">0.0</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span> rec <span class="keyword">in</span> records:</span><br><span class="line"> s=Stock(*rec)</span><br><span class="line"> total+=s.shares+s.price</span><br><span class="line"> <span class="keyword">return</span> total</span><br><span class="line"><span class="comment">#如果示例中的records列表已经包含了这样的实例,那么可以避免显式的将记录转化为Stock命名元组.</span></span><br></pre></td></tr></table></figure><p>namedtuple 的一种用法是作为字典的代替,dict的存储空间耗费更大,因此,如果要构建涉及更大的数据结构,namedtuple会更高效,但是namedtuple is tuple so,namedtuple is immutable.</p><figure class="highlight py"><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">s=Stock(<span class="string">'ACME'</span>,<span class="number">100</span>,<span class="number">123.45</span>)</span><br><span class="line"><span class="built_in">print</span>(s)</span><br><span class="line">s.price=<span class="number">12</span></span><br><span class="line"><span class="comment"># Stock(name='ACME', shares=100, price=123.45)</span></span><br><span class="line"><span class="comment"># Traceback (most recent call last):</span></span><br><span class="line"><span class="comment"># File "G:/Desktop/test/learn_py/struct_angl.py", line 443, in <module></span></span><br><span class="line"><span class="comment"># s.price=12</span></span><br><span class="line"><span class="comment"># AttributeError: can't set attribute</span></span><br></pre></td></tr></table></figure><p>如果需要修改任何属性,可以通过namedtuple的实例_replace()方法来实现.该方法创建一个全新的命名元组,并且相对应的值做替换.</p><figure class="highlight py"><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">s=s._replace(shares=<span class="number">12</span>)</span><br><span class="line"><span class="built_in">print</span>(s)</span><br><span class="line"><span class="comment">#Stock(name='ACME', shares=12, price=123.45)</span></span><br></pre></td></tr></table></figure><p>_replace()可以作为一种简单的方法填充具有可选或缺失字段的命名元组,做到这点,首先要用__replace()创建一个新的实例,把相应的值换掉.</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> namedtuple</span><br><span class="line">Stock=namedtuple(<span class="string">'Stock'</span>,[<span class="string">'name'</span>,<span class="string">'shares'</span>,<span class="string">'prices'</span>,<span class="string">'date'</span>,<span class="string">'time'</span>])</span><br><span class="line"><span class="comment">#Create a prototype instance</span></span><br><span class="line">stock_protype = Stock(<span class="string">''</span>,<span class="number">0</span>,<span class="number">0.0</span>,<span class="literal">None</span>,<span class="literal">None</span>)</span><br><span class="line"><span class="comment">#Function to convert a dictionary to a stock</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">dict_to_stock</span>(<span class="params">s</span>):</span></span><br><span class="line"> <span class="keyword">return</span> stock_protype._replace(**s)</span><br><span class="line">a={<span class="string">'name'</span>:<span class="string">'CSX'</span>,<span class="string">'shares'</span>:<span class="number">100</span>,<span class="string">'prices'</span>:<span class="number">123.45</span>}</span><br><span class="line">a_=dict_to_stock(a)</span><br><span class="line"><span class="built_in">print</span>(a_)</span><br><span class="line">b={<span class="string">'name'</span>:<span class="string">'ZSQ'</span>,<span class="string">'shares'</span>:<span class="number">520</span>,<span class="string">'prices'</span>:<span class="number">13.14</span>,<span class="string">'date'</span>:<span class="string">'4/8/2015'</span>}</span><br><span class="line">b_=dict_to_stock(b)</span><br><span class="line"><span class="built_in">print</span>(b_)</span><br><span class="line"><span class="comment"># Stock(name='CSX', shares=100, prices=123.45, date=None, time=None)</span></span><br><span class="line"><span class="comment"># Stock(name='ZSQ', shares=520, prices=13.14, date='4/8/2015', time=None)</span></span><br></pre></td></tr></table></figure><p>最后,相当重要的是要注意我们的目标是定义一个高效的数据结构,而且将会修改各种实例属性,那么使用namedtuple不是最佳的选择,相反可以考虑定义一个使用__slots__属性的类.</p><h4 id="1-19-同时对数据做转换和换算"><a href="#1-19-同时对数据做转换和换算" class="headerlink" title="1.19 同时对数据做转换和换算"></a>1.19 同时对数据做转换和换算</h4><p>问题 调用一个换算(reduction)函数(sum,min,max)但是首先要对数据筛选</p><p>解决方法</p><p>使用生成器表达式.</p><figure class="highlight py"><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">nums=[i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>)]</span><br><span class="line">s=<span class="built_in">sum</span>(x*x <span class="keyword">for</span> x <span class="keyword">in</span> nums)</span><br></pre></td></tr></table></figure><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#Determine if any .py file exist in a directory</span></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line">files=os.listdir(<span class="string">'dirname'</span>)</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">any</span>(name.endswith(<span class="string">'.py'</span>) <span class="keyword">for</span> name <span class="keyword">in</span> files):</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'there be py'</span>)</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'no py'</span>)</span><br><span class="line"><span class="comment">#output a tuple as csv</span></span><br><span class="line">s=(<span class="string">'ACM'</span>,<span class="number">50</span>,<span class="number">123.45</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">','</span>.join(<span class="built_in">str</span>(i) <span class="keyword">for</span> i <span class="keyword">in</span> s))</span><br><span class="line"><span class="comment">#Data reduction across fields of a data strcture</span></span><br><span class="line">portfolio=[</span><br><span class="line"> {<span class="string">'name'</span>:<span class="string">'A'</span>,<span class="string">'shares'</span>:<span class="number">50</span>},</span><br><span class="line"> {<span class="string">'name'</span>: <span class="string">'B'</span>, <span class="string">'shares'</span>: <span class="number">52</span>},</span><br><span class="line"> {<span class="string">'name'</span>: <span class="string">'V'</span>, <span class="string">'shares'</span>: <span class="number">51</span>},</span><br><span class="line"> {<span class="string">'name'</span>: <span class="string">'S'</span>, <span class="string">'shares'</span>: <span class="number">1</span>},</span><br><span class="line"> {<span class="string">'name'</span>: <span class="string">'x'</span>, <span class="string">'shares'</span>: <span class="number">5</span>}</span><br><span class="line">]</span><br><span class="line">min_shares=<span class="built_in">min</span>(s[<span class="string">'shares'</span>] <span class="keyword">for</span> s <span class="keyword">in</span> portfolio)</span><br></pre></td></tr></table></figure><p>把生成器作为函数表达式的单独参数时在语法上的一些微妙之处(不必重复使用括号)sum((x for x in nums))和sum(x for x in nums )是一个意思.</p><p>比起创建一个临时列表,生成器更加高效和优雅.</p><figure class="highlight py"><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">min_shares=<span class="built_in">min</span>(s[<span class="string">'shares'</span>] <span class="keyword">for</span> s <span class="keyword">in</span> portfolio)</span><br><span class="line"><span class="comment">#Alternative return {'name':'S','shares':1}</span></span><br><span class="line">min_shares_=<span class="built_in">min</span>(portfolio,key=<span class="keyword">lambda</span> s:s[<span class="string">'shares'</span>])</span><br></pre></td></tr></table></figure><h4 id="1-20-将多个映射合并为单个映射"><a href="#1-20-将多个映射合并为单个映射" class="headerlink" title="1.20 将多个映射合并为单个映射"></a>1.20 将多个映射合并为单个映射</h4><p>问题 我们有多个字典,想在逻辑上将它们合并为一个单独的映射结构,以此做一些特定的操作,比如查找值或则键是否存在.</p><p>解决方法:</p><figure class="highlight py"><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">a={<span class="string">'x'</span>:<span class="number">1</span>,<span class="string">'z'</span>:<span class="number">3</span>}</span><br><span class="line">b={<span class="string">'y'</span>:<span class="number">2</span>,<span class="string">'z'</span>:<span class="number">4</span>}</span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> ChainMap</span><br><span class="line">c=ChainMap(a,b)</span><br><span class="line"><span class="built_in">print</span>(c[<span class="string">'x'</span>])<span class="comment">#from a</span></span><br><span class="line"><span class="built_in">print</span>(c[<span class="string">'y'</span>])<span class="comment">#from b</span></span><br><span class="line"><span class="built_in">print</span>(c[<span class="string">'z'</span>])<span class="comment">#from a</span></span><br></pre></td></tr></table></figure><p>ChainMap可接受多个映射然后在逻辑上使他们表现为一个单独的映射结构.但是这些映射在字面上并不会合并在一起.ChainMap 只是简单的维护一个记录底层映射的列表,然后重新定义常见的字典操作来扫描这个表.</p><figure class="highlight py"><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="built_in">print</span>(<span class="built_in">len</span>(c))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(c.keys()))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(c.values()))</span><br><span class="line"><span class="comment"># 3</span></span><br><span class="line"><span class="comment"># ['y', 'z', 'x']</span></span><br><span class="line"><span class="comment"># [2, 3, 1]</span></span><br></pre></td></tr></table></figure><p>如果有重复的键,会对应第一个映射采用的值修改操作也是对应第一个映射结构上.</p><p>ChainMap与带有作用域的值如编程语言中的变量一起工作时特别有用.</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> ChainMap</span><br><span class="line">values=ChainMap()</span><br><span class="line">values[<span class="string">'x'</span>]=<span class="number">1</span></span><br><span class="line"><span class="comment">#add a new mapping</span></span><br><span class="line">values =values.new_child()</span><br><span class="line">values[<span class="string">'x'</span>]=<span class="number">2</span></span><br><span class="line"><span class="comment">#add a new mapping</span></span><br><span class="line">values=values.new_child()</span><br><span class="line">values[<span class="string">'x'</span>]=<span class="number">3</span></span><br><span class="line"><span class="built_in">print</span>(values)</span><br><span class="line"><span class="built_in">print</span>(values[<span class="string">'x'</span>])</span><br><span class="line"><span class="comment">#Discard last mapping</span></span><br><span class="line">values=values.parents</span><br><span class="line"><span class="built_in">print</span>(values[<span class="string">'x'</span>])</span><br><span class="line"><span class="comment">#Discard last mapping</span></span><br><span class="line">values=values.parents</span><br><span class="line"><span class="built_in">print</span>(values[<span class="string">'x'</span>])</span><br><span class="line"><span class="built_in">print</span>(values)</span><br><span class="line"><span class="comment"># ChainMap({'x': 3}, {'x': 2}, {'x': 1})</span></span><br><span class="line"><span class="comment"># 3</span></span><br><span class="line"><span class="comment"># 2</span></span><br><span class="line"><span class="comment"># 1</span></span><br><span class="line"><span class="comment"># ChainMap({'x': 1})</span></span><br></pre></td></tr></table></figure><p>作为ChainMap的替代方案,利用update()方法将多个字典合并在一起.</p><figure class="highlight py"><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">a={<span class="string">'x'</span>:<span class="number">1</span>,<span class="string">'z'</span>:<span class="number">3</span>}</span><br><span class="line">b={<span class="string">'y'</span>:<span class="number">2</span>,<span class="string">'z'</span>:<span class="number">4</span>}</span><br><span class="line"><span class="comment"># merged=dict(b)</span></span><br><span class="line"><span class="comment"># merged.update(a)</span></span><br><span class="line"><span class="comment"># print(merged)</span></span><br><span class="line"><span class="comment"># print(merged['x'])</span></span><br><span class="line"><span class="comment"># print(merged['y'])</span></span><br><span class="line"><span class="comment"># print(merged['z'])</span></span><br><span class="line"><span class="comment"># {'y': 2, 'z': 4, 'x': 1, 'Z': 3}</span></span><br><span class="line"><span class="comment"># 1</span></span><br><span class="line"><span class="comment"># 2</span></span><br><span class="line"><span class="comment"># 4</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#行得通但是需要单独构建一个完整的字典对象(或修改其中一个原有的字典,破坏原始数据.如果原始数据修改了不会反应到合并后的字典中</span></span><br><span class="line"><span class="comment"># a['x']=3</span></span><br><span class="line"><span class="comment"># print(merged['x'])</span></span><br><span class="line"><span class="comment">#1</span></span><br><span class="line"><span class="comment">#但是ChainMap使用的就是原始的字典,所以会反应关联</span></span><br><span class="line"><span class="keyword">from</span> collections <span class="keyword">import</span> ChainMap</span><br><span class="line">merged_=ChainMap(a,b)</span><br><span class="line"><span class="built_in">print</span>(merged_[<span class="string">'x'</span>])</span><br><span class="line">a[<span class="string">'x'</span>]=<span class="number">42</span></span><br><span class="line"><span class="built_in">print</span>(merged_[<span class="string">'x'</span>])<span class="comment">#Notice change to merged dicts</span></span><br><span class="line"><span class="comment"># 1</span></span><br><span class="line"><span class="comment"># 42</span></span><br></pre></td></tr></table></figure>]]></content>
</entry>
<entry>
<title>AFCTF2018 MyOwnCBC</title>
<link href="/2021/07/13/%5BAFCTF2018%5DMyOwnCBC/"/>
<url>/2021/07/13/%5BAFCTF2018%5DMyOwnCBC/</url>
<content type="html"><![CDATA[<h1 id="AFCTF2018-MyOwnCBC"><a href="#AFCTF2018-MyOwnCBC" class="headerlink" title="[AFCTF2018]MyOwnCBC"></a>[AFCTF2018]MyOwnCBC</h1><p>一 什么是CBC模式</p><p>CBC模式的全称是Cipher Block Chaining模式(密文分组链接模式),之所以叫这个名字,是因为密文分组像链条一样相互连接在一起。</p><p>在CBC模式中,首先将明文分组与前一个密文分组进行XOR运算,然后再进行加密。</p><p>CBC模式加解密过程如下:</p><p><img "" class="lazyload placeholder" data-original="C:\Users\Hetaoren4\AppData\Roaming\Typora\typora-user-images\image-20210713072106953.png" src="https://img10.360buyimg.com/ddimg/jfs/t1/157667/29/9156/134350/603c6445Ebbc9cabe/41219c5d36d45072.gif" alt="image-20210713072106953"></p><p>我们来比较一下ECB模式与CBC模式的区别</p><p><img "" class="lazyload placeholder" data-original="C:\Users\Hetaoren4\AppData\Roaming\Typora\typora-user-images\image-20210713072124484.png" src="https://img10.360buyimg.com/ddimg/jfs/t1/157667/29/9156/134350/603c6445Ebbc9cabe/41219c5d36d45072.gif" alt="image-20210713072124484"></p><p>ECB模式只进行了加密,而CBC模式则在加密之前进行了一次XOR。</p><p>二 初始化向量</p><p>当加密第一个明文分组时,由于不存在“前一个密文分组”,因此需要事先准备一个长度为一个分组的比特序列来代替“前一个密文分组”,这个比特序列称为初始化向量(Initialization Vector),通常缩写为IV,一般来说,每次加密时都会随机产生一个不同的比特序列来作为初始化向量。</p><p>三 CBC模式的特点</p><p>明文分组在加密之前一定会与“前一个密文分组”进行XOR运算,因此即使明文分组1和明文分组2的值是相等的,密文分组1和2的值也不一定是相等的。这样一来,ECB模式的缺陷在CBC模式中就不存在了。</p><p>加密过程:在CBC模式中,无法单独对一个中间的明文分组进行加密。例如,如果要生成密文分组3,则至少需要凑齐明文分组1、2、3才行。</p><p>解密过程:假设CBC模式加密的密文分组中有一个分组损坏了。在这种情况下,只要密文分组的长度没有发生变化,则解密时最多只有2个分组受到数据损坏的影响。见下图:</p><p><img "" class="lazyload placeholder" data-original="C:\Users\Hetaoren4\AppData\Roaming\Typora\typora-user-images\image-20210713072148785.png" src="https://img10.360buyimg.com/ddimg/jfs/t1/157667/29/9156/134350/603c6445Ebbc9cabe/41219c5d36d45072.gif" alt="image-20210713072148785"></p><p>假设CBC模式的密文分组中有一些比特缺失了,那么此时即便只缺失1比特,也会导致密文分组的长度发生变化,此后的分组发生错位,这样一来,缺失比特的位置之后的密文分组也就全部无法解密。见下图:</p><p><img "" class="lazyload placeholder" data-original="C:\Users\Hetaoren4\AppData\Roaming\Typora\typora-user-images\image-20210713072157986.png" src="https://img10.360buyimg.com/ddimg/jfs/t1/157667/29/9156/134350/603c6445Ebbc9cabe/41219c5d36d45072.gif" alt="image-20210713072157986"></p><p>四 对CBC模式的攻击</p><p>假设主动攻击者的目的是通过修改密文来操纵解密后的明文。如果攻击者能够对初始化向量中的任意比特进行反转(将1变成0,将0变成1),则明文分组中相应的比特也会被反转。这是因为在CBC模式的解密过程中,第一个明文分组会和初始化向量进行XOR运算。见下图。</p><p><img "" class="lazyload placeholder" data-original="C:\Users\Hetaoren4\AppData\Roaming\Typora\typora-user-images\image-20210713072206698.png" src="https://img10.360buyimg.com/ddimg/jfs/t1/157667/29/9156/134350/603c6445Ebbc9cabe/41219c5d36d45072.gif" alt="image-20210713072206698"></p><p>但是想对密文分组也进行同样的攻击就非常困难了。例如,如果攻击者将密文分组1中的某个比特进行反转,则明文分组2中相应比特也会被反转,然而这一比特的变化却对解密后的明文分组1中的多个比特造成了影响,也就是说,只让明文分1中所期望的特定比特发生变化是很困难的。</p><p>五 填充提示攻击</p><p>填充提示攻击是一种利用分组密码中填充部分来进行攻击的方法。在分组密码中,当明文长度不为分组长度的整数倍时,需要在最后一个分组中填充一些数据使其凑满一个分组长度。在填充提示攻击中,攻击者会反复发送一段密文,每次发送时都对填充数据进行少许改变。由于接收者(服务器)在无法正确解密时会返回一个错误消息,攻击者通过这一错误消息就可以获得一部分与明文相关的信息。这一攻击并不仅限于CBC模式,而是适用所有需要进行分组填充的模式。</p><p>2014年对SSL3.0 造成了重大影响POODLE攻击实际上就是一种填充示攻击。</p><p>六 对初始化向量(IV)进行攻击</p><p>初始化向量(IV)必须使用不可预测的随机数。然而在SSL/TLS的TLS1.0版本协议中,IV并没有使用不可预测的随机数,而是使用上一次CBC模式加密时的最后一个分组。为了防御攻击者对此进行攻击,TLS1.1以上的版本中改为了必须显示传送IV。</p><p>七 CBC模式应用</p><p>确保互联网安全的通信协议之一SSL/TLS,就是使用CBC模式来确保通信机密性的,如使用CBC模式三重DES的3DES_EDE_CBC以及CBC模式256比特AES的AES_256_CBC等。<br>CBC模式解读原文链接:<a href="https://blog.csdn.net/chengqiuming/article/details/82288851">https://blog.csdn.net/chengqiuming/article/details/82288851</a></p><p>题面:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">CBC什么东西呀?不就是把上一轮加密的影响扩散到下一轮嘛</span><br><span class="line">它写的CBC一点都不正宗</span><br><span class="line">我这样写肯定也行的!</span><br><span class="line"></span><br><span class="line">大概吧?</span><br></pre></td></tr></table></figure><p>MyOwnCRC.py</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> AES</span><br><span class="line"><span class="keyword">from</span> Crypto.Random <span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> long_to_bytes</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">MyOwnCBC</span>(<span class="params">key, plain</span>):</span></span><br><span class="line"> <span class="keyword">if</span> <span class="built_in">len</span>(key) != <span class="number">32</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"error!"</span></span><br><span class="line"> cipher_txt = <span class="string">b""</span></span><br><span class="line"> cipher_arr = []</span><br><span class="line"> cipher = AES.new(key, AES.MODE_ECB, <span class="string">""</span>)</span><br><span class="line"> plain = [plain[i:i + <span class="number">32</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(plain), <span class="number">32</span>)]</span><br><span class="line"> <span class="built_in">print</span></span><br><span class="line"> plain</span><br><span class="line"> cipher_arr.append(cipher.encrypt(plain[<span class="number">0</span>]))</span><br><span class="line"> cipher_txt += cipher_arr[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="built_in">len</span>(plain)):</span><br><span class="line"> cipher = AES.new(cipher_arr[i - <span class="number">1</span>], AES.MODE_ECB, <span class="string">""</span>)</span><br><span class="line"> cipher_arr.append(cipher.encrypt(plain[i]))</span><br><span class="line"> cipher_txt += cipher_arr[i]</span><br><span class="line"> <span class="keyword">return</span> cipher_txt</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">key = random.getrandbits(<span class="number">256</span>)</span><br><span class="line">key = long_to_bytes(key)</span><br><span class="line"></span><br><span class="line">s = <span class="string">""</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">"flag.txt"</span>, <span class="string">"r"</span>) <span class="keyword">as</span> f:</span><br><span class="line"> s = f.read()</span><br><span class="line"> f.close()</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">"flag_cipher"</span>, <span class="string">"wb"</span>) <span class="keyword">as</span> f:</span><br><span class="line"> f.write(MyOwnCBC(key, s))</span><br><span class="line"> f.close()</span><br></pre></td></tr></table></figure><p>加密过程就是用上一级的密文,作为下一次加密的密钥key,所以初始密钥key可以知道就是题目给的密文前32个,所以直接逆向解密就可以了。</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os, sys</span><br><span class="line"></span><br><span class="line">os.chdir(sys.path[<span class="number">0</span>])</span><br><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> AES</span><br><span class="line"><span class="keyword">from</span> Crypto.Random <span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">cipher = <span class="built_in">open</span>(<span class="string">'flag_cipher.txt'</span>, <span class="string">'rb'</span>).read()</span><br><span class="line">key = cipher[<span class="number">0</span>:<span class="number">32</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># print(key)</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">MyOwnCBC</span>(<span class="params">key, cipher</span>):</span></span><br><span class="line"> cipher = [cipher[i:i + <span class="number">32</span>] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(cipher), <span class="number">32</span>)]</span><br><span class="line"> flag = <span class="string">b''</span></span><br><span class="line"> tempkey = key</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="built_in">len</span>(cipher)):</span><br><span class="line"> dic_cipher = AES.new(tempkey, AES.MODE_ECB)</span><br><span class="line"> flag += dic_cipher.decrypt(cipher[i])</span><br><span class="line"> tempkey = cipher[i]</span><br><span class="line"> <span class="keyword">return</span> flag</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(MyOwnCBC(key, cipher))</span><br></pre></td></tr></table></figure><p>结果:afctf{Don’t_be_fooled_by_yourself}</p>]]></content>
</entry>
<entry>
<title>One Secret, Two encryption</title>
<link href="/2021/07/11/AFCTF2018One%20Secret,%20Two%20encryption/"/>
<url>/2021/07/11/AFCTF2018One%20Secret,%20Two%20encryption/</url>
<content type="html"><![CDATA[<h1 id="AFCTF2018-One-Secret-Two-encryption"><a href="#AFCTF2018-One-Secret-Two-encryption" class="headerlink" title="[AFCTF2018]One Secret, Two encryption"></a>[AFCTF2018]One Secret, Two encryption</h1><h4 id="在线公钥解析网站"><a href="#在线公钥解析网站" class="headerlink" title="在线公钥解析网站:"></a>在线公钥解析网站:</h4><h4 id="https-www-ssleye-com-pub-asysi-html"><a href="#https-www-ssleye-com-pub-asysi-html" class="headerlink" title="https://www.ssleye.com/pub_asysi.html"></a><a href="https://www.ssleye.com/pub_asysi.html">https://www.ssleye.com/pub_asysi.html</a></h4><p>解析之后获得:e1,e2,n1,n2</p><p>根据题目One Secret, Two encryption猜到 gcd(n1,n2)!=1</p><p>解密脚本:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">e1 = <span class="number">1666626632960368239001159408047765991270250042206244157447171188195657302933019501932101777999510001235736338843107709871785906749393004257614129802061081155861433722380145001537181142613515290138835765236002811689986472280762408157176437503021753061588746520433720734608953639111558556930490721517579994493088551013050835690019772600744317398218183883402192060480979979456469937863257781362521184578142129444122428832106721725409309113975986436241662107879085361014650716439042856013203440242834878648506244428367706708431121109714505981728529818874621868624754285069693368779495316600601299037277003994790396589299</span></span><br><span class="line">e2 = <span class="number">65537</span></span><br><span class="line">n1 = <span class="number">4850297138162223468826481623082440249579136876798312652735204698689613969008632545220976699170308454082390834742570718247804202060929493571642074679428565168405877110681518105667301785653517697684490982375078989886040451115082120928982588380914609273008153977907950532498605486225883973643141516024058315360572988744607134110254489421516026937249163493982681336628726033489124705657217768229058487155865265080427488028921879608338898933540825564889012166181346177276639828346376362168934208822467295673761876965864573164529336885250577357767314256581019474130651412100897839606491189424373959244023695669653213498329</span></span><br><span class="line">n2 = <span class="number">2367536768672000959668181171787295271898789288397672997134843418932405959946739637368044420319861797856771490573443003520137149324080217971836780570522258661419034481514883068092752166752967879497095564732505614751532330408675056285275354250157955321457579006360393218327164804951384290041956551855334492796719901818165788902547584563455747941517296875697241841177219635024461395596117584194226134777078874543699117761893699634303571421106917894215078938885999963580586824497040073241055890328794310025879014294051230590716562942538031883965317397728271589759718376073414632026801806560862906691989093298478752580277</span></span><br><span class="line"><span class="keyword">import</span> gmpy2</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(gmpy2.gcd(n1,n2))</span><br><span class="line">p11 = <span class="number">174410123761631337520799179808598127914184971978811796722414215239874114048347830609255805203105210941441708658356189056418366104015120153227123562166980882513945308613658062284844636341082646995916907680076101741743945938845994542592182491688095893467336553001430454260431413695816790105384153941685561590503</span></span><br><span class="line">p12 = n1 // p11</span><br><span class="line">p21 = <span class="number">174410123761631337520799179808598127914184971978811796722414215239874114048347830609255805203105210941441708658356189056418366104015120153227123562166980882513945308613658062284844636341082646995916907680076101741743945938845994542592182491688095893467336553001430454260431413695816790105384153941685561590503</span></span><br><span class="line">p22 = n2 // p21</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> rsa</span><br><span class="line">d2 = <span class="built_in">int</span>(gmpy2.invert(e2, (p21 - <span class="number">1</span>) * (p22 - <span class="number">1</span>)))</span><br><span class="line">Rsa = rsa.PrivateKey(n2, e2, d2, p21, p22)</span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">'G:\\Desktop\\flag_encry2'</span>,<span class="string">'rb'</span>) <span class="keyword">as</span> f:</span><br><span class="line"> cipher1=f.read()</span><br><span class="line"> <span class="built_in">print</span>(rsa.decrypt(cipher2, Rsa))</span><br></pre></td></tr></table></figure><p>结果:b’OpenSSL is widely used\r\nflag is afctf{You_Know_0p3u55I}’</p>]]></content>
</entry>
<entry>
<title>AFCTF2018MagicNum</title>
<link href="/2021/07/11/AFCTF2018MagicNum/"/>
<url>/2021/07/11/AFCTF2018MagicNum/</url>
<content type="html"><![CDATA[<h2 id="AFCTF2018MagicNum"><a href="#AFCTF2018MagicNum" class="headerlink" title="AFCTF2018MagicNum"></a>AFCTF2018MagicNum</h2><p>题目:where_is_flag</p><p>72065910510177138000000000000000.000000<br>71863209670811371000000.000000<br>18489682625412760000000000000000.000000<br>72723257588050687000000.000000<br>4674659167469766200000000.000000<br>19061698837499292000000000000000000000.000000</p><p>显然是从浮点数转字节:</p><p>解秘脚本:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> struct <span class="keyword">import</span> pack</span><br><span class="line">msg=<span class="string">'''72065910510177138000000000000000.000000</span></span><br><span class="line"><span class="string">71863209670811371000000.000000</span></span><br><span class="line"><span class="string">18489682625412760000000000000000.000000</span></span><br><span class="line"><span class="string">72723257588050687000000.000000</span></span><br><span class="line"><span class="string">4674659167469766200000000.000000</span></span><br><span class="line"><span class="string">19061698837499292000000000000000000000.000000'''</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> msg.split(<span class="string">'\n'</span>):</span><br><span class="line"> <span class="comment"># print(i)</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="built_in">str</span>(pack(<span class="string">'f'</span>, <span class="built_in">float</span>(i)))[<span class="number">2</span>:-<span class="number">1</span>],end=<span class="string">""</span>)</span><br></pre></td></tr></table></figure><p>结果:afctf{sec_is_everywhere}</p>]]></content>
</entry>
<entry>
<title>GKCTF 2021Random</title>
<link href="/2021/07/09/Crypto/"/>
<url>/2021/07/09/Crypto/</url>
<content type="html"><![CDATA[<h2 id="GKCTF-2021-Random"><a href="#GKCTF-2021-Random" class="headerlink" title="[GKCTF 2021]Random"></a>[GKCTF 2021]Random</h2><p>flag是上述随机数生成后再生成一个32位(以位为单位)的随机数</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># import random</span></span><br><span class="line"><span class="comment"># from hashlib import md5</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># def get_mask():</span></span><br><span class="line"><span class="comment"># file = open(r"G:\Desktop\rar\random.txt","r")</span></span><br><span class="line"><span class="comment"># for i in range(104):</span></span><br><span class="line"><span class="comment"># file.write(str(random.getrandbits(32))+"\n")</span></span><br><span class="line"><span class="comment"># file.write(str(random.getrandbits(64))+"\n")</span></span><br><span class="line"><span class="comment"># file.write(str(random.getrandbits(96))+"\n")</span></span><br><span class="line"><span class="comment"># file.close()</span></span><br><span class="line"><span class="comment"># get_mask()</span></span><br><span class="line"><span class="comment"># flag = md5(str(random.getrandbits(32)).encode()).hexdigest()</span></span><br><span class="line"><span class="comment"># print(flag)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="keyword">from</span> hashlib <span class="keyword">import</span> md5</span><br><span class="line"><span class="keyword">from</span> randcrack <span class="keyword">import</span> RandCrack</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">foo</span>(<span class="params">l,i</span>):</span></span><br><span class="line"> a=[] <span class="comment">#32 64 96</span></span><br><span class="line"> a.append(l[i]) <span class="comment">#32位</span></span><br><span class="line"> b1=l[i+<span class="number">1</span>]>><span class="number">32</span></span><br><span class="line"> b2=l[i+<span class="number">1</span>]&(<span class="number">2</span>**<span class="number">32</span>-<span class="number">1</span>)</span><br><span class="line"> a.append(b2)<span class="comment">#64位的低32位</span></span><br><span class="line"> a.append(b1)<span class="comment">#64位的高32位</span></span><br><span class="line"> b1=l[i+<span class="number">2</span>]>><span class="number">64</span></span><br><span class="line"> b2=(l[i+<span class="number">2</span>]&(<span class="number">2</span>**<span class="number">64</span>-<span class="number">1</span>))>><span class="number">32</span></span><br><span class="line"> b3=l[i+<span class="number">2</span>]&(<span class="number">2</span>**<span class="number">32</span>-<span class="number">1</span>)</span><br><span class="line"> a.append(b3)<span class="comment">#96位的低32位</span></span><br><span class="line"> a.append(b2)<span class="comment">#96位的中32位</span></span><br><span class="line"> a.append(b1)<span class="comment">#96位的高32位</span></span><br><span class="line"> <span class="keyword">return</span> a</span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">r'G:\Desktop\rar\random.txt'</span>,<span class="string">'r'</span>) <span class="keyword">as</span> f:</span><br><span class="line"> l=f.readlines()</span><br><span class="line">l=[<span class="built_in">int</span>(i.strip()) <span class="keyword">for</span> i <span class="keyword">in</span> l]</span><br><span class="line">ll=[]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>,<span class="built_in">len</span>(l),<span class="number">3</span>):</span><br><span class="line"> ll+=foo(l,i)</span><br><span class="line">rc=RandCrack()</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> ll:</span><br><span class="line"> rc.submit(i)</span><br><span class="line">aa=rc.predict_getrandbits(<span class="number">32</span>)</span><br><span class="line"><span class="built_in">print</span>(aa)</span><br><span class="line"><span class="built_in">print</span>(md5(<span class="built_in">str</span>(aa).encode()).hexdigest())</span><br><span class="line"><span class="comment"># print('flag{%s}'%md5(str(aa).encode()).hexdigest())</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#每624个32位数字给生成器喂食,题目正好给了这么多,(32+64+96)*104=624*32</span></span><br></pre></td></tr></table></figure><p>python的rng用的mt19937,考烂了</p><p>用randcrack模块梭</p><figure class="highlight py"><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="keyword">from</span> hashlib <span class="keyword">import</span> md5</span><br><span class="line"><span class="keyword">from</span> randcrack <span class="keyword">import</span> RandCrack</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">foo</span>(<span class="params">l,i</span>):</span></span><br><span class="line"> a=[]</span><br><span class="line"> a.append(l[i])</span><br><span class="line"> b1=l[i+<span class="number">1</span>]>><span class="number">32</span></span><br><span class="line"> b2=l[i+<span class="number">1</span>]&(<span class="number">2</span>**<span class="number">32</span>-<span class="number">1</span>)</span><br><span class="line"> a.append(b2)</span><br><span class="line"> a.append(b1)</span><br><span class="line"> b1=l[i+<span class="number">2</span>]>><span class="number">64</span></span><br><span class="line"> b2=(l[i+<span class="number">2</span>]&(<span class="number">2</span>**<span class="number">64</span>-<span class="number">1</span>))>><span class="number">32</span></span><br><span class="line"> b3=l[i+<span class="number">2</span>]&(<span class="number">2</span>**<span class="number">32</span>-<span class="number">1</span>)</span><br><span class="line"> a.append(b3)</span><br><span class="line"> a.append(b2)</span><br><span class="line"> a.append(b1)</span><br><span class="line"> <span class="keyword">return</span> a</span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">r'random.txt'</span>,<span class="string">'r'</span>) <span class="keyword">as</span> f:</span><br><span class="line"> l=f.readlines()</span><br><span class="line">l=[<span class="built_in">int</span>(i.strip()) <span class="keyword">for</span> i <span class="keyword">in</span> l]</span><br><span class="line">ll=[]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>,<span class="built_in">len</span>(l),<span class="number">3</span>):</span><br><span class="line"> ll+=foo(l,i)</span><br><span class="line">rc=RandCrack()</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> ll:</span><br><span class="line"> rc.submit(i)</span><br><span class="line">aa=rc.predict_getrandbits(<span class="number">32</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'flag{%s}'</span>%md5(<span class="built_in">str</span>(aa).encode()).hexdigest())</span><br></pre></td></tr></table></figure><p>结果:GKCTF{14c71fec812b754b2061a35a4f6d8421}</p>]]></content>
</entry>
<entry>
<title>GKCTF 2021 RRRRsa</title>
<link href="/2021/07/09/RRRRsa/"/>
<url>/2021/07/09/RRRRsa/</url>
<content type="html"><![CDATA[<h2 id="GKCTF-2021-RRRRsa"><a href="#GKCTF-2021-RRRRsa" class="headerlink" title="[GKCTF 2021]RRRRsa"></a>[GKCTF 2021]RRRRsa</h2><p>题目</p><figure class="highlight py"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> gmpy2 <span class="keyword">import</span> gcd</span><br><span class="line"></span><br><span class="line">flag = <span class="string">b'xxxxxxxxxxxxx'</span></span><br><span class="line">p = getPrime(<span class="number">512</span>)</span><br><span class="line">q = getPrime(<span class="number">512</span>)</span><br><span class="line">m = bytes_to_long(flag)</span><br><span class="line">n = p*q</span><br><span class="line">e = <span class="number">65537</span></span><br><span class="line">c = <span class="built_in">pow</span>(m,e,n)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'c={}'</span>.<span class="built_in">format</span>(c))</span><br><span class="line"></span><br><span class="line">p1 = getPrime(<span class="number">512</span>)</span><br><span class="line">q1 = getPrime(<span class="number">512</span>)</span><br><span class="line">n1 = p1*q1</span><br><span class="line">e1 = <span class="number">65537</span></span><br><span class="line"><span class="keyword">assert</span> gcd(e1,(p1-<span class="number">1</span>)*(q1-<span class="number">1</span>)) == <span class="number">1</span></span><br><span class="line">c1 = <span class="built_in">pow</span>(p,e1,n1)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'n1={}'</span>.<span class="built_in">format</span>(n1))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'c1={}'</span>.<span class="built_in">format</span>(c1))</span><br><span class="line">hint1 = <span class="built_in">pow</span>(<span class="number">2020</span> * p1 + q1, <span class="number">202020</span>, n1)</span><br><span class="line">hint2 = <span class="built_in">pow</span>(<span class="number">2021</span> * p1 + <span class="number">212121</span>, q1, n1)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'hint1={}'</span>.<span class="built_in">format</span>(hint1))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'hint2={}'</span>.<span class="built_in">format</span>(hint2))</span><br><span class="line"></span><br><span class="line">p2 = getPrime(<span class="number">512</span>)</span><br><span class="line">q2 = getPrime(<span class="number">512</span>)</span><br><span class="line">n2 = p2*q2</span><br><span class="line">e2 = <span class="number">65537</span></span><br><span class="line"><span class="keyword">assert</span> gcd(e1,(p2-<span class="number">1</span>)*(q2-<span class="number">1</span>)) == <span class="number">1</span></span><br><span class="line">c2 = <span class="built_in">pow</span>(q,e2,n2)</span><br><span class="line">hint3 = <span class="built_in">pow</span>(<span class="number">2020</span> * p2 + <span class="number">2021</span> * q2, <span class="number">202020</span>, n2)</span><br><span class="line">hint4 = <span class="built_in">pow</span>(<span class="number">2021</span> * p2 + <span class="number">2020</span> * q2, <span class="number">212121</span>, n2)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'n2={}'</span>.<span class="built_in">format</span>(n2))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'c2={}'</span>.<span class="built_in">format</span>(c2))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'hint3={}'</span>.<span class="built_in">format</span>(hint3))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'hint4={}'</span>.<span class="built_in">format</span>(hint4))</span><br><span class="line"></span><br><span class="line"><span class="comment">#c=13492392717469817866883431475453770951837476241371989714683737558395769731416522300851917887957945766132864151382877462142018129852703437240533684604508379950293643294877725773675505912622208813435625177696614781601216465807569201380151669942605208425645258372134465547452376467465833013387018542999562042758</span></span><br><span class="line"><span class="comment">#n1=75003557379080252219517825998990183226659117019770735080523409561757225883651040882547519748107588719498261922816865626714101556207649929655822889945870341168644508079317582220034374613066751916750036253423990673764234066999306874078424803774652754587494762629397701664706287999727238636073466137405374927829</span></span><br><span class="line"><span class="comment">#c1=68111901092027813007099627893896838517426971082877204047110404787823279211508183783468891474661365139933325981191524511345219830693064573462115529345012970089065201176142417462299650761299758078141504126185921304526414911455395289228444974516503526507906721378965227166653195076209418852399008741560796631569</span></span><br><span class="line"><span class="comment">#hint1=23552090716381769484990784116875558895715552896983313406764042416318710076256166472426553520240265023978449945974218435787929202289208329156594838420190890104226497263852461928474756025539394996288951828172126419569993301524866753797584032740426259804002564701319538183190684075289055345581960776903740881951</span></span><br><span class="line"><span class="comment">#hint2=52723229698530767897979433914470831153268827008372307239630387100752226850798023362444499211944996778363894528759290565718266340188582253307004810850030833752132728256929572703630431232622151200855160886614350000115704689605102500273815157636476901150408355565958834764444192860513855376978491299658773170270</span></span><br><span class="line"><span class="comment">#n2=114535923043375970380117920548097404729043079895540320742847840364455024050473125998926311644172960176471193602850427607899191810616953021324742137492746159921284982146320175356395325890407704697018412456350862990849606200323084717352630282539156670636025924425865741196506478163922312894384285889848355244489</span></span><br><span class="line"><span class="comment">#c2=67054203666901691181215262587447180910225473339143260100831118313521471029889304176235434129632237116993910316978096018724911531011857469325115308802162172965564951703583450817489247675458024801774590728726471567407812572210421642171456850352167810755440990035255967091145950569246426544351461548548423025004</span></span><br><span class="line"><span class="comment">#hint3=25590923416756813543880554963887576960707333607377889401033718419301278802157204881039116350321872162118977797069089653428121479486603744700519830597186045931412652681572060953439655868476311798368015878628002547540835719870081007505735499581449077950263721606955524302365518362434928190394924399683131242077</span></span><br><span class="line"><span class="comment">#hint4=104100726926923869566862741238876132366916970864374562947844669556403268955625670105641264367038885706425427864941392601593437305258297198111819227915453081797889565662276003122901139755153002219126366611021736066016741562232998047253335141676203376521742965365133597943669838076210444485458296240951668402513</span></span><br></pre></td></tr></table></figure><p><img "" class="lazyload placeholder" data-original="C:\Users\Hetaoren4\AppData\Roaming\Typora\typora-user-images\image-20210709203117136.png" src="https://img10.360buyimg.com/ddimg/jfs/t1/157667/29/9156/134350/603c6445Ebbc9cabe/41219c5d36d45072.gif" alt="image-20210709203117136"></p><figure class="highlight py"><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="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> gmpy2 <span class="keyword">import</span> gcd</span><br><span class="line">e=<span class="number">65537</span></span><br><span class="line">c=<span class="number">13492392717469817866883431475453770951837476241371989714683737558395769731416522300851917887957945766132864151382877462142018129852703437240533684604508379950293643294877725773675505912622208813435625177696614781601216465807569201380151669942605208425645258372134465547452376467465833013387018542999562042758</span></span><br><span class="line">n1=<span class="number">75003557379080252219517825998990183226659117019770735080523409561757225883651040882547519748107588719498261922816865626714101556207649929655822889945870341168644508079317582220034374613066751916750036253423990673764234066999306874078424803774652754587494762629397701664706287999727238636073466137405374927829</span></span><br><span class="line">c1=<span class="number">68111901092027813007099627893896838517426971082877204047110404787823279211508183783468891474661365139933325981191524511345219830693064573462115529345012970089065201176142417462299650761299758078141504126185921304526414911455395289228444974516503526507906721378965227166653195076209418852399008741560796631569</span></span><br><span class="line">hint1=<span class="number">23552090716381769484990784116875558895715552896983313406764042416318710076256166472426553520240265023978449945974218435787929202289208329156594838420190890104226497263852461928474756025539394996288951828172126419569993301524866753797584032740426259804002564701319538183190684075289055345581960776903740881951</span></span><br><span class="line">hint2=<span class="number">52723229698530767897979433914470831153268827008372307239630387100752226850798023362444499211944996778363894528759290565718266340188582253307004810850030833752132728256929572703630431232622151200855160886614350000115704689605102500273815157636476901150408355565958834764444192860513855376978491299658773170270</span></span><br><span class="line">n2=<span class="number">114535923043375970380117920548097404729043079895540320742847840364455024050473125998926311644172960176471193602850427607899191810616953021324742137492746159921284982146320175356395325890407704697018412456350862990849606200323084717352630282539156670636025924425865741196506478163922312894384285889848355244489</span></span><br><span class="line">c2=<span class="number">67054203666901691181215262587447180910225473339143260100831118313521471029889304176235434129632237116993910316978096018724911531011857469325115308802162172965564951703583450817489247675458024801774590728726471567407812572210421642171456850352167810755440990035255967091145950569246426544351461548548423025004</span></span><br><span class="line">hint3=<span class="number">25590923416756813543880554963887576960707333607377889401033718419301278802157204881039116350321872162118977797069089653428121479486603744700519830597186045931412652681572060953439655868476311798368015878628002547540835719870081007505735499581449077950263721606955524302365518362434928190394924399683131242077</span></span><br><span class="line">hint4=<span class="number">104100726926923869566862741238876132366916970864374562947844669556403268955625670105641264367038885706425427864941392601593437305258297198111819227915453081797889565662276003122901139755153002219126366611021736066016741562232998047253335141676203376521742965365133597943669838076210444485458296240951668402513</span></span><br><span class="line">a=<span class="built_in">pow</span>(<span class="number">2020</span>*(hint2-<span class="number">212121</span>),<span class="number">202020</span>,n1)</span><br><span class="line">b=<span class="built_in">pow</span>(<span class="number">2021</span>,<span class="number">202020</span>,n1)*hint1</span><br><span class="line">q1=gcd(a-b%n1,n1)</span><br><span class="line">p=<span class="built_in">pow</span>(c1,inverse(e,(q1-<span class="number">1</span>)*(n1//q1-<span class="number">1</span>)),n1)</span><br><span class="line">a=<span class="built_in">pow</span>(hint3,<span class="number">212121</span>,n2)*<span class="built_in">pow</span>(<span class="number">2020</span>,<span class="number">212121</span>*<span class="number">202020</span>,n2)%n2</span><br><span class="line">b=<span class="built_in">pow</span>(hint4,<span class="number">202020</span>,n2)*<span class="built_in">pow</span>(<span class="number">2021</span>,<span class="number">212121</span>*<span class="number">202020</span>,n2)%n2</span><br><span class="line">p2=gcd(a-b%n2,n2)</span><br><span class="line">q=<span class="built_in">pow</span>(c2,inverse(e,(p2-<span class="number">1</span>)*(n2//p2-<span class="number">1</span>)),n2)</span><br><span class="line">m=<span class="built_in">pow</span>(c,inverse(e,(p-<span class="number">1</span>)*(q-<span class="number">1</span>)),p*q)</span><br><span class="line"><span class="built_in">print</span>(long_to_bytes(m))</span><br></pre></td></tr></table></figure><p>flag:</p><p>b’GKCTF{f64310b5-d5e6-45cb-ae69-c86600cdf8d8}’</p>]]></content>
</entry>
<entry>
<title>buuEasyProgram</title>
<link href="/2021/07/09/buuEasyProgram/"/>
<url>/2021/07/09/buuEasyProgram/</url>
<content type="html"><![CDATA[<h1 id="buuEasyProgram"><a href="#buuEasyProgram" class="headerlink" title="buuEasyProgram"></a>buuEasyProgram</h1><p>一个简单的异或加密还原一下就可以了.</p><h2 id="Important-properties-of-XOR"><a href="#Important-properties-of-XOR" class="headerlink" title="Important properties of XOR"></a>Important properties of XOR</h2><p> There are 4 very important properties of XOR that we will be making use of. These are formal mathematical terms but actually the concepts are very simple.</p><ol><li> Commutative </li></ol><pre><code> : A ⊕ B = B ⊕ A This is clear from the definition of XOR: it doesn’t matter which way round you order the two inputs. </code></pre><ol start="2"><li> Associative </li></ol><pre><code> : A ⊕ ( B ⊕ C ) = ( A ⊕ B ) ⊕ C This means that XOR operations can be chained together and the order doesn’t matter. If you aren’t convinced of the truth of this statement, try drawing the truth tables. </code></pre><ol start="3"><li> Identity element </li></ol><pre><code> : A ⊕ 0 = A This means that any value XOR’d with zero is left unchanged. </code></pre><ol start="4"><li> Self-inverse </li></ol><pre><code> : A ⊕ A = 0 This means that any value XOR’d with itself gives zero. </code></pre><p> These properties hold not only when XOR is applied to a single bit, but also when it is applied bitwise to a vector of bits (e.g. a byte). For the rest of this article I will refer to such vectors as bytes, because it is a concept that all programmers are comfortable with, but don’t let that make you think that the properties only apply to a vector of size 8.</p><p>解密脚本:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">s=[<span class="number">0</span> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">256</span>)]</span><br><span class="line">t=[<span class="number">0</span> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">256</span>)]</span><br><span class="line">key=<span class="string">'whoami'</span></span><br><span class="line"><span class="comment"># we have flag:????????????????????????????????</span></span><br><span class="line">flag=<span class="string">''</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">256</span>):</span><br><span class="line"> s[i]=i</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">256</span>):<span class="comment">#0 to 256</span></span><br><span class="line"> t[i]=key[i%(<span class="built_in">len</span>(key))]</span><br><span class="line">i=j=<span class="number">0</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">256</span>):<span class="comment">#0 to 256</span></span><br><span class="line"> j=(j+s[i]+<span class="built_in">ord</span>(t[i]))%<span class="number">256</span></span><br><span class="line"> s[i],s[j]=s[j],s[i]</span><br><span class="line">i=j=<span class="number">0</span></span><br><span class="line">f=<span class="string">"00BA8F112B229F51A12FABB74BD73FEFE1B513BEC4D45D03D9007ACA1D51A473B5EF3D9B31B3"</span></span><br><span class="line">flag=[]</span><br><span class="line">flags=[]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>,<span class="built_in">len</span>(f),<span class="number">2</span>):</span><br><span class="line"> flag.append(f[i:i+<span class="number">2</span>])</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> flag:</span><br><span class="line"> <span class="keyword">if</span> i==<span class="string">'00'</span>:</span><br><span class="line"> flags.append(<span class="number">0</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> flags.append(<span class="built_in">int</span>(<span class="string">'0X'</span>+i,base=<span class="number">16</span>))</span><br><span class="line"><span class="comment"># s=[2, 5, 84, 118, 146, 14, 92, 139, 233, 242, 127, 75, 172, 55, 197, 1, 131, 113, 20, 206, 202, 19, 18, 186, 58, 154, 178, 247, 25, 245, 120, 130, 83, 114, 204, 243, 223, 188, 144, 236, 40, 80, 124, 238, 52, 16, 41, 66, 117, 132, 8, 47, 65, 164, 158, 99, 90, 56, 214, 73, 7, 210, 220, 82, 110, 123, 199, 218, 15, 109, 96, 95, 225, 12, 231, 106, 24, 98, 147, 222, 22, 21, 93, 153, 87, 142, 135, 71, 175, 37, 94, 107, 88, 244, 155, 111, 34, 183, 115, 50, 89, 239, 61, 72, 189, 112, 250, 69, 35, 252, 134, 53, 177, 156, 179, 182, 126, 237, 10, 235, 208, 200, 161, 181, 91, 38, 97, 159, 26, 3, 165, 145, 221, 187, 228, 216, 169, 162, 108, 13, 86, 152, 148, 4, 11, 255, 166, 190, 85, 248, 198, 193, 104, 203, 217, 184, 125, 246, 151, 232, 163, 171, 32, 201, 78, 143, 173, 195, 226, 105, 207, 28, 122, 229, 60, 251, 219, 48, 209, 116, 121, 101, 170, 168, 191, 27, 211, 157, 136, 77, 70, 30, 36, 128, 205, 62, 17, 196, 230, 167, 133, 49, 194, 79, 240, 33, 192, 174, 253, 46, 138, 129, 176, 227, 43, 100, 9, 149, 63, 215, 51, 31, 45, 119, 224, 54, 103, 57, 23, 102, 81, 39, 213, 241, 140, 185, 29, 212, 74, 59, 180, 44, 249, 68, 234, 76, 6, 160, 64, 254, 137, 42, 141, 67, 0, 150]</span></span><br><span class="line">i=j=<span class="number">0</span></span><br><span class="line"><span class="keyword">for</span> m <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">38</span>):<span class="comment">#0 to 38</span></span><br><span class="line"> i=(i + <span class="number">1</span>)%<span class="number">256</span></span><br><span class="line"> j=(j + s[i])%<span class="number">256</span></span><br><span class="line"> s[i], s[j] = s[j], s[i]</span><br><span class="line"> x=(s[i] + (s[j]%<span class="number">256</span>))%<span class="number">256</span></span><br><span class="line"> <span class="comment"># print(m,x)</span></span><br><span class="line"> flags[m]=flags[m]^s[x]</span><br><span class="line"><span class="comment"># print(flags)</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> flags:</span><br><span class="line"> <span class="built_in">print</span>(<span class="built_in">chr</span>(i),end=<span class="string">''</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># fprint flagx to file</span></span><br></pre></td></tr></table></figure><p>解密结果:flag{f238yu28323uf28u2yef2ud8uf289euf}</p>]]></content>
</entry>
<entry>
<title>BUU[HDCTF2019]together</title>
<link href="/2021/07/08/BUU%5BHDCTF2019%5Dtogether/"/>
<url>/2021/07/08/BUU%5BHDCTF2019%5Dtogether/</url>
<content type="html"><![CDATA[<h1 id="BUU-HDCTF2019-together"><a href="#BUU-HDCTF2019-together" class="headerlink" title="BUU[HDCTF2019]together"></a><strong>BUU[HDCTF2019]together</strong></h1><p>第一次写markdown算是一次尝试:</p><p>打开文件后看到4个文件myflag1 ,myflag2,pubkey1,pubkey2公钥分析后可以发现</p><p>n1=n2显然是共模攻击</p><figure class="highlight py"><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">e1 = <span class="number">2333</span></span><br><span class="line">n = <span class="number">14853081277902411240991719582265437298941606850989432655928075747449227799832389574251190347654658701773951599098366248661597113015221566041305501996451638624389417055956926238595947885740084994809382932733556986107653499144588614105694518150594105711438983069306254763078820574239989253573144558449346681620784979079971559976102366527270867527423001083169127402157598183442923364480383742653117285643026319914244072975557200353546060352744263637867557162046429886176035616570590229646013789737629785488326501654202429466891022723268768841320111152381619260637023031430545168618446134188815113100443559425057634959299</span></span><br><span class="line">e2 = <span class="number">23333</span></span><br></pre></td></tr></table></figure><h3 id="RSA共模攻击"><a href="#RSA共模攻击" class="headerlink" title="RSA共模攻击"></a>RSA共模攻击</h3><p>生成秘钥的过程中使用了相同的模数n,此时用不同的秘钥e加密同一信息m即:</p><p>c1 = m^e1 % n<br>c2 = m^e2 % n</p><p>若两个秘钥e互素根据扩展的欧几里得算法则存在s1,s2有:</p><p>e1 * s1 + e2 * s2 = gcd(e1, e2) = 1</p><p>结合以上所有信息,可以得到一个结论:</p><p> (c1^s1 * c2^s2) %n<br>= (m^e1 % n)^s1 * (m^e2 %n)^s2 % n<br>= m^(e1 * s1 + e2 * s2) % n<br>= m % n<br>= m</p><p>也就是在完全不知道私钥的情况下,得到了明文m</p><p>m = (c1^s1 * c2^s2) % n</p><p>解密脚本:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="keyword">import</span> base64</span><br><span class="line"><span class="keyword">import</span> libnum <span class="keyword">as</span> li</span><br><span class="line"><span class="keyword">from</span> gmpy2 <span class="keyword">import</span> invert</span><br><span class="line"></span><br><span class="line"><span class="comment"># 欧几里得算法</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">egcd</span>(<span class="params">a, b</span>):</span></span><br><span class="line"> <span class="keyword">if</span> a == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> (b, <span class="number">0</span>, <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> g, y, x = egcd(b % a, a)</span><br><span class="line"> <span class="keyword">return</span> (g, x - (b // a) * y, y)</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span>():</span></span><br><span class="line"> f1 = <span class="built_in">open</span>(<span class="string">r'G:\Desktop\myflag1.txt'</span>, encoding=<span class="string">'utf8'</span>)</span><br><span class="line"> f2 = <span class="built_in">open</span>(<span class="string">r'G:\Desktop\myflag2.txt'</span>, encoding=<span class="string">'utf8'</span>)</span><br><span class="line"> e1 = <span class="number">2333</span></span><br><span class="line"> n = <span class="number">14853081277902411240991719582265437298941606850989432655928075747449227799832389574251190347654658701773951599098366248661597113015221566041305501996451638624389417055956926238595947885740084994809382932733556986107653499144588614105694518150594105711438983069306254763078820574239989253573144558449346681620784979079971559976102366527270867527423001083169127402157598183442923364480383742653117285643026319914244072975557200353546060352744263637867557162046429886176035616570590229646013789737629785488326501654202429466891022723268768841320111152381619260637023031430545168618446134188815113100443559425057634959299</span></span><br><span class="line"> e2 = <span class="number">23333</span></span><br><span class="line"> c1 = li.s2n(base64.b64decode(f1.read()))</span><br><span class="line"> c2 = li.s2n(base64.b64decode(f2.read()))</span><br><span class="line"> s = egcd(e1, e2)</span><br><span class="line"> s1 = s[<span class="number">1</span>]</span><br><span class="line"> s2 = s[<span class="number">2</span>]</span><br><span class="line"> <span class="comment"># 求模反元素</span></span><br><span class="line"> <span class="keyword">if</span> s1<<span class="number">0</span>:</span><br><span class="line"> s1 = - s1</span><br><span class="line"> c1 = invert(c1, n)</span><br><span class="line"> <span class="keyword">elif</span> s2<<span class="number">0</span>:</span><br><span class="line"> s2 = - s2</span><br><span class="line"> c2 = invert(c2, n)</span><br><span class="line"></span><br><span class="line"> m = <span class="built_in">pow</span>(c1,s1,n)*<span class="built_in">pow</span>(c2,s2,n) % n</span><br><span class="line"> <span class="built_in">print</span>(li.b2s(<span class="built_in">bin</span>(m)))</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> main()</span><br></pre></td></tr></table></figure><p>运行结果:b’flag{23re_SDxF_y78hu_5rFgS}’</p>]]></content>
</entry>
<entry>
<title>BJDCTF2020 编码与调制</title>
<link href="/2021/07/08/%5BBJDCTF2020%5DCoding_and_modulation/"/>
<url>/2021/07/08/%5BBJDCTF2020%5DCoding_and_modulation/</url>
<content type="html"><![CDATA[<h1 id="BJDCTF2020-编码与调制"><a href="#BJDCTF2020-编码与调制" class="headerlink" title="[BJDCTF2020]编码与调制"></a>[BJDCTF2020]编码与调制</h1><p>hint中可以大概了解到曼切斯特编码:</p><img "" class="lazyload placeholder" data-original="C:\Users\Hetaoren4\Downloads\Compressed\I'm hint!!!.png" src="https://img10.360buyimg.com/ddimg/jfs/t1/157667/29/9156/134350/603c6445Ebbc9cabe/41219c5d36d45072.gif" style="zoom: 67%;" /><p>在位中间,信号由高向低跳变表示数据0,信号由低向高跳变表示数据1:</p><p>可以写出解码程序:</p><figure class="highlight py"><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">x=<span class="number">0x2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6</span></span><br><span class="line"><span class="comment"># print(len(bin(x)))</span></span><br><span class="line"><span class="keyword">import</span> libnum <span class="keyword">as</span> li</span><br><span class="line">t=<span class="built_in">str</span>(<span class="built_in">bin</span>(x))[<span class="number">2</span>:]</span><br><span class="line"><span class="built_in">print</span>(t)</span><br><span class="line">ans=<span class="string">''</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>,<span class="built_in">len</span>(t),<span class="number">2</span>):</span><br><span class="line"> <span class="keyword">if</span> t[i:i+<span class="number">2</span>]==<span class="string">'01'</span>:</span><br><span class="line"> ans+=<span class="string">'0'</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ans+=<span class="string">'1'</span></span><br><span class="line"><span class="built_in">print</span>(ans)</span><br><span class="line"><span class="built_in">print</span>(li.b2s(ans))</span><br></pre></td></tr></table></figure><p>运行结果:b’BJD{DifManchestercode}’</p>]]></content>
</entry>
<entry>
<title>BUU[BJDCTF2020]Polybius</title>
<link href="/2021/07/07/BUU%5BBJDCTF2020%5DPolybius/"/>
<url>/2021/07/07/BUU%5BBJDCTF2020%5DPolybius/</url>
<content type="html"><![CDATA[<h2 id="BUU-BJDCTF2020-Polybius"><a href="#BUU-BJDCTF2020-Polybius" class="headerlink" title="BUU[BJDCTF2020]Polybius"></a>BUU[BJDCTF2020]Polybius</h2><p>文件类容:</p><p>密文:ouauuuoooeeaaiaeauieuooeeiea<br>hint:VGhlIGxlbmd0aCBvZiB0aGlzIHBsYWludGV4dDogMTQ=<br>flag:解出明文后,请加上BJD{}</p><p>hint是base64加密:解密后是:The length of this plaintext: 14</p><p>密文的长度是28,结合题目可以看出是波利比奥斯方阵密码:</p><h6 id="波利比奥斯方阵密码简介"><a href="#波利比奥斯方阵密码简介" class="headerlink" title="波利比奥斯方阵密码简介"></a><em>波利比奥斯方阵密码简介</em></h6><p><code>公元前2世纪,一个叫Polybius的希腊人设计了一种将字母编码成符号对的方法,他使用了一个称为Polybius的校验表,这个表中包含许多后来在加密系统中非常常见的成分。Polybius校验表由一个5行5列的网格组成,网格中包含26个英文字母,其中I和J在同一格中。相应字母用数对表示。在古代,这种棋盘密码被广泛使用。Polybius校验表如下</code></p><p><img "" class="lazyload placeholder" data-original="C:\Users\Hetaoren4\AppData\Roaming\Typora\typora-user-images\image-20210708192516690.png" src="https://img10.360buyimg.com/ddimg/jfs/t1/157667/29/9156/134350/603c6445Ebbc9cabe/41219c5d36d45072.gif" alt="image-20210708192516690"></p><p>(2,4)这个坐标既可以表示i 也可以表示 j因此破解的时候这里又会多两种情况</p><h6 id="加密过程"><a href="#加密过程" class="headerlink" title="加密过程"></a>加密过程</h6><p>如’a’就被加密乘 1,1 (第1行,第1列)</p><p>1,2,3,4,5可以用字母代替</p><p>如果用A,D,F,G,X代替 ‘a’就变成了AA ,’b’就变成了AD,以此类推.</p><p>从密文的字母推出代换的字母集合为 s=”aeoiu”</p><p>根据全排列代换字母可以爆破出密文.</p><p>解密脚本:</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># c="ouauuuoooeeaaiaeauieuooeeiea"</span></span><br><span class="line"><span class="comment">#length :28</span></span><br><span class="line"><span class="comment"># The length of this plaintext: 14</span></span><br><span class="line"><span class="keyword">import</span> itertools</span><br><span class="line">s=<span class="string">"aeoiu"</span></span><br><span class="line">sumresult=[]</span><br><span class="line">numsumresult=[]</span><br><span class="line">ciper=<span class="string">"ouauuuoooeeaaiaeauieuooeeiea"</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> itertools.permutations(s,<span class="number">5</span>):<span class="comment">#找出所有全排列</span></span><br><span class="line"> sumresult.append(<span class="string">""</span>.join(i))</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> sumresult:</span><br><span class="line"> temp=<span class="string">""</span></span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> ciper:</span><br><span class="line"> temp+=<span class="built_in">str</span>(i.index(j)+<span class="number">1</span>)</span><br><span class="line"> numsumresult.append(temp)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> numsumresult:</span><br><span class="line"> ans_=<span class="string">""</span></span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(i),<span class="number">2</span>):</span><br><span class="line"> xx=(<span class="built_in">int</span>(i[j])-<span class="number">1</span>)*<span class="number">5</span>+<span class="built_in">int</span>(i[j+<span class="number">1</span>])+<span class="number">96</span></span><br><span class="line"> <span class="keyword">if</span> xx><span class="built_in">ord</span>(<span class="string">'i'</span>):</span><br><span class="line"> xx+=<span class="number">1</span></span><br><span class="line"> ans_+=<span class="built_in">chr</span>(xx)</span><br><span class="line"> <span class="built_in">print</span>(ans_)</span><br></pre></td></tr></table></figure><p>解密结果: flagispolybius</p><p><img "" class="lazyload placeholder" data-original="C:\Users\Hetaoren4\AppData\Roaming\Typora\typora-user-images\image-20210708193201811.png" src="https://img10.360buyimg.com/ddimg/jfs/t1/157667/29/9156/134350/603c6445Ebbc9cabe/41219c5d36d45072.gif" alt="image-20210708193201811"></p>]]></content>
</entry>
</search>