2023年12月31日 星期日

使用 Hugo 跟 Cloudflare 架設個人品牌網站 - changyy.app



買了 changyy.app 網域好一陣子,想說該用來經營一下個人品牌,然後一直偷懶 XD 目前用 Github private repository + Hugo + Cloudflare 維護 https://changyy.app 網站,最近來換一下 Hugo theme ,再重新複習一下。

目前架設個人品牌網站,主要著重在把一些網路足跡紀錄一下,雖說 linkedin 上也是整理足跡的方式,但目的是很正式的求職路線,一些有趣的小品反而不太適合。近三年嘗試了 golang、python 和 node.js 等等外,在工作上的程式語言有盡可能切換到 Python,也試著把一些小品工具包裝成 PyPi 安裝方式作為收尾,預計就可以用來充實個人品牌網站了?!

目前架設個人網站的需求如下:
  • 把相關網站靠 link 關聯著
  • 提供撰寫簡單的條列式記錄生活
就這樣,先挑了 hugo-PaperMod 樣版來試試。

連續動作:

% hugo version
hugo v0.121.1+extended Darwin/arm64 BuildDate=unknown VendorInfo=macports

% hugo new site MyWebsite --format yaml
Congratulations! Your new Hugo site was created in /path/MyWebsite.

Just a few more steps...

1. Change the current directory to /path/MyWebsite.
2. Create or install a theme:
   - Create a new theme with the command "hugo new theme <THEMENAME>"
   - Install a theme from https://themes.gohugo.io/
3. Edit hugo.yaml, setting the "theme" property to the theme name.
4. Create new content with the command "hugo new content <SECTIONNAME>/<FILENAME>.<FORMAT>".
5. Start the embedded web server with the command "hugo server --buildDrafts".

See documentation at https://gohugo.io/.

% cd MyWebsite
% hugo serve


接著套用一下 PaperMod 樣板,稍微從他的教學 github.com/adityatelange/hugo-PaperMod/wiki 小改:

% curl -L https://github.com/adityatelange/hugo-PaperMod/archive/v7.0.zip > /tmp/v7.0.zip
% unzip /tmp/v7.0.zip -d themes/
% mkdir -p config/_default/
% cat config/_default/config.yml 
theme: "hugo-PaperMod-7.0"
% tree -L 2
.
├── archetypes
│   └── default.md
├── assets
├── config
│   └── _default
├── content
├── data
├── hugo.yaml
├── i18n
├── layouts
├── static
└── themes
    └── hugo-PaperMod-7.0

12 directories, 2 files

% hugo serve

 


最後連續動作弄了些:

% cat config/_default/config.yml 
# https://gohugo.io/getting-started/configuration/
baseURL: https://your-domain
languageCode: en-us
title: YourWebsiteName
theme: hugo-PaperMod-7.0

# https://analytics.google.com/analytics/web/?#/xxxxx/reports/intelligenthome
googleAnalytics: G-XXXXXXX

minify:
  disableXML: true
  minifyOutput: true

# https://github.com/adityatelange/hugo-PaperMod/wiki/Installation
params:
  env: production
  # https://github.com/adityatelange/hugo-PaperMod/wiki/Features#profile-mode
  profileMode:
    enabled: true
    imageUrl: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=120
    imageWidth: 120
    imageHeight: 120
    buttons:
      - name: open source
        url: /projects

  socialIcons:
    - name: github
      url: https://github.com/id
    - name: linkedin
      url: https://linkedin.com/in/id
    - name: blogger
      url: https://your-blog-url
    
  assets:
    favicon: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=128
    favicon16x16: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=16
    favicon32x32: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=32
    apple_touch_icon: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=128
    safari_pinned_tab: https://secure.gravatar.com/avatar/MD5_Of_EmailAddress?size=128

% tree -L 2
.
├── archetypes
│   └── default.md
├── assets
├── config
│   └── _default
├── content
│   └── projects
├── data
├── hugo.yaml
├── i18n
├── layouts
├── static
└── themes
    └── hugo-PaperMod-7.0

13 directories, 2 files

下一刻則是 Cloudflare 那邊設定 Workers & Pages 項目,就長出了 changyy.app 啦,希望 2024年還有餘力繼續擴充足跡。

2023年12月25日 星期一

Python 開發筆記 - 開發 epub-image-helper 工具,批次將圖片目錄打包成 EPUB 格式,也支援 PDF to EPUB @ macos 14.2.1, Python 3.11

記得剛出社會沒多久,被派去研究電子書領域,那時就接觸了 EPUB 格式。當時在團隊中被分配到開發 EPUB READER,例如在 HTML5 環境中,在 Browser 讀進 epub 檔案、進行 unzip 、抽出目錄、呈現書的內容。後來也做過電子書相關的應用發想,而主管們相繼離開(?),也讓我接手和接觸了貢獻 webkit 的項目(C++),可惜很多狀態都不了了之。

大概兩三週前想到 EPUB 這格式,想嘗試把照片打包成單一 EPUB 檔案,方便收藏。但大概完成七八成後,才發現有很多限制,例如電子書閱讀器上要處理大檔案時,就會陷入到電子書閱讀器的硬體規格和處理能力,甚至它實作處理 EPUB 格式的方式等,我才發現當初想要把一堆照片合成一大本應當不是正道 XD 後來還是順手練習 python open source 工具,做了一些發布,在此就筆記一下。而能妥善處理大檔案的電子書閱讀器,大概就 iOS devices 而已,實際在 iPhone SE3 上處理 500MB 的電子書EPUB也都很 OK 的。

這次挑選 ebooklib 作為 EPUB 製作的核心函式庫,當初查看 github 專案上有破千的關注,跳下去使用時才發現有些限制,也順手發了兩次 pull requests ,查閱了該專案歷年的 pull requests 活躍狀態,還是自己弄了個 ebooklib.changyy 方便自己整合

最後產出的小專案:
安裝 epub-image-helper:

% pip install epub-image-helper
% epub-image-helper | jq -r '.version'
1.0.4

使用方式可以參考 README 或是 https://github.com/changyy/epub-image-helper/tree/main/example 內的小程式庫,主要可以用 epub-image-helper 將有階層式的照片打包起來,也可以自訂一個 input.json 格式,批次把許多目錄依照一些規則打包起來,如:

% cd example/01-batch-image-to-epub
% tree .
.
├── epub
├── image2epub.py
├── input.json
└── storage
    └── url 
        ├── 001 
        │   ├── 01.jpg
        │   ├── 02.jpg
        │   └── 03.jpg
        └── 002 
            ├── 01.jpg
            ├── 02.jpg
            ├── 03.jpg
            ├── 04.jpg
            └── 05.jpg

6 directories, 10 files
% cat input.json
[
  {   
    "name": "MyPhotosA",
    "author": ["Author"],
    "books": [
      "https://localhost/001/A", 
      "https://localhost/002/B", 
      "https://localhost/003/C"
    ]   
  },  
  {   
    "name": "MyPhotosB",
    "author": ["Author"],
    "books": [
      "https://localhost/004/A", 
      "https://localhost/005/B", 
      "https://localhost/006/C"
    ]   
  }
]
% python3 image2epub.py
...
% tree epub 
epub
└── MyPhotosA
    ├── MyPhotosA01.epub
    └── MyPhotosA02.epub

2 directories, 2 files

除此之外,也支援拿 pdf 作為處理,例如把一份 pdf 內所有的圖片都抽出來打包成 EPUB 格式。

估計就告一個段落吧!這個 epub-image-helper 工具發展過程中,發現自己原先想要做的(弄成一包很大的EPUB)並非主流,就漸漸失去熱情。趁熱情還沒散去之前,先弄成一個小 open source 紀念這段2023年12月初,斷斷續續兩個週末的小產出。

2023年12月19日 星期二

macOS - 使用 Cryptomator cracker 和 Hashcat maskprocessor 官方工具來猜密碼

初老...沒想到半年前朋友推坑嘗試 Cryptomator ,不一會兒也忘記密碼了,查了一下資訊得知 Cryptomator 本身有提供破解的工具,但需要自行取產密碼清單。這時就要來搭配個 hashcat !我原本也以為是透過 hashcat 直接用,最後則是用 hashcat 的密碼產生器

整個過程:
  1. 找到 masterkey.cryptomator
  2. 使用 cryptomator 官方提供的 cracker:github.com/cryptomator/cracker
  3. 使用 hashcat 牌產生密碼檔案:github.com/hashcat/maskprocessor.git
  4. 串起來猜密碼
連續範例:

% ./mp64.bin '?a' | wc -l
      95
% ./mp64.bin '?a?a' | wc -l
    9025
% ./mp64.bin '?a?a?a' | wc -l
  857375
% ./mp64.bin '?a?a' | java -jar ~/Downloads/cracker-0.1.1-fat.jar ~/Downloads/masterkey.cryptomator
Guesses per second: 46.0
Guesses per second: 47.2
Guesses per second: 47.7
Guesses per second: 47.5
Guesses per second: 47.9
Guesses per second: 47.7
Guesses per second: 47.9
Guesses per second: 47.9
Guesses per second: 47.9
...

三個字元的密碼就有 85萬種排列組合,而在電腦上跑每秒能猜 40 左右,等於要將近 2萬秒,也就是 333 分鐘,當然也就是 5 ~ 6 小時。

2023年11月5日 星期日

Python 開發筆記 - L2 Multicast / L3 Multicast 與 IGMP Snooping 測試

幫公司測試了一下 Professional Audiovisual (ProAV) 產品在不同 switch 上的情況,剛好有分別走 L2 Multicast 跟 L3 Multicast 溝通模式,而這些設備會使用 IGMP 通報 switch ,盡可能讓 Multicast 封包不要影響不必要的網路設備,避免俗稱的流量洪水事件。

由於過去經驗都是比較上層應用,這次就多多請教 chatGPT 惡補一下知識,其中 IGMP 的知識倒是被 Cloudflare 的教學文給救贖了一下:


IGMP 是用於 IPv4 的多點傳送通訊協定,是網際網路通訊協定的第四版。IPv6 依賴於多點傳送接聽程式探索 (MLD) 進行多點傳送。IPv6 網路使用 MLD 窺探而不是 IGMP 窺探。

就這句話,我反而在想 L2 Multicast 缺少 L3 (IP層) 的封包資訊,是不是讓 switch 做不到 IGMP snooping 功能?甚至舊款 switch 直接判定是未知 multicast 而進行永久性 broadcast 容錯設計?實測的結果是不同的 switch 行為是不一樣的。

整體上只需要簡單的 python 小程式,透過 scapy 套件,可非常輕鬆拼湊出想製作的 raw socket 來進行測試:

RX app: 

from scapy.all import *
from scapy.contrib.igmp import IGMP

multicastMac = "01:00:5e:00:02:01"
multicastGroupIP = '224.0.2.1'
nicName = '乙太網路'

# IGMPv2 Membership Report
igmpReportPacket = Ether(dst=multicastMac)/IP(dst=multicastGroupIP)/IGMP(type=0x16, mrcode=0, gaddr=multicastGroupIP)
sendp(igmpReportPacket, iface=nicName)

while True:
    multicastReceivePacket = sniff(iface=nicName, filter=f"ether dst {multicastMac}", count=1)
    if multicastReceivePacket:
        print("Received: ", multicastReceivePacket[0][Raw].load.decode("utf-8"))
        #print("Received: ", multicastReceivePacket[0][Raw].load)

TX app:

from scapy.all import *
from scapy.contrib.igmp import IGMP

multicastMac = "01:00:5e:00:02:01"
multicastGroupIP = '224.0.2.1'
nicName = '乙太網路2'

# IGMP Membership Report
igmpReportPacket = Ether(dst=multicastMac)/IP(dst=multicastGroupIP)/IGMP(type=0x16, mrcode=0, gaddr=multicastGroupIP)
sendp(igmpReportPacket, iface=nicName)

i = 0
while True:
    # Multicast
    if i % 3 == 0: 
        multicastTestMessagePacket = Ether(dst=multicastMac, type=0xffff)/"hello"
    elif i % 3 == 1:
        multicastTestMessagePacket = Ether(dst=multicastMac)/IP(dst=multicastGroupIP)/UDP(sport=12345, dport=12345)/"world"
    else:
        multicastTestMessagePacket = Ether(dst=multicastMac)/IP(src="192.168.1.2", dst=multicastGroupIP)/UDP(sport=12345, dport=12345)/"hello world"

    sendp(multicastTestMessagePacket, iface=nicName)

    # IGMPv2 Report
    if i % 600:
        sendp(igmpReportPacket, iface=nicName)
    i += 1

    time.sleep(1/10)

如此,弄一台筆電,讓他上頭有兩張 RJ45 網卡(可靠USB擴充),分別插上待側的 switch ,一邊當 RX 收訊息,另一邊當 TX 送訊息,接著調整 switch 設定後,觀察封包傳遞的狀況。可以的話,其實筆電可以設法弄個 3個網孔?接著另一網孔可以插在 switch 上,看看有沒有流量洪水(traffic floods)

收工

2023年10月12日 星期四

SSD 外接硬碟盒 與 USB3.2 Gen 1 / USB3.2 Gen 2 / USB3.2 Gen 2x2 / USB 4 規格 @ 以 2023 MacBook Air 15吋 M2 使用為例

最近準備升級工作環境,正在評估外接硬碟方案,主因是買的 Type-C 隨身碟很容易掛 :P 先對照著 2023 Macbook Air 15吋 M2 的規格:

兩個 Thunderbolt / USB 4 埠,可支援:

充電
DisplayPort
Thunderbolt 3 (速度最高可達 40Gb/s)
USB 4 (速度最高可達 40Gb/s)
USB 3.1 Gen 2 (速度最高可達 10Gb/s)


這這邊提到 USB4 和 USB 3.1 Gen 2,跟 chatGPT 請教一下,原來 USB3.2 的各代基本上也是用來簡述以前 USB 3.1, USB 3.0 等用法,直接查看 USB 3 WIKI - zh.wikipedia.org/zh-tw/USB_3.0
  • USB 3.2 Gen 1x1 == USB 3.2 Gen 1 == USB 3.1 Gen 1 == USB 3.0
  • USB 3.2 Gen 1x2 (只支援 Type-C)
  • USB 3.2 Gen 2x1 == USB 3.2 Gen 2 == USB 3.1 Gen 2
  • USB 3.2 Gen 2x2 (只支援 Type-C)
然後頻寬就 USB 3.2 Gen 1 = 5 Gbit/s, USB 3.2 Gen 2 = 10 Gbit/s,因此上述依序就是 5 Gbit/s, 10 Gbit/s, 10 Gbit/s, 20 Gbit/s ,這樣就好記許多。而上述通常會簡化成以下三款:
  • USB 3.2 Gen 1 = 5 Gbit/s 傳輸效率 = 理論上約略每秒 500MB 傳輸效率
  • USB 3.2 Gen 2 = 10 Gbit/s 傳輸效率 = 理論上約略每秒 1000MB 傳輸效率
  • USB 3.2 Gen 2x2 = 20 Gbit/s 傳輸效率 = 理論上約略每秒 2000MB 傳輸效率
而 MacBook Air 15吋 M2 版的規格描述就是 USB4 (40Gb/s) or USB 3.1 Gen 2 (10Gb/s)。若不需衝極值,就買支援 USB 3.1 Gen 2 版的外接硬碟即可。此刻也可以採買到 USB 4 的外接SSD盒,通常會詳加描述自己的散熱系統。

此外,在 SSD 規格上,常見 M.2 PCI Express 2280, M.2 PCI Express 2260, M.2 PCI Express 2242, 後面那串數字 2280, 2260, 2242 代表寬x長等於 22x80, 22x60, 22x42,而 PCI Express 也會看的 PCIe 3.0 和 PCIe 4.0 ,其中 PCIe 3.0 每個通道傳輸效率 8 Gbit/s 而 PCIe 4.0 每個通道傳輸效率 16 Gbit/s,例如一款產品名為 M.2 2280 PCIe Gen3x4 ,代表該 SSD 插槽規格為 M.2 規格,寬長 22x80 ,傳輸速度是 Gen3x4 = 8 Gbit/s x4 = 32 Gbit/s = 理論上傳輸效率約 4 GB/s

而上面的傳輸效率都是 "理論上" ,實際上傳輸速度還會跟 SSD 內部控制器晶片、NAND閃存類型以及操作的檔案大小和數量等有關。

關於 SSD 保固上,常見 5年保固 或 600 TBW 有限保固,後者代表寫入達 600 TB 的資料量概念,通常 SSD 空間越大時,保固的 XXX TBW 數字會越大,例如 1TB SSD 會有 600 TBW ,而 2TB 就會常看到 1000 TBW 等有限保固機制。

最後,回到最初的想法,會思考 SSD 外接盒起源於一顆 512GB USB3.2Gen1 隨身碟經常性備份資料或埋了很多零碎檔案後,容易壞掉 :P 

例如插上 Macbook 無法被偵測,甚至無法被修復,後來交叉用 Windows 11 修復,回來在 macOS 又可以辨識到...但這樣的日子太不安穩了,因此評估一下是否在掏錢買個 SSD + 外接盒方案,如此 SSD 可抽換+保固服務長