跳至主要內容

WinUI3 Button

這篇備忘錄記錄了 WinUI3 中的 Button 控制項。

資訊

在 WinUI3 中,Button 是一個基本的交互式控制項,允許用戶通過點擊觸發應用程式中的操作。它通常用於提交表單、確認操作、導航或執行其他命令。

1. 基本用法

創建一個 Button 最簡單的方法是為其提供 Content 和處理 Click 事件。

<Button Content="點擊我" Click="MyButton_Click"/>

在後台程式碼中 (例如 MainWindow.xaml.cs):

// MainWindow.xaml.cs
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace WinUI3App
{
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}

private void MyButton_Click(object sender, RoutedEventArgs e)
{
// 在這裡執行按鈕點擊時的操作
// 例如:
// MessageDialog dialog = new MessageDialog("按鈕被點擊了!", "提示");
// await dialog.ShowAsync();
if (sender is Button button)
{
button.Content = "已點擊!";
}
}
}
}

2. Button 的內容 (Content)

ButtonContent 屬性是 object 類型,這意味著你可以放置任何 UI 元素作為按鈕的內容,而不僅僅是文本。這使得 Button 非常靈活。

範例:文本

<Button Content="提交"/>

範例:圖標 (Icon)

通常使用 FontIconSymbolIcon 來顯示圖標。

<Button Click="SaveButton_Click">
<SymbolIcon Symbol="Save"/>
</Button>

範例:圖標和文本

你可以將 StackPanel 或其他佈局容器放置在 ButtonContent 中,以組合多個元素。

<Button Click="NewFileButton_Click">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="Document" Margin="0,0,8,0"/>
<TextBlock Text="新建檔案"/>
</StackPanel>
</Button>

範例:自定義圖像

<Button Click="ImageButton_Click">
<Image Source="ms-appx:///Assets/CustomIcon.png" Width="24" Height="24"/>
</Button>

3. 按鈕樣式 (Styling)

WinUI3 提供了多種內置樣式,你可以應用於按鈕,使其具有不同的視覺外觀和用途。

範例:主要按鈕 (Primary Button)

AccentButtonStyle 通常用於強調主要操作。

<Button Content="確認" Style="{StaticResource AccentButtonStyle}"/>

範例:其他標準樣式

WinUI3 提供了其他一些默認樣式,如:

  • Button (默認樣式)
  • TextButtonStyle (文本按鈕,沒有背景和邊框)
  • AppBarButtonStyle (應用程式欄按鈕樣式)
<Button Content="取消" Style="{StaticResource TextButtonStyle}"/>

範例:自定義樣式

你可以定義自己的樣式來完全控制按鈕的外觀。

<Grid>
<Grid.Resources>
<Style TargetType="Button" x:Key="CustomButtonStyle">
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="Foreground" Value="DarkBlue"/>
<Setter Property="BorderBrush" Value="DarkBlue"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Padding" Value="12,8"/>
<Setter Property="CornerRadius" Value="4"/>
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
</Grid.Resources>

<Button Content="自定義按鈕" Style="{StaticResource CustomButtonStyle}"/>
</Grid>

4. 命令綁定 (Commanding)

對於 MVVM (Model-View-ViewModel) 模式,你通常會使用命令綁定而不是直接處理 Click 事件。Button 支持 Command 屬性。

<Button Content="執行命令" Command="{Binding MyCommand}"/>

在你的 ViewModel 中:

// ViewModel (例如 MyViewModel.cs)
using CommunityToolkit.Mvvm.Input; // 假設你使用 CommunityToolkit.Mvvm

public class MyViewModel : ObservableObject
{
public IRelayCommand MyCommand { get; }

public MyViewModel()
{
MyCommand = new RelayCommand(ExecuteMyCommand, CanExecuteMyCommand);
}

private void ExecuteMyCommand()
{
// 執行命令邏輯
Console.WriteLine("命令已執行!");
}

private bool CanExecuteMyCommand()
{
// 判斷命令是否可以執行
return true;
}
}

總結

WinUI3 的 Button 控制項是一個功能豐富且高度可自定義的元素。無論是簡單的文本按鈕、帶圖標的複雜按鈕,還是使用命令綁定,它都提供了強大的能力來滿足你的 UI 交互需求。通過樣式化,你可以輕鬆地使其與你的應用程式設計語言保持一致。

WinUI3 MenuFlyoutIcon

這篇備忘錄記錄了 WinUI3 中的 MenuFlyoutIcon

資訊

在 WinUI3 中,MenuFlyoutIcon 是一個用於在 MenuFlyoutItem 中顯示圖標的控制項。它允許你為上下文菜單或主菜單中的項目添加視覺提示,提高用戶界面的可讀性和用戶體驗。

1. MenuFlyoutItemIcon

MenuFlyoutItemMenuFlyout 中的一個可點擊的項目。它本身有一個 Icon 屬性,你可以直接在其中放置圖標控制項。

範例:使用 FontIcon

最常見的方式是使用 FontIcon 顯示一個字體圖標(例如來自 Segoe Fluent Icons 字體)。

<MenuFlyout>
<MenuFlyoutItem Text="新建檔案">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE7C3;" /> {/**/}
</MenuFlyoutItem.Icon>
</MenuFlyadItem>
<MenuFlyoutItem Text="開啟檔案">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE8E5;" /> {/**/}
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutSeparator />
<MenuFlyoutItem Text="儲存">
<MenuFlyoutItem.Icon>
<FontIcon Glyph="&#xE74E;" /> {/**/}
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>

你也可以使用 SymbolIcon 來引用內置的 Symbol 枚舉,這更具可讀性。

<MenuFlyout>
<MenuFlyoutItem Text="新建檔案">
<MenuFlyoutItem.Icon>
<SymbolIcon Symbol="Document" />
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem Text="開啟檔案">
<MenuFlyoutItem.Icon>
<SymbolIcon Symbol="Folder" />
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutSeparator />
<MenuFlyoutItem Text="儲存">
<MenuFlyoutItem.Icon>
<SymbolIcon Symbol="Save" />
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>

範例:使用 BitmapIcon

如果你想使用圖像文件(例如 PNG 或 SVG)作為圖標,可以使用 BitmapIcon

<MenuFlyout>
<MenuFlyoutItem Text="設定">
<MenuFlyoutItem.Icon>
<BitmapIcon UriSource="ms-appx:///Assets/SettingsIcon.png" ShowAsMonochrome="False"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>

確保 Assets/SettingsIcon.png 文件存在於你的專案中。ShowAsMonochrome="False" 確保圖像保持其原始顏色。

範例:使用 PathIcon

對於更複雜或自定義的矢量圖形,可以使用 PathIcon。這允許你使用 XAML 語法定義圖形路徑。

<MenuFlyout>
<MenuFlyoutItem Text="自定義圖標">
<MenuFlyoutItem.Icon>
<PathIcon Data="M10,10 L20,20 M10,20 L20,10" /> {/**/}
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>

2. 為什麼沒有 MenuFlyoutIcon 類?

值得注意的是,你不會在 WinUI3/UWP 的 API 文檔中找到一個名為 MenuFlyoutIcon 的直接類。這是因為 MenuFlyoutItem.Icon 屬性是一個 IconElement 類型,它是一個抽象基類。

因此,你實際上是在 MenuFlyoutItem.Icon 屬性中放置任何繼承自 IconElement 的具體圖標控制項(如 FontIconSymbolIconBitmapIconPathIcon)。這些都是用於顯示圖標的標準 WinUI 控制項,只是在 MenuFlyoutItem 的上下文中使用。

3. 最佳實踐

  • 一致性:在整個應用程式中保持圖標樣式和大小的一致性。
  • 可訪問性:確保圖標清晰可見,並考慮為視力受損用戶提供文本替代。
  • 易於理解:選擇直觀且普遍認可的圖標來代表其操作。
  • 主題適應性:如果使用 FontIconSymbolIcon,它們通常會自動適應應用程式的主題(淺色/深色模式)。對於 BitmapIcon,如果希望它們也能適應,可能需要提供不同主題下的圖像資源。

總結

在 WinUI3 中為 MenuFlyoutItem 添加圖標是通過其 Icon 屬性實現的,該屬性接受任何 IconElement 派生類。最常用的是 FontIconSymbolIcon,因為它們輕量且易於與應用程式主題集成。正確使用圖標可以顯著提高應用程式的可用性和視覺吸引力。

MyCard 備忘錄

這篇備忘錄記錄了 MyCard。

資訊

MyCard 是一個在台灣和香港地區廣泛使用的數位內容點數卡服務平台,主要用於線上遊戲、數位娛樂和其他數位產品的支付。它提供了一種方便、安全的支付方式,尤其適合那些沒有信用卡或不願意使用信用卡的用戶。

1. MyCard 的主要功能和用途

  • 遊戲儲值:MyCard 最主要的功能是為各種線上遊戲、手機遊戲和 PC 遊戲儲值。玩家可以購買 MyCard 點數,然後在遊戲內兌換成遊戲幣、虛寶或其他服務。
  • 數位內容購買:除了遊戲,MyCard 也支持購買其他數位內容,如音樂、影視、電子書等。
  • 支付方式多樣:MyCard 提供多種購買方式,包括:
    • 實體卡(在便利商店、網咖等地購買)。
    • 線上購買(通過信用卡、銀行轉帳、電信小額支付等)。
    • 點數儲值。
  • 活動和優惠:MyCard 經常與遊戲廠商合作舉辦各種促銷活動,提供額外的遊戲獎勵或折扣。

2. 如何購買 MyCard

A. 實體購買

你可以在以下地點購買 MyCard 實體卡:

  • 便利商店:7-ELEVEN、全家 (FamilyMart)、萊爾富 (Hi-Life)、OK Mart。
  • 通訊行:部分手機通訊行。
  • 遊戲店家:專業的遊戲商品店。

B. 線上購買

  1. MyCard 官方網站:訪問 MyCard 官方網站 (https://www.mycard.com.tw/)。
  2. 選擇購買方式:你可以選擇以下方式:
    • 點數卡/點數儲值:輸入實體卡背面的序號和密碼進行儲值。
    • 線上支付:選擇你偏好的支付方式,如信用卡、銀行轉帳、WebATM、電信小額支付(中華電信、遠傳、台灣大哥大等)。
    • 海外支付:支持部分海外支付方式。
  3. 輸入信息並完成支付:根據提示輸入相關信息。

3. 如何儲值到遊戲

以儲值到遊戲為例,一般步驟如下:

  1. 進入遊戲儲值頁面:在你的遊戲中,找到「儲值」、「購買點數」或「會員中心」等入口。
  2. 選擇 MyCard 支付方式:從支付選項中選擇 MyCard。
  3. 選擇儲值類型
    • MyCard 點數卡:輸入你購買的實體卡上的「卡號」和「密碼」。
    • MyCard 會員扣點:如果你有 MyCard 會員帳戶並已儲值點數,可以直接從帳戶扣點。
  4. 確認交易:核對金額和遊戲帳戶信息,然後確認支付。
  5. 完成儲值:通常遊戲內會立即收到相應的遊戲幣或虛寶。

4. 安全注意事項

  • 保護卡號和密碼:MyCard 點數卡一旦被儲值,點數就會被轉移。請妥善保管你的卡號和密碼,不要輕易透露給他人。
  • 官方渠道購買:務必通過官方認可的渠道購買 MyCard,以避免買到偽造卡或無效卡。
  • 確認儲值信息:在儲值到遊戲前,務必仔細核對遊戲帳號和儲值金額,避免錯誤。

總結

MyCard 作為台灣和香港地區主流的數位內容支付平台,為廣大遊戲玩家和數位內容消費者提供了極大的便利。了解其購買和儲值流程,並注意安全事項,可以讓你更好地享受數位娛樂生活。

Poetry 備忘錄

這篇備忘錄記錄了 Poetry。

資訊

Poetry 是一個用於 Python 項目依賴管理和打包的工具。它旨在提供一個更簡潔、更直觀的開發體驗,解決了傳統 Python 項目中 pipvirtualenv 的一些痛點。

Poetry 將依賴管理、虛擬環境、打包和發布功能集成到一個工具中,使得 Python 項目的生命週期管理更加順暢。

1. 安裝 Poetry

推薦使用官方提供的腳本進行安裝:

Linux / macOS / WSL

curl -sSL https://install.python-poetry.org | python3 -

Windows (PowerShell)

(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -

安裝完成後,你可能需要將 Poetry 的可執行路徑添加到你的 PATH 環境變量中。安裝腳本通常會給出提示。

2. 創建新專案

要創建一個新的 Poetry 專案:

poetry new my-project
cd my-project

這會創建一個包含以下結構的新目錄:

my-project/
├── my_project/
│ └── __init__.py
└── pyproject.toml
└── README.md

3. pyproject.toml 文件

Poetry 使用 pyproject.toml 文件來管理項目元數據和依賴。這是 Poetry 的核心配置文件。

範例 pyproject.toml

[tool.poetry]
name = "my-project"
version = "0.1.0"
description = ""
authors = ["Your Name <[email protected]>"]
readme = "README.md"
packages = [{include = "my_project"}] # 指定你的 Python 包

[tool.poetry.dependencies]
python = "^3.10" # 指定 Python 版本
requests = "^2.28.1" # 運行時依賴

[tool.poetry.group.dev.dependencies]
pytest = "^7.1.2" # 開發時依賴 (例如測試工具)

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

4. 管理依賴

添加依賴

poetry add requests # 添加運行時依賴
poetry add --group dev pytest # 添加開發時依賴

這會更新 pyproject.toml 並安裝依賴到虛擬環境中。

移除依賴

poetry remove requests
poetry remove --group dev pytest

安裝依賴

如果 pyproject.tomlpoetry.lock 已經存在,安裝所有依賴:

poetry install

更新依賴

更新所有依賴到最新兼容版本:

poetry update

更新指定依賴:

poetry update requests

5. 虛擬環境

Poetry 會自動為每個專案創建和管理虛擬環境。

運行命令

在虛擬環境中運行命令:

poetry run python my_script.py

進入虛擬環境 Shell

poetry shell

然後你就可以直接運行 python 或其他已安裝的命令。

查看虛擬環境信息

poetry env info

刪除虛擬環境

poetry env remove python3.10 # 替換為實際的 Python 版本或環境路徑

6. 打包和發布

打包專案

創建一個源發行版(sdist)和一個輪子文件(wheel):

poetry build

打包文件會生成在 dist/ 目錄中。

發布到 PyPI

在發布之前,請確保你的 pyproject.toml 中的元數據是準確的。

poetry publish

如果你是第一次發布,可能需要配置 PyPI 憑據。

poetry config pypi-token.pypi <your-pypi-token>

7. 總結

Poetry 是一個現代化的 Python 項目管理工具,它簡化了依賴管理、虛擬環境、打包和發布的整個流程。它的 pyproject.toml 文件提供了一個清晰且中心化的方式來定義項目元數據和依賴,大大提升了開發效率和項目可維護性。

建立個人主頁

這篇備忘錄記錄了如何建立個人主頁。

資訊

建立個人主頁是展示個人作品、技能、簡歷和聯絡方式的重要方式。它可以用作個人品牌建設、求職或僅僅作為一個分享興趣愛好的平台。

1. 選擇技術棧

建立個人主頁有許多種方法,從靜態網頁到複雜的內容管理系統 (CMS)。選擇合適的技術棧取決於你的需求和技術熟練度。

A. 靜態站點生成器 (SSG) - 推薦

靜態站點生成器是建立個人主頁的流行選擇,因為它們易於部署、加載速度快、安全且通常免費託管。

  • Docusaurus:用於建立文檔網站(如本網站)。它基於 React,支持 Markdown,並提供內置的搜尋、版本控制和國際化功能。
  • Jekyll:基於 Ruby 的 SSG,與 GitHub Pages 緊密集成。
  • Hugo:基於 Go 語言的 SSG,以其極快的構建速度而聞名。
  • Next.js / Gatsby:基於 React 的框架,可以生成靜態站點。

B. 前端框架 (SPA)

如果你需要更多互動性或動態內容,可以使用前端框架創建單頁應用程式 (SPA)。

  • React
  • Vue.js
  • Angular

C. 內容管理系統 (CMS)

如果你希望有管理界面來輕鬆更新內容,可以使用 CMS。

  • WordPress
  • Joomla
  • Ghost

2. 規劃內容

在開始編寫程式碼之前,先規劃你的主頁應該包含哪些內容。常見的內容區塊包括:

  • 首頁 / 關於我:簡要介紹自己、你的興趣和目標。
  • 作品集 / 專案:展示你的最佳作品,包括截圖、鏈接和簡要說明。
  • 技能:列出你的技術技能、程式語言、工具和框架。
  • 經歷 / 簡歷:你的教育背景、工作經歷和成就。
  • 部落格 / 文章:如果你喜歡寫作,可以分享你的知識和見解。
  • 聯絡方式:電子郵件、GitHub、LinkedIn、Twitter 等社交媒體鏈接。

3. 建立個人主頁 (以 Docusaurus 為例)

本網站就是使用 Docusaurus 建立的,所以這裡以 Docusaurus 為例。

A. 建立 Docusaurus 專案

npx create-docusaurus@latest my-website classic --typescript
cd my-website

B. 配置 Docusaurus

編輯 docusaurus.config.ts 文件以配置網站標題、導航欄、腳註等。

C. 建立個人主頁內容

  1. 修改首頁: 默認的首頁是 src/pages/index.tsx。你可以編輯這個 React 組件來設計你的首頁。

    // src/pages/index.tsx
    import React from 'react';
    import clsx from 'clsx';
    import Layout from '@theme/Layout';
    import Link from '@docusaurus/Link';
    import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
    import styles from './index.module.css';
    import HomepageFeatures from '../components/HomepageFeatures';

    function HomepageHeader() {
    const {siteConfig} = useDocusaurusContext();
    return (
    <header className={clsx('hero hero--primary', styles.heroBanner)}>
    <div className="container">
    <h1 className="hero__title">{siteConfig.title}</h1>
    <p className="hero__subtitle">{siteConfig.tagline}</p>
    <div className={styles.buttons}>
    <Link
    className="button button--secondary button--lg"
    to="/docs/intro">
    我的簡歷 - 5min 閱讀 ⏱️
    </Link>
    </div>
    </div>
    </header>
    );
    }

    export default function Home(): JSX.Element {
    const {siteConfig} = useDocusaurusContext();
    return (
    <Layout
    title={`Hello from ${siteConfig.title}`}
    description="Description will go into a meta tag in <head />">
    <HomepageHeader />
    <main>
    <HomepageFeatures />
    </main>
    </Layout>
    );
    }
  2. 建立個人資料頁面 (例如 about.md): 你可以在 docs/ 目錄下創建 Markdown 文件作為關於你的頁面。

    {/**/}
    ---
    sidebar_position: 1
    ---

    # 關於我

    你好!我是 [你的名字],一位熱愛 [你的興趣] 的 [你的職位/角色]。
    我在 [領域] 擁有 [X] 年的經驗,專注於 [你的專長]。

    ## 我的技能

    - 程式語言:Python, JavaScript, C#
    - 框架:React, Node.js, .NET
    - 工具:Git, Docker, Kubernetes

    ## 我的專案

    - **專案 A**:[鏈接] - 簡要說明
    - **專案 B**:[鏈接] - 簡要說明

    ## 聯絡方式

    - 電子郵件:[email protected]
    - GitHub:[你的 GitHub]
    - LinkedIn:[你的 LinkedIn]
  3. 配置導航欄: 在 docusaurus.config.ts 中修改 navbar 配置,添加指向你的關於我頁面、部落格等鏈接。

    navbar: {
    title: 'Hikari Dev',
    logo: {
    alt: 'My Site Logo',
    src: 'img/logo.svg',
    },
    items: [
    {
    type: 'doc',
    docId: 'intro', // 指向你的關於我或簡歷文檔
    position: 'left',
    label: '關於我',
    },
    {to: '/blog', label: '部落格', position: 'left'},
    // ... 其他鏈接
    ],
    },

D. 部署網站

最簡單的方法是使用 GitHub Pages 或 Vercel / Netlify。Docusaurus 有內置的部署功能。

  • GitHub Pages: 在 docusaurus.config.ts 中配置 baseUrlprojectName
    baseUrl: '/<your-repo-name>/', // 例如,如果你的 repo 是 yourusername.github.io/my-website
    projectName: 'my-website',
    organizationName: 'yourusername',
    然後運行部署命令:
    GIT_USER=<YOUR_GITHUB_USERNAME> USE_SSH=true yarn deploy

總結

建立個人主頁是一個展現自己的絕佳機會。選擇合適的工具、精心策劃內容,並利用靜態站點生成器等現代技術,你可以輕鬆地建立一個專業且美觀的個人網站。

C# 中的 MD5 雜湊

這篇備忘錄記錄了在 C# 中實現 MD5 雜湊的方法。

資訊

MD5 (Message-Digest Algorithm 5) 是一種廣泛使用的加密雜湊函數,它生成一個 128 位(16 字節)的雜湊值。儘管 MD5 在加密安全方面已被認為不再安全(存在碰撞攻擊),但它仍然經常用於文件完整性校驗或非安全數據的快速雜湊。

1. 使用 System.Security.Cryptography.MD5

C# 提供了內置的 MD5 類(位於 System.Security.Cryptography 命名空間)來計算 MD5 雜湊值。

範例:對字串進行 MD5 雜湊

using System;
using System.Security.Cryptography;
using System.Text;

public class Md5Hasher
{
public static string CalculateMd5Hash(string input)
{
// 創建 MD5 雜湊算法的實例
using (MD5 md5 = MD5.Create())
{
// 將輸入字串轉換為字節數組
byte[] inputBytes = Encoding.UTF8.GetBytes(input);

// 計算雜湊值
byte[] hashBytes = md5.ComputeHash(inputBytes);

// 將字節數組轉換為十六進制字串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("x2")); // "x2" 格式化為兩位十六進制
}
return sb.ToString();
}
}

public static void Main(string[] args)
{
string text = "Hello, MD5!";
string hash = CalculateMd5Hash(text);
Console.WriteLine($"原始字串: {text}");
Console.WriteLine($"MD5 雜湊: {hash}");

// 預期的 MD5 雜湊值 for "Hello, MD5!" (小寫)
// 9e2469446d3288a7c207b04cfd6e01a4
}
}

範例:對文件進行 MD5 雜湊

對文件內容計算 MD5 雜湊通常用於驗證文件是否在傳輸過程中被修改。

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class FileMd5Hasher
{
public static string CalculateFileMd5Hash(string filePath)
{
if (!File.Exists(filePath))
{
return "文件不存在。";
}

using (MD5 md5 = MD5.Create())
{
using (FileStream stream = File.OpenRead(filePath))
{
byte[] hashBytes = md5.ComputeHash(stream);

StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("x2"));
}
return sb.ToString();
}
}
}

public static void Main(string[] args)
{
string filePath = "example.txt"; // 替換為你的文件路徑

// 創建一個範例文件
File.WriteAllText(filePath, "這是一個測試文件的內容。");

string fileHash = CalculateFileMd5Hash(filePath);
Console.WriteLine($"文件路徑: {filePath}");
Console.WriteLine($"文件 MD5 雜湊: {fileHash}");

// 清理範例文件
File.Delete(filePath);
}
}

2. 安全注意事項

  • 不適用於密碼儲存:由於 MD5 存在嚴重的安全漏洞(例如碰撞攻擊),絕對不應該將其用於儲存用戶密碼。對於密碼,應使用專為此目的設計的單向雜湊函數,如 PBKDF2、bcrypt 或 scrypt。
  • 不適用於數字簽名或認證:同樣,MD5 不應在需要強加密安全的場景中使用。
  • 用途:主要用途應該限於文件完整性校驗(驗證文件是否被意外更改)或生成非安全數據的快速雜湊。

總結

C# 中的 MD5 類提供了一種簡單直觀的方式來計算 MD5 雜湊值。雖然它在安全性方面存在限制,但在正確的應用場景下(如文件校驗),它仍然是一個有用的工具。務必牢記其安全限制,避免在加密敏感的上下文中使用它。

CUDA Grid 和 Block

這篇備忘錄記錄了 CUDA Grid 和 Block。

資訊

在 CUDA 中,並行執行的程式碼稱為核函數 (Kernel)。當你啟動一個核函數時,你必須指定執行該核函數的線程數量以及它們如何組織。這就是 Grid (網格) 和 Block (塊) 的概念。

1. 線程層次結構

CUDA 的線程模型是一個分層結構:

  • Grid (網格):由一個或多個 Block 組成。Grid 可以是一維、二維或三維的。
  • Block (塊):由多個線程組成。Block 也可以是一維、二維或三維的。
  • Thread (線程):Grid 中執行的最小單位。每個線程都執行相同的核函數程式碼。

這種層次結構允許你將問題分解為獨立的子任務,並將這些子任務映射到 Grid 和 Block 的維度上。

2. 定義 Grid 和 Block 維度

在啟動核函數時,你使用 <<<Dg, Db>>> 語法來指定 Grid 和 Block 的維度:

kernel_function<<<Dg, Db>>>(arguments);
  • Dg (Dimension Grid):指定 Grid 的維度。這是一個 dim3 類型的變量,可以是一維 (Dg.x)、二維 (Dg.x, Dg.y) 或三維 (Dg.x, Dg.y, Dg.z)。
  • Db (Dimension Block):指定每個 Block 的維度。這也是一個 dim3 類型的變量,可以是一維 (Db.x)、二維 (Db.y) 或三維 (Db.z)。

dim3 結構體

dim3 是一個結構體,通常用於表示 Grid 或 Block 的大小。

struct dim3
{
unsigned int x, y, z;
};

如果你只指定一個值,它會被賦給 .x,其他為 1。例如 dim3(10) 等同於 dim3(10, 1, 1)

3. 線程索引

在核函數內部,每個線程都可以通過幾個內置變量來識別自己的唯一索引:

  • blockIdx.x, blockIdx.y, blockIdx.z:當前線程所在的 Block 在 Grid 中的索引。
  • blockDim.x, blockDim.y, blockDim.z:每個 Block 的維度(線程數)。
  • threadIdx.x, threadIdx.y, threadIdx.z:當前線程在 Block 中的索引。
  • gridDim.x, gridDim.y, gridDim.z:Grid 的維度(Block 數)。

通過這些變量,可以計算出每個線程在整個 Grid 中的全局唯一索引。

一維索引計算

對於一維 Grid 和 Block,全局索引的計算方式為:

int global_index = blockIdx.x * blockDim.x + threadIdx.x;

二維索引計算

對於二維 Grid 和 Block,全局索引的計算方式為:

int x_index = blockIdx.x * blockDim.x + threadIdx.x;
int y_index = blockIdx.y * blockDim.y + threadIdx.y;

// 如果將二維數據存儲在一維數組中,則需要將 (x_index, y_index) 轉換為一維索引
// 假設矩陣寬度為 width
int global_index = y_index * width + x_index;

範例:向量加法

這是一個簡單的向量加法核函數,演示了 Grid 和 Block 的使用。

#include <iostream>
#include <vector>
#include <cuda_runtime.h>

// 核函數:在設備上執行向量加法
__global__ void add_vectors(int* a, int* b, int* c, int N) {
// 計算當前線程在 Grid 中的全局索引
int idx = blockIdx.x * blockDim.x + threadIdx.x;

// 確保索引在有效範圍內
if (idx < N) {
c[idx] = a[idx] + b[idx];
}
}

int main() {
int N = 100000; // 向量大小
size_t size = N * sizeof(int);

// 主機 (CPU) 數據
std::vector<int> h_a(N), h_b(N), h_c(N);

// 初始化主機數據
for (int i = 0; i < N; ++i) {
h_a[i] = i;
h_b[i] = i * 2;
}

// 設備 (GPU) 數據指針
int *d_a, *d_b, *d_c;

// 在設備上分配內存
cudaMalloc((void**)&d_a, size);
cudaMalloc((void**)&d_b, size);
cudaMalloc((void**)&d_c, size);

// 將數據從主機複製到設備
cudaMemcpy(d_a, h_a.data(), size, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, h_b.data(), size, cudaMemcpyHostToDevice);

// 配置 Grid 和 Block 維度
int threadsPerBlock = 256;
int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock; // 確保覆蓋所有元素

// 啟動核函數
add_vectors<<<blocksPerGrid, threadsPerBlock>>>(d_a, d_b, d_c, N);

// 將結果從設備複製回主機
cudaMemcpy(h_c.data(), d_c, size, cudaMemcpyDeviceToHost);

// 驗證結果 (可選)
std::cout << "h_c[0] = " << h_c[0] << std::endl; // 0 + 0 = 0
std::cout << "h_c[1] = " << h_c[1] << std::endl; // 1 + 2 = 3
std::cout << "h_c[N-1] = " << h_c[N-1] << std::endl; // (N-1) + 2*(N-1) = 3*(N-1)

// 釋放設備內存
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);

return 0;
}

總結

理解 CUDA 的 Grid 和 Block 概念對於有效利用 GPU 的並行計算能力至關重要。通過合理地組織線程,你可以將複雜的計算任務分解為數百萬個小任務,並在 GPU 上高效地執行它們。

Rust 隨機數

這篇備忘錄記錄了如何在 Rust 中生成隨機數。

資訊

Rust 的標準庫不直接包含生成隨機數的功能,而是通過 rand crate 提供。rand 是一個強大且靈活的庫,支持多種隨機數生成器和分佈。

1. 添加 rand 依賴

首先,你需要將 rand crate 添加到你的 Cargo.toml 文件中:

[dependencies]
rand = "0.8" # 使用 0.8.x 系列的最新版本

2. 生成隨機整數

使用 rand::Rng trait 來生成隨機數。最簡單的方法是使用 rand::thread_rng() 獲取一個線程局部隨機數生成器。

use rand::Rng; // 導入 Rng trait

fn main() {
let mut rng = rand::thread_rng(); // 獲取線程局部隨機數生成器

// 生成一個範圍在 [1, 10) 之間的隨機整數 (不包含 10)
let random_int = rng.gen_range(1..10);
println!("隨機整數 (1-9): {}", random_int);

// 生成一個範圍在 [1, 10] 之間的隨機整數 (包含 10)
let random_int_inclusive = rng.gen_range(1..=10);
println!("隨機整數 (1-10): {}", random_int_inclusive);

// 生成一個布爾值
let random_bool = rng.gen_bool(0.5); // 0.5 的概率為 true
println!("隨機布爾值: {}", random_bool);
}

3. 生成隨機浮點數

gen_range 也可以用於浮點數。

use rand::Rng;

fn main() {
let mut rng = rand::thread_rng();

// 生成一個範圍在 [0.0, 1.0) 之間的隨機浮點數 (不包含 1.0)
let random_float = rng.gen_range(0.0..1.0);
println!("隨機浮點數 (0.0-1.0): {}", random_float);

// 生成一個範圍在 [10.0, 20.0) 之間的隨機浮點數
let random_float_custom = rng.gen_range(10.0..20.0);
println!("隨機浮點數 (10.0-20.0): {}", random_float_custom);
}

4. 從列表中隨機選擇

你可以使用 rand::seq::SliceRandom trait 來從切片(如向量或數組)中隨機選擇元素或打亂順序。

use rand::seq::SliceRandom;
use rand::Rng;

fn main() {
let mut rng = rand::thread_rng();
let choices = ["蘋果", "香蕉", "櫻桃", "日期"];

// 隨機選擇一個元素
let random_choice = choices.choose(&mut rng);
println!("隨機選擇: {:?}", random_choice.unwrap());

// 隨機選擇多個元素 (可能重複)
let mut selected_multiple: Vec<&str> = (0..2)
.map(|_| choices.choose(&mut rng).unwrap())
.collect();
println!("隨機選擇多個: {:?}", selected_multiple);

// 隨機打亂向量的順序
let mut numbers = vec![1, 2, 3, 4, 5];
numbers.shuffle(&mut rng);
println!("打亂後的數字: {:?}", numbers);
}

5. 自定義隨機數生成器 (PRNG)

如果你需要可重複的隨機數序列,或者需要不同的隨機數生成器,你可以使用 rand crate 提供的各種 PRNG。例如,StdRng 是一個確定性隨機數生成器。

[dependencies]
rand = { version = "0.8", features = ["std"] } # 確保啟用 "std" feature 以使用 StdRng
rand_chacha = "0.3" # 引入一個具體的 PRNG 實現
use rand::{SeedableRng, Rng};
use rand_chacha::ChaCha8Rng; // 使用 ChaCha8Rng 作為範例

fn main() {
// 使用固定的種子創建一個隨機數生成器
let seed = [0; 32]; // 32 字節的種子
let mut rng = ChaCha8Rng::from_seed(seed);

let random_value1 = rng.gen_range(0..100);
println!("第一個隨機值: {}", random_value1);

let random_value2 = rng.gen_range(0..100);
println!("第二個隨機值: {}", random_value2);

// 如果再次使用相同的種子,將會得到相同的序列
let mut another_rng = ChaCha8Rng::from_seed(seed);
let another_value1 = another_rng.gen_range(0..100);
println!("再次使用相同種子得到的值: {}", another_value1);
}

總結

rand crate 為 Rust 提供了全面且安全的隨機數生成功能。無論是簡單的隨機數,從集合中選擇,還是需要自定義隨機數生成器,rand 都能滿足你的需求。記得在 Cargo.toml 中添加正確的依賴。

PC 環境備忘錄

這篇備忘錄記錄了個人電腦 (PC) 環境設置的一些常用配置和工具。

1. 作業系統

Windows

  • Windows Subsystem for Linux (WSL):在 Windows 上運行 Linux 環境的最佳方式。推薦安裝 WSL2。
  • PowerShell:Windows 的強大命令行 Shell。
    • Oh My Posh:自定義 PowerShell 提示符,使其更美觀和功能豐富。
  • 包管理器 (Package Manager)
    • Winget:Windows 內置的應用程式包管理器。
    • Chocolatey:另一個流行的 Windows 包管理器。

Linux (Ubuntu/Debian)

  • 桌面環境:GNOME (默認), KDE Plasma, XFCE 等。
  • 終端模擬器
    • GNOME Terminal (默認)
    • Tilix:平鋪式終端模擬器,支持多個面板。
    • Alacritty:GPU 加速的終端模擬器,速度快。
  • Shell
    • Bash (默認)
    • Zsh + Oh My Zsh:高度可自定義,提供豐富的插件和主題。
  • 包管理器apt (Debian/Ubuntu)。

macOS

  • iTerm2:功能豐富的終端模擬器,比默認的 Terminal 更好用。
  • Homebrew:macOS 的包管理器,大大簡化了軟體安裝。
  • Zsh + Oh My Zsh (默認 Shell)。

2. 開發工具

文本編輯器 / IDE

  • Visual Studio Code (VS Code):輕量級但功能強大的程式碼編輯器,支持大量擴展。
  • JetBrains IDEs:如 IntelliJ IDEA (Java), PyCharm (Python), WebStorm (Web) 等,功能齊全的專業 IDE。
  • Vim / NeoVim:高效的命令行文本編輯器,學習曲線陡峭但效率極高。
  • Emacs:另一個強大的可自定義編輯器。

版本控制

  • Git:分布式版本控制系統,幾乎是所有開發者的必備工具。
    • GUI 工具:GitKraken, SourceTree, VS Code 內置 Git 支持。

程式語言運行環境

  • Node.js:JavaScript 運行時。
    • NVM (Node Version Manager):管理多個 Node.js 版本。
  • Python
    • pyenv:管理多個 Python 版本。
    • Poetry / pipenv:虛擬環境和依賴管理工具。
  • Ruby
    • rbenv / RVM:管理多個 Ruby 版本。
  • Go
  • Rust

容器化

  • Docker:容器化平台,用於打包和運行應用程式。
  • Kubernetes (K8s):容器編排系統。

3. 實用工具

  • 文件同步
    • OneDrive / Google Drive / Dropbox:雲端同步。
    • Syncthing:開源的點對點文件同步工具。
  • 密碼管理器
    • Bitwarden:開源、跨平台。
    • LastPass
  • 截圖工具
    • ShareX (Windows):功能豐富。
    • Flameshot (Linux):
  • VPN:保護網絡隱私。
  • 剪貼板管理器
    • Ditto (Windows)
    • Gnome Clipboard Indicator (Linux)
  • 搜索工具
    • Everything (Windows):極速文件搜索。
    • fzf (Linux/macOS):模糊查找器。

4. 網絡配置

  • DNS 設定:更改為公共 DNS (如 8.8.8.8, 1.1.1.1) 以提高解析速度和隱私。
  • SSH 密鑰:用於安全地連接到遠端服務器。

總結

建立一個高效且舒適的 PC 環境是一個持續的過程,它涉及到選擇適合你工作流程的工具和配置。這篇備忘錄提供了一個起點,你可以根據自己的需求進一步探索和客製化。

IT 護照英文縮寫整理

縮寫全名意義
CSRCorporate Social Responsibility企業以合乎道德、永續且對社會負責的方式營運的責任。
SDGsSustainable Development Goals聯合國通過的17項全球目標,旨在推動永續發展。
OJTOn the Job Training員工在工作崗位上進行的在職訓練。
Off-JTOff the Job Training員工離開工作崗位進行的訓練。
HRTechHuman Resource Technology將資訊技術應用於人力資源管理。
CEOChief Executive Officer公司最高層的經營者,負責整體組織的成功。
CIOChief Information Officer負責運用資訊技術達成組織目標的高階主管。
COOChief Operating Officer負責企業日常行政與營運功能的高階主管。
CFOChief Financial Officer負責管理公司財務風險的高階主管。
ABC 分析依重要性將資料分為三類的柏拉圖分析法。
B/SBalance Sheet顯示公司在特定時間點的資產、負債與股東權益的財務報表。
ROEReturn On Equity衡量公司相對於股東權益盈利能力的比率。
JAN CodeJapanese Article Number日本使用的條碼標準。
QR CodeQuick Response能儲存比傳統條碼更多資料的二維條碼。
ISOInternational Organization for Standardization制定與發布國際標準的國際組織。
SWOT 分析Strengths・Weaknesses・Opportunities・Threats用於評估公司優勢、劣勢、機會與威脅的策略規劃工具。
PPMProduct Portfolio Management將產品分類為明星、金牛、問題兒童與落水狗的管理方法。
M&AMergers and Acquisitions兩家或多家公司合併為一家的行為。
VCVenture Capital投資高成長潛力新創企業的投資公司。
IPOInitial Public Offering私人公司首次向公眾發行股票。
TOBTake Over Bid公司直接向股東購買股份以收購另一家公司的要約收購。
MBOManagement Buyout公司管理團隊購買公司股票的交易。
4PProduct・Price・Place・Promotion行銷的四個P:產品、價格、通路與促銷。
4CCustomer Value・Cost・Convenience・Communication以買方為中心的行銷組合方式。
RFM 分析Recency・Frequency・Monetary依最近購買時間、購買頻率與購買金額分析顧客購買行為。
UXUser Experience使用者在使用產品、系統或服務時的體驗。
BSCBalance Scorecard從財務、顧客、內部流程及學習成長四個面向衡量公司績效的策略管理工具。
CSFCritical Success Factors對公司成功至關重要的因素。
KPIKey Performance Indicator衡量公司是否有效達成關鍵業務目標的量化指標。
ERPEnterprise Resource Planning整合企業財務、人力資源及供應鏈管理等各面向的系統。
CRMCustomer Relationship Management管理公司與現有及潛在顧客互動關係的系統。
SFASales Force Automation自動化銷售任務並提升銷售團隊效率的軟體。
SCMSupply Chain Management管理從原料到最終消費者的商品與服務流動。
RFIDRadio Frequency Identification利用無線電波識別與追蹤物體的技術。
NFCNear Field Communication近距離無線通訊技術。
AIArtificial Intelligence開發能執行通常需要人類智慧任務的電腦系統。
POS SystemPoint of Sale處理銷售交易的系統。
CADComputer Aided Design使用電腦軟體設計產品。
CAMComputer Aided Manufacturing使用電腦軟體控制製造流程。
JITJust In Time僅在需要時才生產商品以將庫存降至最低的製造策略。
ECElectronic Commerce透過網際網路進行商品與服務的買賣。
IoTInternet of Things嵌入感測器、軟體及其他技術以連接並與其他裝置及系統交換資料的實體物體網絡。
Society 5.0融合實體與虛擬世界以實現經濟發展並解決社會問題的社會形態。
EAEnterprise Architecture設計與實施組織資訊系統的框架。
SoESystem of Engagement強化與顧客關係的系統。
DFDData Flow Design顯示資料如何在系統中流動的圖表。