---
# System prepended metadata

title: 機概筆記

---

# 拯救機概
## 大家應該知道怎麼用吧 不懂的人看這裡  [Hackmd語法大全](https://hackmd.io/@eMP9zQQ0Qt6I8Uqp2Vqy6w/SyiOheL5N/%2FBVqowKshRH246Q7UDyodFA?type=book)  
[數學的打法](https://math.meta.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference)

目錄
===


# Ch8 基礎演算法
:::success
概念: 提出有效率解決問題的一種方式 
定義: 有其先後順序、明確步驟、產生結果、有限時間內結束
演算法的三種結構：循序、選擇、重複
:::


UML 統一塑模語言，以圖畫方式表示 ex:案例圖、狀態圖
persudocode 虛擬程式碼，一種代碼的表示方式，但只有大略簡寫而已

----------
### (一) 排序

1. 選擇排序 Seletion sort

[圖示化影片](https://youtu.be/g-PGLbMth_g?si=YTmV4qJdF0njJdlf) 

程式碼範例:
```python!
def selection_sort(deta):
    for i in range(len(deta)- 1):
        for j in range(i,len(deta)):
            m = max(deta)+1#表示很大的值
            if deta[j] < m:
                m = deta[j]
                index = j
        deta[i],deta[index] = deta[index],deta[i]
    return deta

nums = [2,1,3,5,4]
selection_sort(nums)
```
2. 泡沫排序 Bubble sort

[圖示化影片](https://youtu.be/xli_FI7CuzA?si=_Qtosz-MGNGdKhcs)

程式碼範例:
```python!
def bubble_sort(nums):
    n = len(nums)
    for i in range (n-1):
        for j in range (n-i-1):
            if nums[j] > nums[j+1]:
                temp = nums[j]
                nums[j] = nums[j+1]
                nums[j+1] = temp

nums = [2,1,3,5,4]
bubble_sort(nums)
```
3. 插入排序 Insertion sort

[圖示化影片](https://www.youtube.com/watch?v=JU767SDMDvA)

程式碼範例:
```python!
def insertion_sort(nums):
    n = len(nums)
    for i in range(1,n):
        for j in range (i,0,-1):
            if nums[j] < numd[j-1]:
                nums[i],nums[i-1] = nums[i-1],num[i]
            else:
                break
    return nums

nums = [2,1,3,5,4]
insertion_sort(nums)
#以上排序後都為[1,2,3,4,5]
```

### (二) 搜尋
:::info
Problem：
$$
如何在五個數中找到最大or最小整數，那有10^9個數呢?
$$
#hint 資料結構 Array(在python中稱為list)
:::
1. 循序搜尋(暴力法) Sequential search
  * 最大的數 
```python!
n = [1,2,3,4,5]
ans = -1 #答案
for i in n:
    if i>ans:
        ans = i
```
  * 最小的數
```python!
n = [1,2,3,4,5]
ans = 10**10 #答案
for i in n:
    if i>ans:
        ans = i
```
* 懶人法
```python!
n = [1,2,3,4,5]
min_ans = min(n)
max_ans = max(n)
```
:::info
練習
請在2秒內建立一個1000000以內的質數表，並計算出有幾個質數
 hint [埃拉托斯特尼篩法](https://zh.wikipedia.org/zh-tw/%E5%9F%83%E6%8B%89%E6%89%98%E6%96%AF%E7%89%B9%E5%B0%BC%E7%AD%9B%E6%B3%95)
:::


2. 二分搜尋法 Binary search
:::warning
當你的資料量很大怎麼辦? 這時候需要二分搜尋法幫你找問題了
注意! 只有在資料經過排序之後才能夠使用
:::
```python!
n=[1,2,3,4,5] #需先排序
left=0 #最左項
right=len(n)-1 #最右項
while left<=right:
    mid=(left+right)//2
    #切一半後判斷
    if n[mid]>target:
        right=mid-1 #超過取左邊串
    elif n[mid]<target:
        left=mid+1 #未達取右邊串
    elif n[mid]==target:#找到目標
        return mid 
```

$$
二分搜速度是非常快的，當你有n=10^{10}個資料的時候，大概只需要跑\log_2 n次迴圈就可以找到答案。
$$

### (三) 遞迴 Recursion
定義: 演算法中出現演算法本身（反之，為反覆式）白話文:重複呼叫自己
優點: 程式精簡
缺點: 速度慢，不容易實作，需要透過大量練習才能掌握


:::warning 
使用python實作時只能遞迴3000次，超過記憶體會爆
解決方法:
import 標準函式庫sys 中的setrecursionlimit
```python!
import sys
sys.setrecursionlimit(100000)#可自由增加遞迴次數，太大扔會造成memory error
```
:::



以自訂義函式實作
ex: 1+2+3+....+n-1


```python!
def g(n):
    if n<0:
        return 0
    return g(n-1)+n
#g(10) = 55

```

**Tower of Hanoi（河內塔)**
* Problem: move n disks from A to C
* Rules
    * Move one disk at a time
    * Cannot place a larger disk onto a smaller disk

簡易規則：小盤子一定要在大盤子上面，一次只能移動一個
![image](https://hackmd.io/_uploads/HJlySdSBT.png)
:::info
* How to move n disks?

* How many moves in total?
    $$2^{n-1}+1次$$
:::


* To move n disks from A to C (for n > 1):

    1. 移動 Disk 1~n-1 form A to B
    2. 移動 Disk n from A to C
    3. 移動 Disk 1~n-1 from B to C
```python!
#sudo code
Hanoi(n, src, dest, spare)
	if n == 1 # base case
		Move disk from src to dest
        else # recursive case
		Hanoi(n-1, src, spare, dest)
		Move disk from src to dest
		Hanoi(n-1, spare, dest, src)
```
實作
```python!
def Hoi(n,a,b,c):
    if n ==0:
        print(f"desk {n} from {a} to {c}")
    else:
        Hoi(n-1,a,c,b)
        print(f"desk {n} from {a} to {c}")
        Hoi(n-1,b,a,c)
    Hoi(10,"a","b","c")
    
```


**GCD(輾轉相除法)**

```python!
#a>b
def GCD(a,b):
    if a%b==0 :
        return(b)
    else:
        return(GCD(b,a%b))
```

**費氏數列(Fibonacci)**
```python!
def Fib(n):
    if n==1 or n==2:
        return(1)
    else:
        return(Fib(n-1)+Fib(n-2))
```
![image](https://hackmd.io/_uploads/H1poVKrSa.png =80%x)

### 外傳 stack



#### ps.很佔記憶體

--------------------------------------------------------------

# Ch9 程式語言
### 演化
1. 機器語言(0與1位元樣式所構成)
2. 組合語言Assembly(符號語言symbolic)
:::info
* 二進位碼->指令，記憶體位址->符號or助憶碼
* 組譯器(assemlber)程式：符號碼轉機器碼
:::
3. 高階語言
    依解決問題的方法分為4種：程序式、物件導向式、函數式、宣告式
    - 程序式 : C, Fortran, COBL, BASIC, Pascal, Ada
    - 物件導向式 : c++, c#, JAVA, python, Visual Basic, Smalltalk
    - 函數式 : LISP, Scheme
    - 宣告式 : prolog

![image](https://4.bp.blogspot.com/_1111KAvK4Ds/SQ13AR9zK2I/AAAAAAAAAy8/esqoV1KUZnI/s400/programming+language.ex1.jpg=80%x)



~~外傳 [x86 compiler](https://onecompiler.com/assembly/3w22x43ev)~~



### 高階程式語言
1. 為了解決難以讀懂程式碼的問題
2. 通常為直譯或編譯方式轉譯成機器語言


### 轉譯
1. 編譯 Compilation：整個轉譯
2. 直譯 Interpretation：逐行轉譯，有兩種
:::info
第一種：Java前的，逐行轉譯為對應電腦的機器語言，並立即執行
第二種：Java開始，先編譯成位元組碼，並於有 JVM 的電腦執行
:::

### 原始程式的轉譯處理
![image alt](https://cdn.discordapp.com/attachments/972002954116726794/1182162476658327582/image.png?ex=6583b199&is=65713c99&hm=46cd18dbc99891c1c64e754de8ef236c889b33114ab93448a21ac63badc4ab71&)
1. 語彙分析器（lexical analyzer）：讀入符號，並產生符記（tokens）
2. 語法分析器（syntax analyzer）：將符記剖析為指令
3. 語意分析器（semantic analyzer）：檢查產生的指令，確保語意不會產生混淆
5. 程式碼產生器（code generator）：將其轉換為一組機器語言所構成的指令，以供電腦執行



### 物件導向(使用python實作)
#### 範例 建立使用者跟使用者id
```python!
class User:
    # Attribute
    def __init__(self,user_id,username): 
        self.id = user_id
        self.name = username
        self.follower = 0 #Attribute 可以預設，也可以內建
        self.following = 0
    #Method
    #Method always need to have self parameter 
    def follow(self,user):
        user.follower += 1
        self.following += 1

user_1 = User("11211109","daidai0000")
#print(user_1.id,user_1.name)
#print(user_1.follwer)
user_2 = User("777","taro")

user_1.follow(user_2)
print(user_1.follower)
print(user_1.following)

print(user_2.follower)
print(user_2.following)
# 可以拿去執行看看
```
:::danger
##### CH10老師跳過
:::
# CH11 資料結構Data Structure
## 函式中資料的傳遞 - 傳值，傳址，傳參考
:::info
* 引數（argument）~~又稱實際參數(實參，actual parameter)~~ 
  是主程式用於「呼叫函式」，也就是「執行函式」時的「輸入值」
* 函式內的參數（parameter）~~又稱形式參數（形參，formal parameter）~~
  是用於「函式的宣告」，也就是定義函式
:::
1. 傳值(pass by value):把值「複製」到函式中
![image alt](https://i.imgur.com/me7uIlo.jpg)
![image alt](https://i.imgur.com/W59TMVQ.jpg)
2. 傳址(pass by address):傳遞記憶體位址
![image alt](https://i.imgur.com/H0aXqsZ.jpg)
![image alt](https://i.imgur.com/kRRWw5d.jpg)
    * ##### 事實上pass by address也是在傳值，只不過這個值剛好是記憶體位址(指標)
3. 傳參考(pass by reference):類似傳址，但不會分配記憶體給參數x、y，所需記憶體較少
![image alt](https://i.imgur.com/nDaule9.jpg)
4.  二維陣列到多維陣列
     
5. struct
    * 特性 
        * first in first out
        * 像疊積木一樣一層一層
    * 經典範例 (請看CH8 合內塔演算法)
        * 



7. link-list(鏈結串列)
:::info
鏈結串列(Linked List)常用來處理相同類型資料，在不連續的記憶體位置，以隨機的方式儲存，由於不用事先宣告一塊連續記憶體空間，所以較不會造成記憶體的浪費。
由許多節點組成，每個節點包含**資料欄**與**指標欄**，指標欄會指向下一個資料所在的記憶體位置。因此再追加或刪除資料相當方便，因為只需要更動指標的指向，但在讀取資料就會較費時，因為必須從串列的頭開始尋找。
:::
![image alt](https://miro.medium.com/v2/resize:fit:828/format:webp/1*7-WWgP21cjCHfbsUuJpf3Q.png)
* 實作
:::danger  
以上由chat-gpt生成，可能果會跟預期結果不太一樣
(基本上還是看得懂，好像也沒差)
:::
```python!
class Node:
    def __init__(self, data):
        self.data = data
        self.next_node = None


class LinkedList:
    def __init__(self):
        self.head = None

    def is_empty(self):
        return self.head is None

    def append(self, data):
        new_node = Node(data)
        if self.is_empty():
            self.head = new_node
        else:
            current_node = self.head
            while current_node.next_node:
                current_node = current_node.next_node
            current_node.next_node = new_node
    def delete(LinkedList, current_node, pre):
        if pre == None:
        # 如果 pre 為 None，表示要刪除的是鏈結串列的第一個節點
        # 將 LinkedList 更新為 cur 節點的下一個節點，即將頭指針指向下一個節點
            LinkedList = current_node.next_node
        else:
        # 如果 pre 不為 None，表示要刪除的是中間或尾部的節點
        # 將 pre 節點的 next 指向 cur 節點的下一個節點，即跳過 cur 節點
            pre.next_node = cur.next_node
        return LinkedList
    
    def display(self):
        current_node = self.head
        while current_node:
            print(current_node.data, end=" -> ")
            current_node = current_node.next_node
        print("None")
        
    # Create a linked list
    my_linked_list = LinkedList()

    # Append elements to the linked list
    my_linked_list.append(1)
    my_linked_list.append(2)
    my_linked_list.append(3)

    # Display the linked list
    my_linked_list.display()
```
:::info  
執行結果 1 -> 2 -> 3 -> None
:::
-----------------------------------------------
# Ch12 抽象資料型態ADT
:::warning
複雜抽象資料型態:
* 串列：list
* 堆疊：stack，後進先出(Last In First Out LIFO)
* 佇列：quene，先進先出(First In First Out FIFO)
:::
## Stack 堆疊
1. 限制性的線性串列
2. 增加和移出都在頂端(先進後出)
3. 資料的存取必須符合LIFO
### 運算格式
    * stack(stackName)：建立空堆疊
    * push(stackName,deta_whichin)：在頂端推入元素
    * pop(stackName,deta_whichdelete)：刪除頂端元素，可被使用或被丟棄
    * empty(stackName)：檢查堆疊是否為空的
### 應用
* 反轉資料：完整建立堆疊後再pop輸出 
* 配對資料：
#### stack 經典應用例子一
以作業十的「1,2,3」數字序列為例，要輸出以下數字的步驟為:
* 123: push 1, pop, push 2, pop, push 3, pop
* 132: push 1, pop, push 2, push 3, pop ,pop
* 213: push 1, push 2, pop, pop, push 3, pop
* 231: push 1, push 2, pop, push 3, pop, pop
* 312: 無法產生
* 321: push 1, push 2, push 3,pop, pop, pop


括號匹配問題 現在有一堆左括號跟右括號，現在你要判斷他能不能符合數學上的表示方式
simpal input
```
(((())))))
((((()))))
((((((((())))))))
```
simpal ouput
```
no
yes
no
```


## Queue 佇列
1. 先進先出 FIFO：
輸入順序:123 輸出順序:123

![image](https://hackmd.io/_uploads/rJv0C9RP6.png)

## 樹上演算法
:::warning
nodes(節點)：根、樹葉、內部節點
root(根)：最上面沒有進入弧線的節點
leaves(樹葉)：最下方的節點
internal nodes(內部節點)：如其名，是在中間的節點
arcs(弧線)：連結節點的線
path(路徑)：一連串弧線
child(子)：從一個已知節點可以直接存取的節點
parent(父)：可以直接存取子的節點
siblings(兄弟)：有共同的父的節點
descendents(後代)：全部可被同個節點到達的節點
ancestor(祖先)：全部可到達同個節點的節點
subtree(子樹)：一個節點的所有子和每個子的後代，一個子和他的後代算一個子樹
:::
### BST(二元樹)
##### DFS(深度優先)
前序 (preorder), 中序 (inorder) 和後序 (postorder) 是指遍歷二元樹 (binary tree) 時，父節點相對於左右節點的順序。
假設二元樹如下：

        4         #4為根
       / \
      2   6       #2、6為內部節點
     / \ / \            #123為左子樹，246為右子樹
    1  3 5  7     #1、3、5、7為樹葉
則三種遍歷的順序依序為：

* 前序 (preorder): 中 -> 左 -> 右，4213657
* 中序 (inorder): 左 -> 中 -> 右，1234567
* 後序 (postorder): 左 -> 右 -> 中，1325764
:::danger
對二元搜尋樹 (binary search tree, BST) 做 inorder traversal 就是由小到大依序遍歷。
:::
例子
```python!
stack=[reference link]
rpn=['1','2','3','*','+']
for i in range (len(rpn)):
    if rpn[i] not in {'+','-','*','/'}:
        node=Node(rpn[i])
        stack.append(node)
    else:
        node=Node(rpn[i])
        node.right=stack.pop()
        node.left=stack.pop()
        stack.append(node)
bet=stack,pop()
```
##### BFS(Breadth-First 廣度優先)
        4         #4為根
       / \
      2   6       #2、6為內部節點
     / \ / \            #123為左子樹，246為右子樹
    1  3 5  7     #1、3、5、7為樹葉
順序：4->2->6->1->3->5->7
#### GRAPH(圖)
#### 四則運算(應用)
利用二元樹概念處理運算問題
ex: 1+2*3 => 1 2 3 * + (輸入數字，遇符號先計算後兩者數字


---------------------------------------------------
# CH8 資訊安全(全華那本
## 基本原則 CIA
資料機密性(Confidenriality)：防治未經授權第三者
資料完整性(Integrity)：避免遭到竄改
系統可用性(Availability)：確保資料、系統可即時提取
不可否認性(Non-Reputation)：提供訊息傳送方與接受方的交易證明
## 其他需求
信賴性(authenticity)：資料本身或來源可被驗證
究責性(accounability)：確保資料的不可否認性，提供可靠的紀錄

## 資料機密性：對稱式加密 vs. 非對稱式加密
:::warning
密碼法(crypotography)
加密法(ciphers)
加密(encryption)
解密(decryption)
明文(plaintext)
密文(ciphertext)
:::
### 對稱式金鑰密碼加密法(Symmteric-key ciphers，密鑰加密法):
:::info
加解密時使用相同密鑰
:::
![image alt](https://miro.medium.com/v2/resize:fit:1100/format:webp/1*4wIvr3cQ4TfSkozEv3-3mg.png)
#### 方法
##### 傳統對稱式：
1. 替換式加密：用一個符號替換另一個符號
    * 移位密碼(加密時將每個符號往前後移N格) ex:凱薩加密法
    * 替換密碼(製作一個轉換表) ex:[跳舞小人密碼](https://codepen.io/anie116/full/jdzvJK)
2. 區塊式加密：多個等長的模組（block），各區塊各自加解密
    * 事先約定一個短字串當作秘密ex:ENIGMA
    * XOR運算(先轉換二進位利用XOR進行加密，再轉ACSII code)

IV加密
IV初始向量

運作方式
搭配區塊式
會在內容中添入文本(增加複雜度)
#### 優點
簡單好用，是一個有效率又省錢的方案
#### 缺點
易破解(被攔截到金鑰)

### 非對稱式金鑰密碼加密法(Asymmetric-key ciphers，公鑰密碼加密法):
:::info
兩組密碼:一組加密，一組解密
公鑰(Public key):公開(大家都知道)
私鑰(Private key):隱藏(個人)
:::
常見應用
1. 加密
2. 數位簽章Digital Signature(私鑰簽章，公鑰驗證)
3. 密碼交換
:::danger
加解密的鑰匙要是完整一對(pair)的，所以可以是公鑰加密私鑰解密，也可以是私鑰加密公鑰解密，沒有一定。
:::
ex:RSA, Diffie-Hellman
#### 基本原理
![image alt](https://miro.medium.com/v2/resize:fit:1100/format:webp/1*AODyNUnHj2xwMLO1FFMESQ.png)
[圖片來源](https://medium.com/@RiverChan/%E5%9F%BA%E7%A4%8E%E5%AF%86%E7%A2%BC%E5%AD%B8-%E5%B0%8D%E7%A8%B1%E5%BC%8F%E8%88%87%E9%9D%9E%E5%B0%8D%E7%A8%B1%E5%BC%8F%E5%8A%A0%E5%AF%86%E6%8A%80%E8%A1%93-de25fd5fa537)
使用數學上的難解問題(以下為例子)
離散:給定二數$x$和$y$
例子:給$x^y$，求$x$、$y$
因數分解：給定二個質數$p$和$q$
例子:給定$pq$，求$p$、$q$
### RSA加密演算法
#### 優點
1. 可配合對稱式加密運算
#### 缺點
1. 大量運算
2. 耗時特長

假設甲乙加換密碼
兩者有著共同密碼
第三者難以計算出(目前)
例子:
甲密碼為$x^a$除以$q$的餘數，乙密碼為$x^b$除以$q$的餘數
共同密碼:$x^{a+b}$除以$q$的餘數

## 資料完整性
驗證密碼是否被修改
例子:雜湊函數

### 雜湊函數(HashTable Function)
任意長度字串運算後，得到固定長度的雜湊函數

#### 應用
1. 驗證資料傳輸是否無誤
2. 訊息驗證碼(MAC)
#### 優點
1. 高敏感度(微小改動，結果不同)
2. 單向函數(無法回推)
3. 不易發生碰撞(不同輸入，不易得到相同結果)

### HMAC基本概念
傳送端和接受端共享一組密碼(驗證來源，目的地正確性)
實際配合其他參數，避免被不同類型的網路攻擊

### 數位簽章

確認資料是來自特定使用者
特定使用者，使用其私要進行簽章

### PGP加密(雙層加密)
利用會議金鑰進行加密
會議金鑰使用公開金鑰加密

### PGD解密
先用公鑰解密，在使用會議金鑰解密出密文

### 公開金鑰管理
集中式管理
PKI
CA(憑證授權中心)認證公鑰

分散式管理:Web of Trust

故障偵測機制:常用<心跳機制>

## 8-5網路攻擊
目的
未經許可的存取
中斷服務氣正常運作
<駭客>
hacker:專精某領域的專家