瀏覽代碼

Désobfuscation du code de calcul des séquences

pull/5/head
Figg 9 月之前
父節點
當前提交
52e42682f9
共有 2 個檔案被更改,包括 36 行新增31 行删除
  1. 17
    29
      million/analyze/find_holes.py
  2. 19
    2
      million/model/sequence.py

+ 17
- 29
million/analyze/find_holes.py 查看文件

@@ -9,44 +9,32 @@ import million.analyze.message_evaluation as msg_ev
9 9
 
10 10
 def compute_sequences(messages: List[Message], accepted_max: int = 1_000_000) -> List[Sequence]:
11 11
     sequences: List[Sequence] = []
12
-    current_sequence = Sequence(
13
-        start_message=messages[0],
14
-        end_message=messages[0]
15
-    )
16
-    for i in range(1, len(messages)):
17
-        message = messages[i]
18
-        message_value = msg_ev.compute(message)
19
-        if message_value > accepted_max:
20
-            continue
21
-        if message_value - current_sequence.end() == 1:
22
-            current_sequence.end_message = message
12
+    current = Sequence(start_message=messages[0])
13
+    
14
+    for message in messages[1:]:
15
+        if msg_ev.compute(message) > accepted_max: continue
16
+
17
+        if msg_ev.compute(message) == current.end() + 1:
18
+            current.end_message = message
23 19
         else:
24
-            sequences.append(current_sequence)
25
-            current_sequence = Sequence(
26
-                start_message=message,
27
-                end_message=message
28
-            )
20
+            sequences.append(current)
21
+            current = Sequence(start_message=message)
29 22
 
30 23
     # order the sequences by start
31 24
     sequences.sort(key=lambda s: s.start())
32 25
 
33 26
     merged_sequences: List[Sequence] = []
34
-    current_sequence = sequences[0]
35
-    for i in range(1, len(sequences)):
36
-        sequence = sequences[i]
37
-        sequence_start_is_in_current_sequence = current_sequence.start() <= sequence.start() and current_sequence.end() >= sequence.start()
38
-        sequence_end_is_further = sequence.end() > current_sequence.end()
39
-        sequence_start_is_current_end_or_next = sequence.start() == current_sequence.end() + 1
40
-
41
-        if sequence_start_is_in_current_sequence or sequence_start_is_current_end_or_next:
42
-            if sequence_end_is_further:
43
-                current_sequence.end_message = sequence.end_message
27
+    previous = sequences[0]
28
+    
29
+    for sequence in sequences[1:]:
30
+        if previous.overlaps(sequence):
31
+            previous.merge(sequence)
44 32
         else:
45
-            merged_sequences.append(current_sequence)
46
-            current_sequence = sequence
33
+            merged_sequences.append(previous)
34
+            previous = sequence
47 35
 
48 36
     # Having merged the sequences once, any sequence having start = end can be removed
49
-    return [s for s in merged_sequences if s.start() != s.end()]
37
+    return [s for s in merged_sequences if s.length() > 1]
50 38
 
51 39
 
52 40
 def find_holes(messages: List[Message], accepted_max: int = 1_000_000) -> List[Hole]:

+ 19
- 2
million/model/sequence.py 查看文件

@@ -1,5 +1,7 @@
1
+from __future__ import annotations
1 2
 
2 3
 from pydantic import BaseModel
4
+import pydantic
3 5
 
4 6
 from million.model.message import Message
5 7
 import million.analyze.message_evaluation as msg_ev
@@ -7,10 +9,25 @@ import million.analyze.message_evaluation as msg_ev
7 9
 
8 10
 class Sequence(BaseModel):
9 11
     start_message: Message
10
-    end_message: Message | None
12
+    end_message: Message | None = None
13
+
14
+    @pydantic.validator('end_message', pre=True, always=True)
15
+    def default_end_message(cls, v, *, values):
16
+        return v or values['start_message'] 
11 17
 
12 18
     def start(self) -> int:
13 19
         return msg_ev.compute(self.start_message)
14 20
     
15 21
     def end(self) -> int:
16
-        return msg_ev.compute(self.end_message)
22
+        return msg_ev.compute(self.end_message)
23
+    
24
+    def length(self) -> int:
25
+        return self.end() - self.start() + 1
26
+    
27
+    def merge(self, other: Sequence) -> None:
28
+        if other.start() < self.start(): self.start_message = other.start_message
29
+        if other.end() > self.end(): self.end_message = other.end_message
30
+    
31
+    def overlaps(self, other: Sequence) -> bool:
32
+        return self.start() <= other.end() + 1 and \
33
+            other.start() <= self.end() + 1

Loading…
取消
儲存